动机
Ant Design Charts 使用 lerna 已经一年多,还算稳定,除了体验稍差,也没什么大的问题,但随着官方的一篇文章,我决定切换到 pnpm(节省磁盘&安装快),特别是对于维护多个项目的同学来说,定期清理 node_modules 是不可避免的。
检测对应文件夹下的 node_modules
tnpx npkill --directory ~/yourworkproject --sort path
pnpm
站在巨人肩膀上的巨人,吸取了 yarn、npm 的精华,做了我多年前想做但没做(没能力)的事情!
节省磁盘空间
在操作系统中,文件实际上是一个指针,只不过它指向的不是内存地址,而是一个外部存储地址(硬盘、U盘、甚至是网络),从上图的 Hard Link和Symbolic Link可以看出,不同项目的node_modules ,如果包和版本都相同,他们使用的是同一套数据,而不是多次安装,可以极大的节省磁盘空间,项目越多越明显!
Tips:软连接可以链接目录,硬链接只能链接文件
安装快
lock 大家都知道,pnpm 也有 pnpm-lock.yaml的概念,和 yarn.lock是类似的,这里不展开。不同的是,即使没有对应的 lock 文件,pnpm 也可以做到快速安装,只要之前有过安装记录,因为 pnpm 有个virtual stroe 的概念,每次安装前都会去检测,如果本地磁盘已经安装过,且版本满足匹配规则,直接使用(建立硬链接),不会再次下载,没有安装过的话会先下载到 virtual store,再建立链接。
如果没有设置过 virtual-path 的话,可以在 ~/.pnpm-store/v3/files目录下看到对应的依赖数据。
迁移
workspace
lerna 切换到 pnpm 非常简单,因为两者本身就很简单,加之 workspace 是 pnpm 默认提供的,不需要安装三方依赖。
- 新增 pnpm-workspace.yaml,对应 lerna.json
packages:
- 'packages/**'
- 新增 .npmrc ,全部使用默认值也不是不可以!
auto-install-peers=true
strict-peer-dependencies=false
你以为就完了吗?核心的就这两,至于 scripts 、.gitignore 这些细节,自己调整就好了!
踩坑记录
这么简单的变动还能踩坑?对,因为这是迁移,不是新项目!
幽灵依赖
charts 依赖 g2plot ,g2plot 的 dependencies 已经有@antv/util ,也就是说,只要安装了 g2plot ,依赖里面就一定有@antv/util,charts 层是不需要指定的,在 yarn 时代是可行的,但 pnpm 过于优秀,默认会检测到 util 依赖丢失,需要安装,仔细想想,这也比较合理。
workspace root
# alias p=pnpm
p add @antv/util -S --filter @ant-design/plots
文件路径
如果代码里面有使用到相对路径,并且是从 node_modules 里面直接引入的话,需要修改一下引入路径,这是因为 yarn 和 pnpm 对依赖的处理方式不一致,yarn 会将依赖安装的最外层的 node_moduels ,而 pnpm 会将包的直接依赖安装到当前目录。
依赖丢失
这个问题,看起来是依赖没有安装,如果仔细查看,你会发现根目录
node_modules/.pnpm 里面是有该依赖的
解决办法是提升依赖,在 .npmrc 里面配置 public-hoist-pattern[]=gatsby-link,这样的话会将 gatsby-link直接安装到 node_modules 下面,全局可用。
官网对这种情况的解释如下:
This setting is useful when dealing with some flawed pluggable tools that don't resolve dependencies properly.
如果需要处理的依赖较多,可以直接配置shamefully-hoist=true ,和public-hoist-pattern[]=* 等效。
依赖冲突
.npmrc: auto-install-peers=true
由于auto-install-peers 配置,如果项目依赖了多个包,他们的 peerDependencies 不一致的话,就可能出现版本冲突问题,具体问题具体分析就好。
"peerDependencies": {
"react": ">=16.8.4",
"react-dom": ">=16.8.4"
},
其它
发包
- 子包:构建完发布即可,和 yarn 么区别
- 主包:需要注意一点,由于存在包之间的引用,建议将对应版本修改为
workspace:*,使用 pnpm publish
"dependencies": {
"@ant-design/flowchart": "workspace:*",
"@ant-design/graphs": "workspace:*",
"@ant-design/maps": "workspace:*",
"@ant-design/plots": "workspace:*"
},
node 版本
由于 pnpm 自带 node 版本管理能力,详见 pnpm.io/cli/env ,如果你以前使用 nvm 等 node 版本管理的话,可以下掉了。
pnpm env use --global 16
总结
pnpm,你值得拥有!如果对你有用,别忘了给个点赞!