动机,节省磁盘空间
生成非扁平化的 node_modules 目录
当使用 npm 或 yarn 来安装依赖,所有包被提升到根模块。这导致,源码能获取到它们,虽然它们没有被作为依赖添加到项目中的 dependencies。
默认情况下,pnpm 使用符号链接来添加项目的直接依赖,位置在模块的根目录。
安装
npm install -g pnpm
功能比较
Feature | pnpm | Yarn | npm |
---|---|---|---|
共享工作空间支持 | ✔️ | ✔️ | ✔️ |
隔离 node_modules | ✔️ - 默认 | ✔️ | ✔️ |
提升 node_modules | ✔️ | ✔️ | ✔️ - 默认 |
自动安装 peers | ✔️ - 通过 auto-install-peers=true | ❌ | ✔️ |
Plug’n’Play(即插即用功能) | ✔️ | ✔️ - 默认 | ❌ |
零安装 | ❌ | ✔️ | ❌ |
更新依赖 | ✔️ | ✔️ | ❌ |
管理 nodejs 版本 | ✔️ | ❌ | ❌ |
有 lockfile 文件 | ✔️ - pnpm-lock.yaml | ✔️ - yarn.lock | ✔️ - package-lock.json |
Overrides 支持 | ✔️ | ✔️ - 通过 resolutions | ✔️ |
内容寻址存储 | ✔️ | ❌ | ❌ |
动态包执行 | ✔️ -通过 pnpm dlx | ✔️ - 通过 yarn dlx | ✔️ - 通过 npx |
副作用缓存 | ✔️ | ❌ | ❌ |
列出 licenses | ✔️ - 通过 pnpm licenses list | ✔️ - 通过 plugin | ❌ |
选项
不像 npm 不验证,pnpm 会验证所有选项,非法的选项将会出错。比如,pnpm install --target_arch x64
会验证失败,因为 --target_arch 是一个非法的选项。
-C
, --dir
使用该选项,会在
-w, --workspace-root
使用该选项,会在工作空间的根目录下执行 pnpm 脚本命令。
命令
npm 命令 | 等效的 pnpm 命令 |
---|---|
npm install | pnpm install |
npm i pkg | pnpm add pkg |
npm run cmd | pnpm cmd |
当使用一个未知的命令时,pnpm 将会在 package.json 里搜索对应名字的脚本。所以 pnpm run lint 等同于 pnpm lint。
如果没有对应名字的 script,那么 pnpm 将会把命令作为 shell 脚本执行。所以你能够使用 pnpm eslint(等同于 pnpm exec eslint)。
pnpm exec <name>
意为执行 node_modules/.bin 下的 shell 命令。
配置
pnpm 使用 npm 安装依赖时的配置。
过滤
过滤允许你限制命令只在特定的包下面生效。
pnpm 支持丰富的选择器语法来选择包,比如通过名字或相对路径。
选择器通过 --filter (or -F)
标志指定。
pnpm --filter <package_selector> <command>
管理依赖
Command | Meaning |
---|---|
pnpm add sax | 保存到生产依赖 |
pnpm add -D sax | 保存到开发依赖 |
pnpm add -O sax | 保存到可选依赖 |
pnpm add -g sax | 安装到全局 |
pnpm add sax@next | 从下一个标记安装 |
pnpm add sax@3.0.0 | 指定 3.0.0 版本 |
pnpm 管理 node 版本
没试过。现在还在用 nvm 管理 node 版本。
pnpm-workspace.yaml
packages:
# 所有在 packages/ 直接子目录下的包会加入到工作空间
- 'packages/*'
# 只要在 components/ 目录下的包,不管层级,都会加入到工作空间
- 'components/**'
# 但是要排除在 test 目录下的包,它们不会加入到工作空间
- '!**/test/**'
Workspace
pnpm 对 monorepositories 有内置支持。(又名 multi-package 仓库,multi-project 仓库,monolithic 仓库)。你可以在一个单仓库中创建一个工作空间,来联合多个项目。
一个工作空间必须有一个 pnpm-workspace.yaml 文件在根目录。也可能需要 .npmrc 文件来进行其它的配置。
Workspace protocol (workspace:)
默认情况下,如果可获取的包符合声明的版本范围,pnpm 将从工作空间链接包。
举例,foo@1.0.0 将会被链接到 bar 里面:如果 bar 有一个依赖 “foo”:“^1.0.0”,并且包 foo@1.0.0 在那个工作空间下。
但如果 bar 有一个依赖 “foo”: “2.0.0”,并且 foo@2.0.0 不再工作空间下,foo@2.0.0 将会从仓库中下载。这个行为导致一些不确定性。
幸运的是,pnpm 支持 workspace: protocol。当使用 protocol 时,pnpm 将会拒绝处理任何事除了本地工作空间的包。
所以,如果你设置 “foo”: “workspace:2.0.0”,这次安装将会失败,因为 “foo@2.0.0” 不在当前的工作空间里。
Workspace 匹配策略
npm 的版本匹配策略
- ^1.0.1:只要主版本一致都匹配(1.x),如:1、1.x(后面两个版本随便变)
- ~1.0.1:只要主版本和次版本一致都匹配(1.1.x),如:1.1、1.1.x(后面一个版本随便变)
- 1.0.1:只能匹配 1.0.1 版本。
Workspace 匹配策略
# 匹配最新版
pnpm add @ah-ailpha/utils@* --filter @ah-ailpha/components
# 只要主版本一致都匹配
pnpm add @ah-ailpha/utils@^ --filter @ah-ailpha/components
# 只要主版本和次版本一致都匹配
pnpm add @ah-ailpha/utils@~ --filter @ah-ailpha/components
# 只能匹配 1.0.1 版本
pnpm add @ah-ailpha/utils@1.0.1 --filter @ah-ailpha/components
显示 npm 用户名
npm whoami [--registry <registry>]
workspace 中如何使用 changesets
pnpm install @changesets/cli --save-dev -w
pnpm install changeset --save-dev -w
npx changeset init
# 添加 changeset
npx changeset
更新版本并发布
npx changeset version
npx changeset publish
只允许pnpm
当在项目中使用 pnpm 时,如果不希望用户使用 yarn 或者 npm 安装依赖,可以将下面的这个 preinstall 脚本添加到工程根目录下的 package.json中:
{
"scripts": {
"preinstall": "npx only-allow pnpm"
}
}