在团队协作和自动化部署(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
用于在自动化流程或新环境中复现一个已知的、确定的依赖状态。