package-lock.json 是否提交问题
# 前言
之前博主使用 vdoing (opens new window) 这款主题创建了博客,已经使用了很长时间,然后远程分别使用了 Vercel 部署和云服务器部署,然后最近服务器迁移到国外,重新部署网站之后,发现 npm 拉取包失败,但是 Vercel 可以正常拉取包部署
我开始怀疑自己的服务器配置过低,导致拉取包出现服务器 CPU & 内存占用率过高,然后导致系统卡死,拉取包失败,虽然后面排查确实有这方面原因。下面我将详细讲解排查记录
# 排查
# 问题
然后我使用 windows 主机拉取仓库也安不上依赖,然后我仔细检查了仓库文件,结果 .gitignore 文件中居然有 package-lock.json,导致 package-lock.json 没有上传,结果下载的包版本有错误
# 文档
官方文档:package-lock.json | npm Documentation (codingdict.com) (opens new window)
npm 官方文档对于 package-lock.json 解释是这样的
package-lock.json
为 npm 修改 node_modules
树或 package.json
的任何操作自动生成。它描述了生成的确切树,以便后续安装能够生成相同的树,而不考虑中间依赖项更新。
此文件旨在提交到源存储库中,并具有多种用途:
- 描述依赖关系树的单个表示形式,以便保证团队成员、部署和持续集成安装完全相同的依赖关系。
- 为用户提供一种工具,使其可以“时间旅行”到以前的状态,
node_modules
而无需提交目录本身。 - 通过可读的源代码管理差异提高树更改的可见性。
- 通过允许 npm 跳过以前安装的包的重复元数据解析来优化安装过程。
一个 package-lock.json
关键细节是它不能发布,如果在顶级包以外的任何地方找到它将被忽略。它与 npm-shrinkwrap.json 共享一种格式,后者本质上是相同的文件,但允许发布。除非部署 CLI 工具或以其他方式使用发布过程来生成生产包,否则不建议这样做。
# 解释
首先我们知道 npm 包的依赖关系是树状的,手动能锁定的只有 package.json 里的第一层包的版本,每个包往下还有数不清的依赖分支,每个依赖中都有自己独立的 package.json,这些没办法都手动锁定版本,它们升级的话,一样会造成同样的问题。
package-lock.json 的出现就是为了解决上面的问题,对整个依赖树进行版本锁定 。 这个方案大概是在npm 5之后出现的。
所以如果有锁定版本的需求,package-lock.json 需要提交到源码库中,这样锁定后问题是确定性的,维护会方便。如果出现问题,可以定位到指定的包,然后如果问题修复就手动更新,比较方便
如果说你不需要锁定版本的需求,可以直接在 .npmrc 添加 package-lock=false 即可,或者在 .gitignore 写入 package-lock.json ,这样的话可以及时获得开发者修复升级的版本,不容易有潜在 bug,但是问题是由于版本出现环境依赖问题,会比较难定位问题,不好解决
注:所以理论上锁版本和不锁版本都没问题,看项目需求
# 解决
按照上面说的,直接把 package-lock.json 上传到源码库即可解决,云服务器就可以正常拉取依赖部署网站。
但是其实上面我提到个问题,同样没有 package-lock.json,为什么云服务器自己部署拉取依赖出错 ,但是 Vercel 可以正常拉取依赖包,也许是 Vercel 有特殊机制,不过这个问题也不重要了