因为没提交 package-lock.json,我们的线上项目差点翻车

27 阅读2分钟

因为没提交 package-lock.json,我们的线上项目差点翻车

“怎么会突然挂了?昨天还是好的啊!”
—— 这是我周一早上被运维炸到的第一句话。


一、事故现场

上周我们上线了一个小功能,按理说改动不大,代码都通过 CI 测试了
然而生产环境却出现了奇怪的错误:

  • 页面依赖某个工具库报错
  • 某个接口返回异常
  • 线上日志显示版本不匹配

追查半天,发现问题根源:

我们的项目没有上传 package-lock.json,CI 重新安装依赖时拉到了 最新版本 的一个子依赖,而这个版本有破坏性改动。

换句话说:

  • 开发环境跑得好好的
  • 生产环境用的依赖和开发环境不一致
  • 导致生产环境翻车

二、为什么上传 package-lock.json 很关键

1️⃣ package.json 只是“意图”

"dependencies": {
  "lodash": "^4.17.0"
}
  • ^4.17.0 表示允许 4.17.x 的任意版本
  • 它告诉 npm:“我能接受这些版本”
  • 但不保证每次安装都一样

2️⃣ package-lock.json 是“结果”

"lodash": "4.17.21"
  • 精确记录了当前安装版本
  • 包括所有子依赖版本
  • 保证 安装可复现

换句话说,package.json 是意图,package-lock.json 才是结果


三、npm install 会自动更新 lock 吗?

大多数人误以为:

“写了 ^4.17.0,npm install 会升级到最新符合范围的版本吧?”

实际情况:

  • 只要 lock 文件存在且满足 semvernpm install 不会升级
  • registry 上有新版本也不会动

只有在以下情况,lock 文件才会更新:

  1. 修改 package.json
  2. 主动执行 npm update / npm install 某个包
  3. lock 文件被删除或损坏

这也解释了为什么没有上传 lock,会导致生产环境依赖漂移。


四、生产环境的正确姿势

1️⃣ 开发环境

npm install
  • 安装依赖
  • 生成或更新 package-lock.json
  • 测试通过 → 提交 lock 文件到仓库

2️⃣ CI / 生产环境

npm ci
  • 严格按照 lock 文件安装
  • 不解析 semver,不升级依赖
  • lock 不一致 → 构建失败

CI 的这个流程可以保证开发环境和生产环境完全一致


五、node_modules 要不要提交?

绝大多数情况下 不要提交

  • 体积庞大
  • 不可复现
  • 已有 package-lock.json 管控依赖

例外场景:

  1. 内网无法访问 npm registry
  2. 临时修改了依赖源码(建议用 fork 或 patch-package,而不是直接提交 node_modules)

六、教训总结

  • 没有上传 package-lock.json,生产环境不可控
  • package.json 是意图,package-lock.json 是结果
  • CI / 生产环境必须依赖 lock 文件安装
  • node_modules 不提交,除非特殊场景
  • 如果临时修改依赖源码 → 用 fork 或 patch-package

一句话总结:

想要安全上线,先确保 lock 文件在仓库里。