迁移步骤
1.全局安装pnpm
npm -g i pnpm
2. 使用 pnpm import
由yarn.lock导出pnpm.lock
3. 添加 script
到 package.json
确保pnpm唯一包管理
"scripts": {
"preinstall": "npx only-allow pnpm",
...
}
4. 更换.yarnrc
为 .npmrc
5. 运行 pnpm i
安装依赖
6. 将脚本的指令由 yarn
更换为 pnpm
7. 对应ci构建的脚本更改
8. 删除yarn.lock
文件(需先删除node_modules)
9. 根据测试方案进行测试
10. 最后效果汇总
迁移风险
一、幽灵依赖问题
由于 yarn/npm
的扁平化包管理,导致项目中存在许多幽灵依赖的使用问题,直接切换pnpm
而不处理,会导致项目直接运行失败
解决方案:
使用自开发的幽灵依赖扫描工具@winches/ghost
幽灵扫描原理:
基于AST和正则对项目中的
require(), import(), import/export from xxx, @import
进行扫描将扫描出的包名与项目中的
package.json
对比,并过滤不合法包名,路径别名,内置nodejs包以发掘出项目中存在的幽灵依赖
以下为使用工具扫描出目前项目中存在的幽灵依赖:
编译时报错(依赖中的幽灵依赖):tslib@2.4.0(tsconfig.json
里importHelpers
配置开启后需要)
幽灵依赖的处理:
1、
.npmrc
中添加public-hoist-pattern[]='package name'
将对应的包提示至顶层目录2、
pnpm add
对应版本的依赖3、
shamefully-hoist=true
将所有依赖都提升至根目录(不推荐)。
二、peerDependencies
安装第三方包的时候,可能出现该包 A peerDependencies
包 B 的错误
这通常表示尝试安装的包 A 需要另一个包 B 作为其依赖项才能正常工作。
解决方案:
1、 直接显式安装本地,按照报错提示,先安装包 B,然后再安装包 A
2、使用
packageExtensions
处理
三、Conflicting
解决方法:
1、
--force
强制安装冲突的包2、如果你在使用一个 monorepo 管理多个项目,可以使用
pnpm recursive
命令,在整个 monorepo 中安装/更新包,以解决依赖冲突3、使用
pnpm dedupe
命令,它会自动检测并解决依赖冲突。
四、unmet peer dependencies
非可选对等依赖项打印出来的警告,包可以在没有对等依赖的情况下工作则可忽略对应的提示
1、配置peerDependencyRules忽略对应的警告提示
{ "pnpm": { "peerDependencyRules": { "allowAny": [ "eslint" ] } } }
2、
.npmrc
配置文件中添加strict-peer-dependencies=false
,关闭严格的对等依赖模式
测试方案
1. 依次运行package.json
里的scripts
命令
2. 触发各流水线检查功能是否正常
3. 页面检查
最后效果
性能对比
yarn
第一次安装:用时 242.09s
存在缓存时:用时 161.93s
pnpm
第一次安装:用时 93.00 s
存在缓存时:用时 60.00 s
内存对比
yarn
pnpm
安全性对比
yarn
扁平化依赖虽然解决了不少问题,但是随即带来了依赖非法访问的问题,项目代码在某些情况下可以在代码中使用没有被定义在 package.json 中的包,这种情况就是我们常说的幽灵依赖。
pnpm
默认情况下禁止幽灵依赖,pnpm
的依赖文件结构与 package.json
中的声明保持一致,因此,我们将不能再访问 package.json
中未声明的包。 这解决了 npm
/ yarn
一直依赖的幽灵依赖问题,提升了依赖访问的安全性。