I've been using PNPM to manage my dependencies in this project. PNPM is a great, performance-focused option for monorepos.
But I ran into a problem after switching to PNPM and trying to deploy this site: Netlify doesn't support PNPM by default. It supports NPM, Yarn, and Bower. And, as of writing this, they don't plan to support additional package managers, at least not PNPM for now.
I ended up following this community discussion, from which I finally figured out how to get it all working. Here's the synthesized process:
You can disable NPM in two steps. First, remove the lock file for another package manager if it's in place. This is usually either package-lock.json
or yarn.lock
. If you've been tracking either of this with Git, you should probably also add them to your .gitignore
file.
Next, you can tell Netlify to not install your dependencies with NPM, which it will do by default if it finds a package.json
and no other specific (supported) lock file.
To do this you'll want to add a NPM_FLAGS
environment variable set to /dev/null
. You can set this either in your netlify.toml
file:
netlify.toml
[build.environment]
NPM_FLAGS="--prefix=/dev/null"
Or you can set it through the Netlify UI. Read more about environment variables here.
Now that you have no package manager, you have to tell Netlify what to do. Before installing PNPM, be sure you are tracking your pnpm-lock.yaml
file. (Make sure it's not listed in your .gitignore
file.
Next, we'll want to install PNPM. Since NPM is already installed, you can actually use NPM to install PNPM globally. Your best option here is to add a prebuild
script to your package.json
file.
package.json
{
"scripts": {
"prebuild": "test \"$CI\" = true && npx pnpm install -r --store=node_modules/.pnpm-store || echo skipping pnpm install",
"build": "..."
}
}
Netlify should run this automatically before running build
. This will use a remote version of PNPM to install your packages.
Note: This is where I ended up running into trouble. I had other processes that were running prior to the prebuild
script. That's why I ended up going the plugin route.
But if this works for you, that's great! You can use npm
to run your build scripts just as you would have otherwise, but now you've used pnpm
to manage your dependencies. You can be confident that the packages you're using in production are the same as those you use to develop locally.
I attempted to turn this code into a shared plugin and I ran into issues with it, so I abandoned the approach. However, I did write a local plugin that I'm using on this project. Note the following:
manifest.yml
file to name the plugin.index.js
file with the plugin's code.prebuild
script in package.json
.netlify.toml
file.Want to receive approximately one email every month with new articles, tools, and references I've discovered? Sign up below.
This site was created and is maintained by Sean C Davis. It was designed by Matt Willett.
The stack is Eleventy, Tailwind CSS, and loads of other open-source software. The code is built, deployed, and hosted with help from GitHub and Netlify.
And here's a super important legal document Sean made up.