套件管理器指令对照
四个套件管理器的常用指令并排对照,可以直接填入你自己的套件名称。并标出 Yarn 1 与 Yarn 2 以上不同之处,以及根本没有对应指令的地方。
在你的浏览器中运行
| 要做的事 | npm | yarn | pnpm | bun |
|---|---|---|---|---|
| 安装 lockfile 里的全部依赖 | ||||
| CI 安装,lockfile 若会改动就失败 | Yarn 1(Classic): | |||
| 新增依赖包 | ||||
| 新增开发依赖 | ||||
| 锁定版本,不用范围 | ||||
| 全局安装 | 没有对应命令 Yarn 1(Classic): | |||
| 移除依赖包 | ||||
| 在既有版本范围内更新 | Yarn 1(Classic): | |||
| 列出落后最新版的包 | Yarn 1(Classic): | |||
| 执行 package.json 里的 script | ||||
| 不安装就执行包的可执行文件 | ||||
| 建立新包 | ||||
| 查出某个包为什么被装进来 | ||||
| 检查依赖包的安全通报 | Yarn 1(Classic): | |||
| 把依赖装到某一个 workspace |
Yarn 列是 Yarn 2 以上(Berry)。Yarn 1 不同的地方会列在下面。
四个管理器,同一件事,四种写法
这些指令没有一个难记,难的是要记四遍——公司的专案用 pnpm、要发 PR 的开源专案用 Yarn、 而 README 是照 npm 写的。
在上面输入套件名称,表格里的指令会全部填好。点任何一格就复制。
一般对照表错的两个地方
yarn 指的是两个不同的程序
Yarn 1(Classic)与 Yarn 2 以上(Berry)不是同一个程序,而且差别刚好落在大家会去查的那几条:
| 要做的事 | Yarn 1 | Yarn 2+ |
|---|---|---|
| CI 安装 | yarn install --frozen-lockfile | yarn install --immutable |
| 升级 | yarn upgrade | yarn up |
| 看哪些落后 | yarn outdated | yarn upgrade-interactive |
| 安全通报 | yarn audit | yarn npm audit |
| 不安装直接执行 | 没有对应 | yarn dlx |
上面的表格显示的是 Berry,因为 corepack enable 给你的就是它,package.json 里的
packageManager 栏位锁的也是它。Yarn 1 不同的地方会列在该格下面。
有些情况根本没有对应指令
Yarn 2 以上没有全域安装。yarn global add 被移除而且刻意不补回来,维护者的理由是:全域安装
等于让一个专案的相依跑出专案之外。yarn dlx 不是替代品——它是下载、执行一次、丢掉。
表格在这种情况直接写「没有对应指令」,而不是塞一个看起来最像的。会猜的对照表比会承认缺口的更糟。
行为真的不一样的那几条
大部分列只是同一件事的不同写法。有三条不是:
npm ci会先删掉node_modules,其他三个不会。pnpm install --frozen-lockfile和yarn install --immutable会在 lockfile 将被改动时失败,这正是 CI 要的性质,但它们会沿用已经 存在的东西。npm run <script>的run不能省。yarn build、pnpm build可以直接写;npm build也能执行,但那是另一个已被废弃的指令,不是你的 script。bun run <script>同样要写run, 因为bun <文件>是拿来执行文件的。npx在本机没有时会去 registry 抓。pnpm dlx和bunx也是。但 Yarn 1 的yarn <bin>只找得到已经在node_modules里的执行档,所以那一列没有 Classic 的写法。
Lockfile 不能互转
换管理器不是把指令翻译一下就好。每一个管理器都写自己的 lockfile——package-lock.json、
yarn.lock、pnpm-lock.yaml、bun.lock——而且没有一个读得懂别人的。真正的迁移是删掉旧的
lockfile、重新安装,然后检查解出来的版本是不是你要的那些。
只 commit 一个 lockfile。仓库里放两个,就会变成谁跑哪个指令、谁就得到不同的相依树。
相关
只需要其中一组的话,npm 转 Yarn 与 npm 转 pnpm 是同一张表的两栏版本。
你输入的东西不会送到任何地方。表格本来就在页面里,代入是在你的浏览器做的。