在团队协作和自动化部署(CI/CD)的场景中。为了确保每个环境(开发、测试、生产)的依赖完全一致,必须严格按照 package-lock.json 来安装 npm 包。
核心答案
要严格按照 package-lock.json 来安装,应该使用的命令是:
npm ci
ci 代表 “Continuous Integration”(持续集成),这个命令就是为了这种可复现、确定性的安装场景而设计的。
npm ci 和 npm install 的关键区别
npm ci 与我们常用的 npm install 在行为上有根本性的不同。理解这些不同之处,你就知道为什么 npm ci 是你需要的答案。
1. 依赖来源 (The Source of Truth)
npm ci: 只认package-lock.json(或npm-shrinkwrap.json)。它会完全忽略package.json文件中的版本范围(如^1.2.3或~4.5.6)。它会安装package-lock.json中记录的精确版本的每一个包。npm install: 主要读取package.json。如果node_modules存在且package-lock.json与package.json兼容,它会尝试复用package-lock.json。但如果版本范围允许,它可能会更新次要版本或补丁版本,并相应地更新package-lock.json文件。
2. 对 node_modules 的处理
npm ci: 先删除,再安装。在安装之前,它会先检查是否存在node_modules文件夹,如果存在,会整个删除它,然后再进行一次纯净的、全新的安装。这确保了环境中不会有任何“残留”的、旧的或不相关的包。npm install: 增量安装。它会检查现有的node_modules文件夹,并尝试在它的基础上进行添加、更新或删除包。这个过程通常比npm ci慢,且不如npm ci干净。
3. 对 lock 文件的影响
npm ci: 从不修改package.json或package-lock.json。它的职责是消费(consume)lock 文件,而不是生成或更新它。如果package-lock.json与package.json的依赖不匹配,或者package-lock.json不存在,npm ci会直接报错并退出,而不是尝试修复它。npm install: 可能会修改package-lock.json。当你添加新包 (npm install lodash) 或有时只是单纯运行npm install,它都可能会根据package.json中的规则去更新依赖树,并把结果写入package-lock.json。
对比
| 特性 / 行为 | npm ci (推荐用于自动化环境) |
npm install (推荐用于本地开发) |
|---|---|---|
| 主要目的 | 可复现的、干净的安装 | 管理和安装项目依赖 |
| 依赖来源 | 严格遵循 package-lock.json |
主要基于 package.json,参考 package-lock.json |
node_modules 处理 |
先删除整个文件夹,再全新安装 | 在现有文件夹上增量更新 |
| 是否修改 lock 文件 | 从不修改 | 会修改 package-lock.json 以反映依赖树的变化 |
| 速度 | 通常更快(因为它跳过了复杂的依赖解析) | 可能较慢(因为它需要计算依赖树) |
| 前置条件 | 项目中必须存在 package-lock.json |
即使没有 package-lock.json 也能运行 |
正确的工作流程
结合 npm ci 和 npm install 的最佳实践工作流程如下:
-
本地开发时 (你的电脑上)
- 当你需要添加、更新或删除依赖时,使用
npm install。- 添加新包:
npm install <package-name> - 更新包:
npm update <package-name>
- 添加新包:
npm会帮你更新package.json和package-lock.json。- 将修改后的
package.json和package-lock.json文件一起提交到你的版本控制系统(如 Git)中。 这是至关重要的一步!
- 当你需要添加、更新或删除依赖时,使用
-
自动化环境 (CI/CD 服务器、Docker 构建) 或新同事加入项目时
- 从 Git 仓库拉取代码后,不要运行
npm install。 - 运行
npm ci。 - 这会确保服务器或新同事的电脑上安装的依赖包,与你本地开发和测试时的依赖包版本完全一致,从而避免“在我电脑上是好的”这类经典问题。
- 从 Git 仓库拉取代码后,不要运行
总结
- 要严格按照
package-lock.json安装,杜绝任何自动升级和不确定性,请使用npm ci。 npm install用于日常开发中管理(增、删、改)你的项目依赖。npm ci用于在自动化流程或新环境中复现一个已知的、确定的依赖状态。