目前,npm ci
是使用CI时安装Node模块的最常见方式。但它实在太慢了。
有没有一种方法可以使用缓存来加速npm ci
,或者不完全删除现有程序包(整个node_modules文件夹)?
目前,npm ci
是使用CI时安装Node模块的最常见方式。但它实在太慢了。
有没有一种方法可以使用缓存来加速npm ci
,或者不完全删除现有程序包(整个node_modules文件夹)?
NPM缓存位于~/.npm
,但在大多数CI中,您只能缓存工作目录内的内容。
为了规避这个问题,您可以使用npm set cache .npm
将缓存目录更改为当前目录。现在,NPM缓存将位于./.npm
,您可以在CI作业之间缓存此文件夹。
GitLab CI示例:
my-super-job:
image: node:13-alpine
script:
- npm set cache .npm
- npm ci
cache:
paths:
- .npm
编辑:刚刚发现您可以将配置设置为命令行标志,因此npm ci --cache .npm
应该是相同的。
tl;dr 不完全是。
npm ci
应该在 CI 中优先使用,因为它尊重 package-lock.json
文件。与 npm install
不同,后者会重写该文件并始终安装新版本。
由于设计原因,该命令始终会清除所有本地软件包,即在开始时删除 node_modules
目录。这是长时间构建的主要原因。而且没有选项可以避免这种烦人的行为。
在本地计算机上,您可以通过添加选项 --prefer-offline
来加快 npm ci
,告诉 NPM 忽略缓存最短时间并立即使用本地缓存的软件包,而不是将其与注册表进行验证。
然而,NPM 缓存 位于 Unix 上的 ~/.npm
或 Windows 上的 %AppData%/npm-cache
。这些文件夹在大多数 CI 中默认情况下无法缓存。例如,GitLab CI 只有 可用工作区域中的存储库 作为缓存。其他目录,如主目录或系统目录(例如 apt
),则未被缓存。因此,此设置可能不会影响您的 CI 构建时间。
--progress=false
通过移除进度条显著影响构建时间。然而,这个问题似乎已经不存在了,我再也无法测量到显著的差异。--only=production
,NPM将忽略开发依赖项。由于上述原因,这不会影响缓存。
更新2021-06:现在可以更改缓存目录
如下评论所指出的,现在可以更改NPM缓存目录的位置。例如,通过在每个命令中传递它作为参数(--cache .npm
)或环境变量(npm_config_cache=.npm
)。因此,将其更改为存储在存储库中的临时目录的路径,将其添加到CI缓存堆栈,但在部署构建中排除它。然后,您将能够在CI脚本中使用--prefer-offline
参数。npm ci --cache <local cache directory> --prefer-offline --only=production --silent
npm install
那样快速npm ci
的结果:
https://docs.gitlab.com/ee/ci/caching/#caching-nodejs-dependencies - Saqib Ahmed--prefer-offline
和 --no-audit
,例如:npm ci --prefer-offline --no-audit
。在使用 npm ci 运行时,您可以设置缓存文件夹。
npm ci --cache .npm
然后在你的CI中,缓存.npm
文件夹
对我很有帮助,尽管它可能只在本地有用。https://dev59.com/hFIH5IYBdhLWcg3wVcZD#61364681
基本上使用npm ci --production
,这将跳过安装dev-dependencies。
编辑:较新版本的NPM建议使用npm ci --omit=dev
,如此处所述。
npm ci
,然后在构建/测试阶段之后,运行npm prune --production
。 - Coderer免责声明,该方法不足以用于最终版本构建。
然而,如果您需要尽可能快地运行一些辅助脚本,并且只需要来自 packages-lock.json
的所有软件包,您可以将其与 node_modules 文件夹中的 .package-lock.json
文件进行比较。如果在那里检测到更改,则调用通常的npm ci
。在我的情况下,这使得某些任务加快了数百倍。
以下是链接到要点 install.js。此方法适用于 npm v7.0 及以上版本。
1. If no change in package.json, don't install npm_modules & fetch it from cache
2. Set up a expiry limit for cache, so even if there is no change in package.json for the time limit you have set, revalidate cache
and install modules again.
node_modules
文件夹以完成确定性构建。 - ambianBeing