【发布时间】:2019-03-01 03:54:15
【问题描述】:
【问题讨论】:
标签: npm continuous-integration npm-install npm-ci
【问题讨论】:
标签: npm continuous-integration npm-install npm-ci
npm ci 将删除任何现有的 node_modules 文件夹并依赖 package-lock.json 文件来安装每个包的特定版本。它比 npm install 快得多,因为它跳过了一些功能。它的干净状态安装非常适合 ci/cd 管道和 docker 构建!您还可以使用它一次安装所有内容,而不是特定软件包。
【讨论】:
您链接的文档有摘要:
简而言之,使用 npm install 和 npm ci 的主要区别是:
- 项目必须具有现有的 package-lock.json 或 npm-shrinkwrap.json。
- 如果包锁中的依赖项与 package.json 中的依赖项不匹配,npm ci 将退出并报错,而不是更新包锁。
- npm ci 一次只能安装整个项目:无法使用此命令添加单个依赖项。
- 如果 node_modules 已经存在,它将在 npm ci 开始安装之前自动删除。
- 它永远不会写入 package.json 或任何包锁:安装基本上是冻结的。
【讨论】:
来自npm docs:
简而言之,使用 npm install 和 npm ci 的主要区别是:
- 项目必须具有现有的 package-lock.json 或 npm-shrinkwrap.json。
- 如果包锁中的依赖项与 package.json 中的依赖项不匹配,npm ci 将退出并报错,而不是更新包锁。
- npm ci 一次只能安装整个项目:无法使用此命令添加单个依赖项。
- 如果 node_modules 已经存在,它将在 npm ci 开始安装之前自动删除。
- 它永远不会写入 package.json 或任何包锁:安装基本上是冻结的。
基本上,
npm install 读取package.json 以创建依赖项列表并使用package-lock.json 通知要安装这些依赖项的哪些版本。 如果依赖项不在package-lock.json 中,它将由npm install 添加。
npm ci(以 Continuous Integration 命名)直接从 package-lock.json 安装依赖项,并仅使用 package.json 进行验证没有不匹配的版本。 如果缺少任何依赖项或版本不兼容,则会抛出错误。
使用npm install 添加新的依赖项,并更新项目的依赖项。通常,您会在拉取更新依赖列表的更改之后在开发期间使用它,但在这种情况下使用 npm ci 可能是个好主意。
如果您需要确定性、可重复的构建,请使用 npm ci。例如在持续集成、自动化作业等期间以及第一次安装依赖项时,而不是npm install。
npm installnpm-shrinkwrap.json 和 package-lock.json(按此顺序)驱动。node_modules 中安装任何缺少的依赖项。package.json 或package-lock.json。
npm i packagename) 一起使用时,它可能会写入 package.json 以添加或更新依赖项。npm i) 可能会写入 package-lock.json 以锁定某些依赖项的版本(如果它们不在此文件中)。npm cipackage-lock.json 或npm-shrinkwrap.json 才能在场。package.json 不匹配,则会引发错误。node_modules 并立即安装所有依赖项。package.json 或package-lock.json。虽然npm ci 从package-lock.json 或npm-shrinkwrap.json 生成整个依赖关系树,但npm install 使用以下算法更新node_modules 的内容 (source): p>
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
【讨论】:
npm install 可以写入 package.json。你知道它可以在这里写什么吗?
npm install package 可以同时修改package-lock.json 和 package.json,而npm install 没有参数只会修改package-lock.json
devDependencies 由--production 标志或NODE_ENV 环境变量控制,对于npm i 和npm ci 都是如此
npm ci 中的 ci 更好地理解为全新安装而不是持续集成。
这些命令在功能上非常相似,但不同之处在于安装package.json 和package-lock.json 文件中指定的依赖项的方法。
npm ci 执行应用程序的所有依赖项的全新安装,而npm install 可能会跳过某些安装,如果它们已经存在于系统上。如果系统上已安装的版本不是您的package.json 打算安装的版本,即安装的版本与“必需的”版本不同,则可能会出现问题。
其他区别是npm ci 永远不会触及您的package*.json 文件。如果 package.json 和 package-lock.json 文件中的依赖版本不匹配,它将停止安装并显示错误。
您可以从官方文档here 中阅读更好的解释。
此外,您可能还想了解包锁here。
【讨论】:
值得记住的是,像 alpine 这样的轻节点 docker 映像没有安装 Python,它是 node-gyp 的依赖项,由 npm ci 使用。
我认为为了让npm ci 工作,您需要在构建中安装 Python 作为依赖项,这有点固执己见。
【讨论】:
react-scripts 有问题不是因为npm ci 从我发现npm ci 中的python 没有依赖关系
你应该在不同的情况下使用它们。
npm install 非常适合开发和在 CI 中缓存node_modules 目录。
什么时候用这个?如果你正在制作一个包供其他人使用,你可以这样做(你没有在这样的版本中包含node_modules)。关于缓存,请注意,如果您计划支持不同版本的Node.js,请记住,由于Node.js 运行时要求之间的差异,可能必须重新安装node_modules。如果你想坚持一个版本,坚持最新的LTS。
npm ci 应该在您要测试和发布生产应用程序(最终产品,不被其他软件包使用)时使用,因为重要的是您的安装尽可能具有确定性,此安装将花费更长的时间,但最终会使您的应用程序更可靠(您确实在这样的版本中包含node_modules)。坚持使用LTS 版本的Node.js。
npm i 和 npm ci 都使用 npm 缓存(如果存在),此缓存通常位于 ~/.npm。
另外,npm ci 尊重 package-lock.json 文件。与 npm install 不同,后者会重写文件并始终安装新版本。
奖励:您可以根据自己的复杂程度混合使用它们。在 git 的功能分支上,您可以缓存 node_modules 以提高团队的工作效率,而在合并请求和主分支上,则依赖 npm ci 获得确定性结果。
【讨论】:
npm i 而不是npm ci,除非您想更新依赖项。 npm ci 总是更好,因为确定性行为总是更好
npm i 缓存更快,npm ci 更慢,因为它会重新安装。它们都很有用。
npm ci 与每个包都在 npm 缓存中一样快
npm ci 即使在本地 NPM 缓存中重复执行时也会显着变慢:npm install 大约为 2 秒,npm ci 为同一项目运行时为 16 秒。清除缓存后,它们是相同的。我们迫切需要一些可以从 package-lock 安装但不要从删除 node_modules 开始的东西:github.com/npm/cli/issues/564