文章目录
- [一、核心原则:lockfile 必须被严格控制](#一、核心原则:lockfile 必须被严格控制)
-
- [必须提交到 Git](#必须提交到 Git)
- [CI 必须使用 frozen-lockfile](#CI 必须使用 frozen-lockfile)
- 二、为什么加一个依赖会导致其他版本变化
-
- [原因 1:依赖使用 ^ 或 ~](#原因 1:依赖使用 ^ 或 ~)
- [原因 2:transitive dependency 升级](#原因 2:transitive dependency 升级)
- [原因 3:pnpm dedupe](#原因 3:pnpm dedupe)
- [原因 4:pnpm 版本不同](#原因 4:pnpm 版本不同)
- [三、团队推荐 workflow](#三、团队推荐 workflow)
-
- [1. 安装新依赖](#1. 安装新依赖)
- [2. 安装依赖](#2. 安装依赖)
- [3. 检查 lockfile diff](#3. 检查 lockfile diff)
- [4. CI 强制锁定](#4. CI 强制锁定)
- 四、一个非常有效的方案(强烈推荐)
- [五、如果 lockfile 已经乱了](#五、如果 lockfile 已经乱了)
- 六、前端团队最佳实践
- 总结
在 pnpm 项目里,pnpm-lock.yaml 本来是用来 保证依赖可重复安装(deterministic install) 的。但很多团队都会遇到如下问题:
加一个新依赖 →
pnpm install→ lockfile 里其他模块版本也变了 → 运行出现问题。
这通常不是 pnpm 的 bug,而是 依赖范围、lockfile使用方式、团队流程的问题。
下面是比较成熟的维护策略。
一、核心原则:lockfile 必须被严格控制
pnpm-lock.yaml 的定位应该是:
团队唯一依赖快照
所以应该遵循两个原则:
必须提交到 Git
bash
git add pnpm-lock.yaml
否则每个人安装的依赖可能不同。
CI 必须使用 frozen-lockfile
CI 中必须使用:
bash
pnpm install --frozen-lockfile
含义:
- 只按照 lockfile 安装
- 不允许修改 lockfile
- 如果 lockfile 不匹配直接失败
二、为什么加一个依赖会导致其他版本变化
常见原因有 4 个。
原因 1:依赖使用 ^ 或 ~
例如:
json
{
"react": "^18.2.0"
}
^ 允许升级:
18.2.0 → 18.3.0
当你执行:
bash
pnpm install
pnpm 可能会 重新解析依赖树。
解决方案:
使用更稳定的版本
json
{
"react": "18.2.0"
}
或者只允许 patch:
json
"react": "~18.2.0"
原因 2:transitive dependency 升级
例如:
A
└ B ^1.0.0
└ C ^2.0.0
当你安装新包时:
C 2.0.1 → 2.1.0
lockfile 可能更新。
解决方案:
使用 overrides 锁版本。
pnpm 支持:
json
{
"pnpm": {
"overrides": {
"lodash": "4.17.21"
}
}
}
在 pnpm 中,overrides 的作用是:
强制指定某个依赖的版本,即使它是其他包的"间接依赖(transitive dependency)"。
简单说:overrides = 强行改写依赖树里的版本
原因 3:pnpm dedupe
pnpm 会自动优化依赖树:
A
└ lodash 4.17.20
B
└ lodash 4.17.21
可能被 dedupe 成:
lodash 4.17.21
解决方案:可以运行:
bash
pnpm install --lockfile-only
查看变化。
原因 4:pnpm 版本不同
不同版本 pnpm 可能生成不同 lockfile。
解决方案:
在项目里固定 pnpm 版本:
json
{
"packageManager": "pnpm@9.0.0"
}
然后使用:
bash
corepack enable
三、团队推荐 workflow
这是比较成熟的流程。
1. 安装新依赖
只允许:
bash
pnpm add axios
不要直接手动改 package.json。
2. 安装依赖
bash
pnpm install
3. 检查 lockfile diff
提交前必须检查:
bash
git diff pnpm-lock.yaml
如果看到:
+ lodash 4.17.21
- lodash 4.17.20
要确认是否合理。
4. CI 强制锁定
CI:
bash
pnpm install --frozen-lockfile
避免 lockfile 被自动更新。
四、一个非常有效的方案(强烈推荐)
使用:
bash
pnpm install --lockfile-only
作用:
- 只更新 lockfile
- 不安装 node_modules
适合 review 依赖变化。
五、如果 lockfile 已经乱了
可以重新生成:
bash
rm -rf node_modules
rm pnpm-lock.yaml
pnpm install
但这通常只适合:
- 小项目
- 或升级依赖
大型项目不建议。
六、前端团队最佳实践
推荐组合:
pnpm
+ overrides
+ frozen-lockfile
+ 固定 pnpm 版本
package.json 示例:
json
{
"packageManager": "pnpm@9.1.0",
"pnpm": {
"overrides": {
"lodash": "4.17.21"
}
}
}
总结
避免 lockfile 混乱的关键:
1️⃣ commit pnpm-lock.yaml
2️⃣ CI 使用 --frozen-lockfile
3️⃣ 固定 pnpm 版本
4️⃣ 使用 overrides 控制 transitive dependency
5️⃣ 安装依赖必须用 pnpm add