lern to pnpm

253 阅读4分钟

动机

Ant Design Charts 使用 lerna 已经一年多,还算稳定,除了体验稍差,也没什么大的问题,但随着官方的一篇文章,我决定切换到 pnpm节省磁盘&安装快),特别是对于维护多个项目的同学来说,定期清理 node_modules 是不可避免的。

检测对应文件夹下的 node_modules

tnpx npkill --directory ~/yourworkproject --sort path

pnpm

站在巨人肩膀上的巨人,吸取了 yarn、npm 的精华,做了我多年前想做但没做(没能力)的事情!

1663055294260-d4253919-91fe-49f6-a289-f3c785d4812c.png

节省磁盘空间

在操作系统中,文件实际上是一个指针,只不过它指向的不是内存地址,而是一个外部存储地址(硬盘、U盘、甚至是网络),从上图的 Hard LinkSymbolic Link可以看出,不同项目的node_modules ,如果包和版本都相同,他们使用的是同一套数据,而不是多次安装,可以极大的节省磁盘空间,项目越多越明显!

Tips:软连接可以链接目录,硬链接只能链接文件

3A33B224-5790-400C-BE60-0BB49EEEF86D.png

安装快

lock 大家都知道,pnpm 也有 pnpm-lock.yaml的概念,和 yarn.lock是类似的,这里不展开。不同的是,即使没有对应的 lock 文件,pnpm 也可以做到快速安装,只要之前有过安装记录,因为 pnpm 有个virtual stroe 的概念,每次安装前都会去检测,如果本地磁盘已经安装过,且版本满足匹配规则,直接使用(建立硬链接),不会再次下载,没有安装过的话会先下载到 virtual store,再建立链接。

如果没有设置过 virtual-path 的话,可以在 ~/.pnpm-store/v3/files目录下看到对应的依赖数据。

4051B883-4204-4CA3-9B16-7880045A5EB4.png

迁移

workspace

lerna 切换到 pnpm 非常简单,因为两者本身就很简单,加之 workspace 是 pnpm 默认提供的,不需要安装三方依赖。

  1. 新增 pnpm-workspace.yaml,对应 lerna.json
packages:
  - 'packages/**'
  1. 新增 .npmrc ,全部使用默认值也不是不可以!
auto-install-peers=true 
strict-peer-dependencies=false

你以为就完了吗?核心的就这两,至于 scripts 、.gitignore 这些细节,自己调整就好了!

踩坑记录

这么简单的变动还能踩坑?对,因为这是迁移,不是新项目!

幽灵依赖

charts 依赖 g2plot ,g2plot 的 dependencies 已经有@antv/util ,也就是说,只要安装了 g2plot ,依赖里面就一定有@antv/util,charts 层是不需要指定的,在 yarn 时代是可行的,但 pnpm 过于优秀,默认会检测到 util 依赖丢失,需要安装,仔细想想,这也比较合理。

AE26EF5F-9B42-4BAF-9081-3EFA22BB13C4.png

workspace root

# alias p=pnpm
p add @antv/util -S --filter @ant-design/plots

文件路径

如果代码里面有使用到相对路径,并且是从 node_modules 里面直接引入的话,需要修改一下引入路径,这是因为 yarn 和 pnpm 对依赖的处理方式不一致,yarn 会将依赖安装的最外层的 node_moduels ,而 pnpm 会将包的直接依赖安装到当前目录。

610F6F9A-5BBC-4AD7-B511-AFBEFC5A958B.png

依赖丢失

8C2F959F-E6F1-4C22-991B-AD31DC80B60F.png 这个问题,看起来是依赖没有安装,如果仔细查看,你会发现根目录 node_modules/.pnpm 里面是有该依赖的

E7AD193B-8FC5-44FB-B61D-D387C61255D1.png

解决办法是提升依赖,在 .npmrc 里面配置 public-hoist-pattern[]=gatsby-link,这样的话会将 gatsby-link直接安装到 node_modules 下面,全局可用。

7.png

官网对这种情况的解释如下:

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,你值得拥有!如果对你有用,别忘了给个点赞!