Just as an informative note for future users, here some info on how to workaround Netlify’s CI in order to use pnpm
instead of npm
or yarn
and pnpm workspaces.
-
Remove your
package-lock.json
oryarn.lock
file and add it to your.gitignore
, if applicable. Be sure to trackpnpm-lock.yaml
instead. -
If you’re using workspaces: add
pnpm
itself as a dev dependency on your top-level project, this so it is possible to usepnpm recursive
commands inside your build scriptspnpm install --save-dev pnpm@3
-
Add the
NPM_FLAGS="--prefix=/"
env var to yournetlify.toml
or set it on Netlify’s web dashboard[build.environment] NPM_FLAGS="--prefix=/"
This makes netlify skip their automatic
npm install
, to letpnpm
take care of it. -
Add
pnpm install
as a build step in your build process, only for Netlify, most probably before anything else. Assuming your build command isnpm run build
, you might add the following script into your top-levelpackage.json
:"prebuild": "[[ $CI = true ]] && npx pnpm@3 install -r --store=node_modules/.pnpm-store || echo skiping pnpm install"
Use the
-r
option only if you’re using workspaces. The--store
option tells pnpm where to save its “global” cache. I initially tried to save it to the netlify cache dir, but netlify is picky on what saves in cache for the next build. Even when I was able to make netlify save the pnpm cache, the install was not very efficient because pnpm had to resort to the copy strategy because netlify mounts the cache folder in a different drive, so symlinking is not possible. Saving the store intonode_modules
makes the install quite fast.
We have been using this setup in prod without issues for a while now. And unlike with yarn, we haven’t experienced issues with missing node_modules
inside workspaces, since pnpm
stores every dep inside the top-level node_modules
(which is the only Netlify saves for cache) and pnpm install
simply creates symlinks.