"npm install" 和 "npm ci" 有什么区别?

What is the difference between "npm install" and "npm ci"?

我正在使用持续集成并发现了 npm ci 命令。

我不知道在我的工作流程中使用这个命令有什么好处。

更快吗?会不会让考试更难,好吧,之后?

npm ci 将删除任何现有的 node_modules 文件夹并依赖 package-lock.json 文件来安装每个包的特定版本。它比 npm install 快得多,因为它跳过了一些功能。它的干净状态安装非常适合 ci/cd 管道和 docker 构建!您还可以使用它一次性安装所有内容,而不是特定的包。

您链接的文档包含摘要:

In short, the main differences between using npm install and npm ci are:

  • The project must have an existing package-lock.json or npm-shrinkwrap.json.
  • If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
  • npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.
  • If a node_modules is already present, it will be automatically removed before npm ci begins its install.
  • It will never write to package.json or any of the package-locks: installs are essentially frozen.

来自npm docs

In short, the main differences between using npm install and npm ci are:

  • The project must have an existing package-lock.json or npm-shrinkwrap.json.
  • If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
  • npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.
  • If a node_modules is already present, it will be automatically removed before npm ci begins its install.
  • It will never write to package.json or any of the package-locks: installs are essentially frozen.

本质上, npm install 读取 package.json 以创建依赖项列表并使用 package-lock.json 通知要安装这些依赖项的版本。 如果依赖项不在 package-lock.json 中,它将由 npm install 添加。

npm ci(也称为 Clean Install)是旨在用于自动化环境——例如测试平台、持续集成和部署——或者任何你想确保你正在干净安装你的依赖项的情况。

它直接从 package-lock.json 安装依赖项并使用 package.json 来验证没有不匹配的版本。 如果缺少任何依赖项或具有不兼容的版本,它将抛出错误

使用npm install 添加新的依赖项,并更新项目的依赖项。通常,您会在开发过程中拉取更新依赖项列表的更改后使用它,但在这种情况下使用 npm ci 可能是个好主意。

如果您需要确定性的、可重复的构建,请使用 npm ci。例如在持续集成、自动化作业等期间以及第一次安装依赖项时,而不是 npm install.

npm install

  • 安装包及其所有依赖项。
  • 依赖项由 npm-shrinkwrap.jsonpackage-lock.json(按此顺序)驱动。
  • 不带参数: 安装本地模块的依赖。
  • 可以安装全局包。
  • 将在 node_modules 中安装任何缺少的依赖项。
  • 它可能写入package.jsonpackage-lock.json
    • 当与参数 (npm i packagename) 一起使用时,它可能会写入 package.json 以添加或更新依赖项。
    • 当不带参数使用时,(npm i) 它可能会写入 package-lock.json 以锁定某些依赖项的版本,如果它们不在该文件中的话。

npm ci

  • 至少需要 npm v5.7.1
  • 需要 package-lock.jsonnpm-shrinkwrap.json 存在。
  • 如果这两个文件的依赖关系不匹配,则抛出错误 package.json
  • 删除node_modules并立即安装所有依赖项
  • 它从不写入 package.jsonpackage-lock.json

算法

虽然 npm cipackage-lock.jsonnpm-shrinkwrap.json 生成整个依赖关系树,但 npm install 更新 node_modules[= 的内容118=] 使用以下算法 (source):

load the existing node_modules tree from disk
clone the tree
fetch the package.json and assorted metadata and add it to the clone
walk the clone and add any missing dependencies
  dependencies will be added as close to the top as is possible
  without breaking any other modules
compare the original tree with the cloned tree and make a list of
actions to take to convert one to the other
execute all of the actions, deepest first
  kinds of actions are install, update, remove and move

这些命令在功能上非常相似,但区别在于安装 package.jsonpackage-lock.json 文件中指定的依赖项所采用的方法。

npm ci 执行应用程序所有依赖项的全新安装,而 npm install 可能会跳过某些安装(如果它们已存在于系统中)。如果系统上已安装的版本不是您 package.json 打算安装的版本,即安装的版本与“需要的”版本不同,则可能会出现问题。

其他区别是 npm ci 永远不会触及您的 package*.json 文件。如果 package.jsonpackage-lock.json 文件中的依赖版本不匹配,它将停止安装并显示错误。

您可以从官方文档中阅读更好的解释 here

此外,您可能想阅读有关包锁的信息 here

值得注意的是,像 alpine 这样的轻节点 docker 图像没有安装 Python,这是 npm ci 使用的 node-gyp 的依赖项.

我认为为了使 npm ci 工作,您需要在构建中安装 Python 作为依赖项,这有点固执己见。

这里有更多信息

虽然其他人都回答了技术差异none请解释在什么情况下使用两者。

你应该在不同的情况下使用它们。

npm install 非常适合开发,在 CI 中当您想缓存 node_modules 目录时。 什么时候用这个?如果你正在制作一个包供其他人使用 (你不在这样的版本中包含 node_modules,你可以这样做。关于缓存,请注意,如果您计划支持不同版本的 Node.js 请记住,由于 Node.js 运行时要求之间的差异,可能需要重新安装 node_modules。如果你想坚持一个版本,坚持最新的 LTS.

npm ci 应该在您要测试和发布生产应用程序(最终产品,不被其他包使用)时使用,因为安装尽可能具有确定性很重要,此安装将花费更长的时间,但最终会使您的应用程序更可靠 (您在此类版本中包含 node_modules。坚持 LTS 版本的 Node.js

npm inpm ci 都使用 npm 缓存(如果存在),该缓存通常位于 ~/.npm.

此外,npm ci 尊重 package-lock.json 文件。与 npm install 不同,它会重写文件并始终安装新版本。

奖励:您可以根据要制作的复杂程度混合使用它们。在 git 中的功能分支上,您可以缓存 node_modules 以提高团队生产力,在合并请求和主分支上,依赖 npm ci 获得确定性结果。

它进行全新安装,在您要删除 node_modules 和 re-run npm i.

的情况下使用它

我不知道为什么有些人认为它是“持续集成”的缩写。有一个 npm install 命令可以 运行 为 npm i 和一个 npm clean-install 命令可以 运行 为 npm ci.