pnpm - a fast disk space efficient package manager#
I came across into a scenario where I have multiple Node.js projects
or directories and turns out that it has its own copies of node_modules for
each folder which accumulates large sizes on disk.
Learning about pnpm package manager made me realize that it is fast as it reuses packages already installed instead of creating another copy of the package which adds space in disk.
Motivation#
Tip
You can also go visit: https://pnpm.io/motivation
Installation#
Reference: https://pnpm.io/installation#using-npm
npm install -g pnpm@latest-10
Usages#
Installing node packages#
pnpm install # install ALL dependencies and dev-dependencies from package.json
# ==> Creates `pnpm-lock.yaml`
pnpm add <pkg-name>
pnpm add -D <pkg-name> # single dev-dependency
npm install # install ALL dependencies and dev-dependencies from package.json
# ==> Creates `package-lock.json`
npm install <pkg-name>
npm install -D <pkg-name> # single dev-dependency
Running scripts#
pnpm start # start script from package.json
pnpm dev # dev script from package.json
npm start # start script from package.json
npm run dev # dev script from package.json
Migration#
Existing package-lock.json#
Moving to pnpm but already have existing package-lock.json?
pnpm import
Generates a
pnpm-lock.yamlbased onpackage-lock.json
Existing pnpm-lock.yaml#
Moving back to npm?
When you don't have the package-lock.json
but has pnpm-lock.yaml
npm install --package-lock-only
Generates a
package-lock.jsonand would NOT actually install or touchnode_modules
Known Issues#
Importing a dependency of your dependency#
-
For example you have installed a node package which is a direct
dependenciesordevDependenciesin yourpackage.json. -
And it depends on another package called
uuidfor an instance. -
And you directly import
uuidas part of your application.
Then using npm, you may not encounter an error.
But using pnpm may throw an error.
In this case, you must hoist uuid in the root level of your node_modules
shamefully-hoist=true
Reinstall node_modules via pnpm install after configuring .npmrc
Reference: https://pnpm.io/settings#shamefullyhoist
Info
This happens because npm commonly installs ALL dependencies and its dependencies in your root node_modules.
Meanwhile, this may not be the same for pnpm.
Module Not Found#
After initial pnpm install, you may encounter this warning.
╭ Warning ───────────────────────────────────────────────────────────────────────────────────╮
│ │
│ Ignored build scripts: @apollo/protobufjs, @nestjs/core, node-snowball. │
│ Run "pnpm approve-builds" to pick which dependencies should be allowed to run scripts. │
│ │
╰────────────────────────────────────────────────────────────────────────────────────────────╯
You may ignore it.
But you may encounter issues after npm start / npm run dev / pnpm start / pnpm dev:
Error: Cannot find module './build/Release/snowball'`
The reason is, under the hood, your dependency is importing a module from a "build" that was not generated.
npm command will always allow build, especially few dependencies have a postinstall which
triggers the build to be generated.
However, pnpm will not allow this by default. Therefore, if your dependencies require these builds.
Then you have to approve those builds.
pnpm approve-builds
After successfuly operation, this command generates a
pnpm-workspace.yaml
This will display a list of build scripts which you can select from.
We will select node-snowball as we should know that it has a postinstall script to create
or generate the './build/Release/snowball'.
ignoredBuiltDependencies:
- '@apollo/protobufjs'
- '@nestjs/core'
onlyBuiltDependencies:
- node-snowball