Motivation
pnpm
is more performant at fetching, resolving, and storing dependencies. My personal experience shows that in some projects pnpm
can be approx. 10x time faster at resolving dependencies and up to 3x more efficient for disk usage.
It is also easy to start using pnpm
if you have used npm
or yarn
before because the CLI is very similar.
Migration guide
Step 1: Install pnpm
Installation
Step 2: Delete node_modules
npx npkill
Step 3: Add to package.json
"scripts": {
"preinstall": "npx only-allow pnpm",
...
}
This will prevent other devs from accidentally installing dependencies with anything else than pnpm
Step 4: Create pnpm-workspace.yaml
packages:
# include packages in subfolders (e.g. apps/ and packages/)
- "apps/**"
- 'packages/**'
# if required, exclude some directories
- '!**/test/**'
Step 4 (a): remove "workspaces"
from "package.json"
, since it's no longer needed.
Step 5: Run
pnpm import
This command will create a pnpm-lock.yaml
file based on yarn.lock
(or packages-lock.json
)
Step 6: Remove yarn.lock
(or packages-lock.json
)
Step 7: Install dependencies
pnpm i
Step 8: Replace npm run
(or yarn
) to pnpm
in all package.json
and other files (E.g. pnpm test
instead of npm run test
)
Important! You need to keep in mind that pnpm
doesn’t use dependency hoisting:
When installing dependencies with npm or Yarn Classic, all packages are hoisted to the root of the modules directory. As a result, source code has access to dependencies that are not added as dependencies to the project.
By default, pnpm uses symlinks to add only the direct dependencies of the project into the root of the modules directory.
pnpm
In practice it means that if you have a package A
that imports a package B
(import something from 'B'
) but doesn’t explicitly specify B
in the dependencies
or devDependencies
, then the execution will fail.
Cheatsheet
Tables | Commands | Cool |
---|---|---|
Install dependencies | pnpm i |
https://pnpm.io/cli/install |
Add a dependency | pnpm add <package> |
https://pnpm.io/cli/add |
Shows all packages that depend on the specified package | pnpm why <package> |
https://pnpm.io/cli/why |
Run a command as if it was executed form the root of the project rather than a workspace package | pnpm -w <command> |
https://pnpm.io/pnpm-cli#-w---workspace-root |
Restrict commands to specific subsets of packages | pnpm --filter <package_selector> <command> |
https://pnpm.io/filtering |
This runs an arbitrary command from each package's "scripts" object | pnpm -r <command> |
https://pnpm.io/cli/run#--recursive--r |
Top comments (20)
I'm in a project transition moving from
npm
topnpm
and it is a nightmare to remember when using each one.So I decided to create a command to do this. One command will translate to the respective PM.
npmjs.com/package/swpm
Cool stuff!
I found another package which does the same. github.com/antfu/ni
I've tested
ni
and it is an amazing project too, but have a different approach.ni
focus only on commonly used commands and assign an alias to each one.The SWPM key differences are:
node_modules
.save-dev
,exact-version
, and others that have been requested by the users.NVM
andVolta
compatible.get all time: Invalid package manager specification in package.json; expected a semver version
in my package.json:
"name": "express-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"preinstall": "npx only-allow pnpm",
"test": "echo \"Error: no test specified\" && exit 1"
},
"packageManager": "pnpm@7.1.7>",
It looks like you have a redundant ">" there
"packageManager": "pnpm@7.1.7>",
should be
"packageManager": "pnpm@7.1.7",
Also, this line is optional. It is a node experimental feature. nodejs.org/api/corepack.html
I guess I better remove it from the example
If I use
npm ci
in a Jenkins / GitLab pipeline, what command do I need to use withpnpm
?I'm not 100% sure, but according to the docs (docs.npmjs.com/cli/v8/commands/npm-ci) one of the main features of
npm ci
isIf dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
pnpm
docs saysIn a CI environment, installation fails if a lockfile is present but needs an update.
pnpm.io/cli/install
So, it looks like
pnpm i
behaves similar tonpm ci
. Try justpnpm i
orpnpm install --frozen-lockfile
Here is a good answer on StackOverflow stackoverflow.com/questions/701545...
Can pnmp be set up to allow fall back to npm, say if someone on a locked down/limited device (IoT or something) wants to pull a repo?
I think it could. Just remove
"preinstall": "npx only-allow pnpm",
, so the person working with the repo could usenpm
to install dependencies.And also, in that case it would make sense to keep
packages-lock.json
as well.Note: these are my assumptions. I'm not a maintainer of
pnpm
and may not know some pitfalls.Hoes does
only-allow
work? Does that detect when you run a script?Hi!
After following your tutorial to migrate an existing project from npm to pnpm (without any kind of problem) I run my app with "ng serve", as I was used to do with npm, and I get this errors:
`./src/main.ts - Error: Module build failed (from ./node_modules/.pnpm/@ngtools+webpack@14.2.10_7ypeylls7k.../node_modules/@ngtools/webpack/src/ivy/index.js):
Error: Emit attempted before Angular Webpack plugin initialization.
./src/polyfills.ts - Error: Module build failed (from ./node_modules/.pnpm/@ngtools+webpack@14.2.10_7ypeylls7k.../node_modules/@ngtools/webpack/src/ivy/index.js):
Error: Emit attempted before Angular Webpack plugin initialization.`
Any ideas about how to fix it?
Thanks a lot!
in my workspace i had the problem you described of importing packages, in npm it worked without modification, but now my package B which depends on package A can't find it, how do i add it in the dependecies?
For those having problems with
moment
anddotenv
dependencies when migrating fromnpm
topnpm
, simply add a .npmrc file with this content:issue reference
The script
preinstall
is not working for me... I tried to usenpm i
and also runshi! is pnpm support all npm packages?
Some comments may only be visible to logged-in visitors. Sign in to view all comments.