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

因为没提交 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 文件在仓库里。

你运行了: ```bash git check-ignore -v package-lock.json ``` 输出是: ``` .gitignore:11:package-lock.json package-lock.json ``` 但你说:**第 11 行是 `dist`** 这说明有一个严重的问题 —— **Git 显示的行号与你看到的内容不一致!** 这意味着:`.gitignore` 文件中 **确实有一行 `package-lock.json`,但它可能被隐藏字符干扰、或你在编辑器里看到真实内容。** --- ## 🔍 深度排查:为什么“明明有写却说有”? ### ✅ 问题本质: > Git 认为 `.gitignore` 第 11 行写着 `package-lock.json`,但你看不到 → 说明文件中有 **不可见字符** 或 **编码问题**(如 BOM、空格、制表符混淆),或者你查看方式不对。 --- ## 🛠 解决方案一:用命令行精确查看第 11 行 不要依赖 IDE/编辑器显示,使用终端命令查看真实内容: ```bash # 查看 .gitignore 前 15 行,并显示行号和不可见字符 cat -A .gitignore | nl -ba ``` ### 示例输出解释: ```text 1 ^I# 2 ^ILog$ 3 ^Ilogs$ 4 ^I*.log$ 5 ^Inpm-debug.log*$ 6 ^Iyarn-debug.log*$ 7 ^Iyarn-error.log*$ 8 ^Ipnpm-debug.log*$ 9 ^Ilerna-debug.log*$ 10 ^I$ 11 ^Ipackage-lock.json$ 12 ^Inode_modules$ 13 ^Idist$ 14 ^Idist-ssr$ 15 ^I*.local$ ``` 🔍 注意: - `^I` = 制表符(Tab) - `$` = 行尾标记 - 如果第 11 行出现了 `package-lock.json$`,那就说明它真的存在! 👉 即使你在 VS Code 里看见,也可能是缩进太多、折叠了、或用了软换行导致视觉错位。 --- ## 🛠 解决方案二:直接搜索关键词 用 grep 精确查找是否包含 `package-lock.json` ```bash grep -n "package-lock" .gitignore ``` ### 输出示例: ```bash 11:package-lock.json ``` ✅ 这就坐实了:第 11 行确实写了 `package-lock.json`,只是你注意到! --- ## ✅ 如何修复? ### 步骤 1:编辑 `.gitignore` 并删除该行 ```bash # 使用 vim 编辑(推荐) vim .gitignore ``` 跳转到第 11 行: - 按 `Esc` - 输入 `11G` 跳转到第 11 行 - 按 `dd` 删除这一行 - 输入 `:wq` 保存退出 或者使用其他编辑器打开并手动删除含有 `package-lock.json` 的那一行。 --- ### 步骤 2:验证是否已解除忽略 ```bash git check-ignore -v package-lock.json ``` ✅ 正常情况:**无任何输出** → 表示不再被忽略! --- ### 步骤 3:将 `package-lock.json` 加入 Git 跟踪 ```bash # 添加文件 git add package-lock.json # 查看状态 git status ``` 你应该看到: ```bash Changes to be committed: new file: package-lock.json ``` → 提交即可: ```bash git commit -m "chore: add package-lock.json to version control" ``` --- ## ⚠️ 可能原因总结 | 原因 | 说明 | |------|------| | ❌ 手动添加过 `package-lock.json` 忘记删除 | 曾为了“干净”而加进去,后来忘了 | | 💬 编辑器软换行导致看错行号 | 实际物理行 ≠ 视觉行 | | 🧼 复制粘贴时带入隐藏内容 | 从网页复制 .gitignore 时常带多余行 | | 🔤 不可见字符干扰 | 如 `\r\n`、BOM 头等 | --- ## ✅ 推荐:使用标准模板重建 .gitignore 建议使用官方推荐的 Node.js 项目 `.gitignore` 模板: 👉 来源:https://github.com/github/gitignore/blob/main/Node.gitignore 下载命令: ```bash curl -o .gitignore https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore ``` 然后检查是否包含你需要的规则(如 `.vscode/extensions.json` 白名单)。 --- ## ✅ 最终验证流程 ```bash # 1. 确认不再被忽略 git check-ignore -v package-lock.json # (期望:无输出) # 2. 添加文件 git add package-lock.json # 3. 查看状态 git status # 应显示 "new file: package-lock.json" # 4. 提交 git commit -m "feat: include package-lock.json for deterministic builds" ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值