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

Web*_*man 143 continuous-integration npm npm-install npm-ci

我正在进行持续集成并发现了npm ci命令.

我无法确定在我的工作流程中使用此命令的优点.

它更快吗?它会使测试更难,好吗,之后?

luc*_*aro 228

综上所述:

npm install读取package.json以创建依赖项列表,并用于package-lock.json通知要安装这些依赖项的版本.如果不包含依赖项package-lock.json,则将添加依赖项npm install.

npm ci(以C ontinuous I ntegration 命名)直接从中安装依赖项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

  • 需要package-lock.jsonnpm-shrinkwrap.json存在.
  • 如果来自这两个文件的依赖项不匹配,则会引发错误package.json.
  • 一次删除node_modules并安装所有依赖项.
  • 它永远不会写package.jsonpackage-lock.json.

算法

npm ci从生成整个依赖树package-lock.jsonnpm-shrinkwrap.json,npm install 更新的内容node_modules使用以下算法:

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
Run Code Online (Sandbox Code Playgroud)

  • @Link14 对于“npm i”和“npm ci”,“devDependency”的安装由“--product”标志或“NODE_ENV”环境变量控制 (5认同)
  • 好吧,这可能有点误导......当你用它来安装,更新或删除依赖项时,它会写入package.json.我会在文中说清楚,谢谢! (4认同)
  • 虽然文档中没有明确说明,但“npm ci”中的“ci”更好地理解为全新安装而不是持续集成。 (4认同)
  • 我不知道 `npm install` 可以写入 package.json。你知道它可以在这里写什么吗? (2认同)
  • `npm install package`可以同时修改`package-lock.json` **和** package.json,而`npm install`不带任何参数只会修改`package-lock.json`。 (2认同)

Adm*_*ama 28

  • npm ci- 准确安装 package-lock.json 中列出的内容
  • npm install- 不更改package.json中的任何版本,使用package.json编写package-lock.json,然后准确安装package-lock.json中列出的内容
  • npm update- 类似于npm install但也会安装“模糊版本”内容的更新(例如*^1.2.3
  • npx npm-check-updates -u; npm install- 将尝试将所有内容更新到最新版本。使用这个时要小心破坏性的改变。

或者换种说法,npm ci更改 0 个包文件,npm install更改npm update1 个包文件(package-lock.json),npx npm-check-updates -u; npm install更改 2 个包文件(package.json 和 package-lock.json)。


小智 14

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

  • 也许不提交node_modules? (11认同)
  • 删除预先存在的node_modules可能会使构建速度变慢 (5认同)
  • @MichaelFreidgeim 是使用预先存在的node_modules 还是从一个干净的开始? (3认同)
  • @jontro,我的同事测量了 docker 中的命令,发现对于我们的软件包 ci 明显比 install 快(40 秒 vs 130 秒),但是 YMMV。 (2认同)

Osc*_*Ryz 8

您链接的文档包含以下摘要:

简而言之,使用npm install和npm ci之间的主要区别是:

  • 该项目必须具有现有的package-lock.json或npm-shrinkwrap.json。
  • 如果程序包锁中的依赖项与package.json中的依赖项不匹配,则npm ci将退出并显示错误,而不是更新程序包锁。
  • npm ci一次只能安装整个项目:此命令不能添加单个依赖项。
  • 如果已经存在一个node_modules,它将在npm ci开始安装之前被自动删除。
  • 它永远不会写入package.json或任何包锁:安装实际上是冻结的。


kri*_*han 7

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

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

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

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

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


Kar*_*son 7

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

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

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

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

npm i并且npm ci两者都使用 npm 缓存(如果存在),该缓存通常位于~/.npm.

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

  • 我认为在任何情况下都不应使用“npm i”而不是“npm ci”,除非您想更新依赖项。`npm ci` 总是更好,因为确定性行为总是更好 (12认同)
  • 就我而言,即使重复执行,使用本地 NPM 缓存,`npm ci` 也会明显变慢:为同一项目运行时,`npm install` 约为 2 秒,`npm ci` 为 16 秒。清除缓存后它们是相同的。我们迫切需要一些可以从 package-lock 安装但不从删除 node_modules 开始的东西:https://github.com/npm/cli/issues/564 (5认同)
  • @Piedone我想说删除`node_modules`是一个功能,因为我看到开发人员在那里进行了一些自定义更改,并且想知道为什么它不能在生产中工作。我总是更喜欢重复执行完全相同结果的命令,而不是看似更快的命令。然而,“npm install”可能会改变“package-lock.json”这一事实对于依赖管理器来说是一个非常糟糕的默认值,但对于“npm ci”来说也是一个巨大的胜利。即使在我的开发机器上,我也总是使用“ci”进行纯安装,而“install”仅在我想要更新或添加新依赖项时使用。 (3认同)
  • 如果每个包都在 npm 缓存中,那么 `npm ci` 也同样快 (2认同)

tes*_*seo 5

值得记住的是,像 alpine 这样的轻节点 docker 镜像没有安装 Python,这node-gypnpm ci.

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

更多信息请点击此处Docker 和 npm - gyp ERR!不好

  • 从您发布的问题来看,他们遇到了“react-scripts”问题,而不是由于“npm ci”,我发现“npm ci”中没有对“python”的依赖 (2认同)