加速 npm install

48

我正在尝试在构建过程中加快npm安装的速度。 我的package.json文件中几乎包含了锁定版本的包列表。 我还使用命令配置了缓存目录


npm config set cache /var/tmp/npm-cache --global

然而,尝试使用npm install -g --cache进行安装时,我发现这一步并没有通过仅从缓存中加载包来减少安装时间,就像我预期的那样。事实上,我怀疑它甚至没有首先使用本地缓存来查找软件包。


我不确定我完全理解了,但听起来类似于npm-shrinkwrap试图解决的一些问题。https://www.npmjs.org/doc/cli/npm-shrinkwrap.html - Matt Pileggi
嗨@Prashanth,你能否看一下我的答案,如果正确的话,请接受它? - Mostafa Ghadimi
8个回答

26

提出两种更现代的方法:

1)npm ci

使用 npm ci,从 npm 版本 5.7.0 开始可用(虽然我建议使用 5.7.1 及以上版本,因为存在错误的发布版本)。这需要存在 package-lock.json 文件,并跳过基于 package.json 构建依赖树,而是保留锁定文件中已解析的依赖项 URL。

对于 CI/CD 环境,这非常快速(我们的构建时间减少了四分之一!),或者确保所有开发人员在开发期间使用相同版本的依赖项(而无需在 package.json 文件中硬编码严格版本)。

但是请注意,npm ci 在安装前会删除 node_modules/ 目录,因此它不会受益于任何缓存策略。

2)npm i --prefer-offline

使用 --prefer-offline 标志与正常的 npm install / npm i。通过此方法,您需要确保在构建之间缓存了您的 node_modules/ 目录(在 CI/CD 环境中)。如果它无法在本地找到特定版本的软件包,它会安全地回退到网络。


您也可以添加--no-audit --progress=false以减少预安装检查并删除进度条(后者只是一种非常轻微的改进)


24

对于纯npm解决方案,您可以尝试

npm install --prefer-offline --no-audit --progress=false

首次运行时,选择离线可能无法起到实际作用。


你现在是我的神了。 :D - Uri Kutner
1
这个在网速较慢的情况下真是救命稻草。 - Sharif
1
不错!你也可以加上 --production 参数,这样它只会下载直接依赖项。谢谢! - H_H

14

正如 @Daniel Serodio 建议的那样

您也可以将 node_modules 文件夹包含在您的代码库中,但最好先将其 压缩 再添加到 repo 中,在安装时可以 解压 并直接使用。

 npm rebuild

(可以在不同平台上运行)它非常快。

这也将使您完全控制所有依赖项的好处。

另外,您可以将进程标志设置为false,以将速度提高2倍。

npm set progress=false

阅读更多信息请查看来源

更新: 您也可以使用pnpm来进行此操作

npm i -g pnpm

这基本上使用本地缓存的模块(我听说比YARN更好)


使用 -s 选项不是一样的吗? - Pablo Ezequiel Leone
如果你在使用 npm install -s <packagename> 中的 -s,那么它代表着“save”,意思是将该包保存到 package.json 文件中。 - Anurag Jain
3
不再应该出现进展减缓事物的情况。 - rhand
1
@rhand 你是对的,这个问题已经通过提交github.com/npm/npm/issues/11283#issuecomment-251924063得到了解决。 - Anurag Jain
1
正如我在上面的帖子中所描述的那样,pnpm包是最佳解决方案! - Mostafa Ghadimi
显示剩余3条评论

9

最好使用以下命令安装pnpm包:

npm i -g pnpm

pnpm通过硬链接和符号链接只在磁盘上保存一个模块版本。例如,如果您有100个项目都使用相同版本的lodash,使用npm或Yarn时,您将在磁盘上拥有100份lodash副本。但是,使用pnpm,lodash将保存在磁盘上的单个位置,并且一个硬链接将把它放入应该安装的node_modules中。

例如,当您想要安装package.json文件的依赖项时,您需要做的就是输入pnpm i,它会自行处理其他事情。


这会产生任何冲突还是一个可靠的解决方案? - billa-code
1
@Credoz 这是一个可靠的解决方案,因为它使用符号链接仅保存模块的一个版本一次!正如文本中所提到的。 - Mostafa Ghadimi

7

更新:原始答案发布于2014年。我不建议检查 node_modules,因为有更好的选项可以加速安装,特别是对于 ci pipeline,例如 npm ci --only=production

你也可以将 node_modules 文件夹包含在你的代码库中(你可能正在使用 git),然后在构建/部署过程中只需执行 npm rebuild 命令(它可以跨平台运行),而且速度非常快。

这样做还可以让你完全控制所有依赖项(我知道这通常应该使用 shrinkwrap)

编辑:

另外,你可以将 progress 标志设置为 false,以至少提高 20% 的速度。这仅适用于 npm@v3.x.x,并且希望很快会有解决方法(请参见第二个链接)

npm set progress=false

谢谢!我们正在使用Subversion。这样还可以吗? - Prashanth
1
当然,但请记住,您可能会遇到一些合并问题。在我们的团队中,我们是这样做的,并且我们对此非常满意。完全控制依赖项,并且构建/部署过程非常快速。 - hereandnow78
1
你绝对不应该在代码库中包含 node_modules。版本控制和包管理的整个目的就是避免这种情况。 - Norgul

4
作为一种现代化的解决方案,您可以开始使用Docker。 Docker允许您将当前代码状态(包括安装的npm模块和其他好处)虚拟化并预定义为映像。
一旦构建了基础架构/环境的docker映像,并在本地或从远程存储库检索到它,它将存储在主机上,您可以在几秒钟内启动服务器。另一个好处是,在部署代码的任何机器上,您都可以使用相同的虚拟化代码基础设施。 Docker加速了安装/部署流程,是广泛使用的技术。
要开始使用docker,只需执行以下操作(所有片段仅为预设置的模拟/示例,不是最健壮/优雅的解决方案):
1)使用手册安装docker和docker-compose,并在docker.com上获取一些基本理解
2)在应用程序的根目录中编写Dockerfile文件
FROM node:6.9.5
RUN mkdir /usr/local/app
WORKDIR  /usr/local/app
COPY package.json package.json
RUN npm install

3) 在您的项目根目录下创建docker-compose.yml文件,其内容如下:

version: "2"
server:
  hostname: server
  container_name: server
  image: server
  build: .
  command: sh -c 'NODE_ENV=development PORT=8080 node app.js' 
  ports:
    - "8080:8080"
  volumes: #list of folders and files to use 
    - ${PWD}/server:/usr/local/server
    - ${PWD}/app.js:/usr/local/app.js

4) 要启动服务器,您需要使用 docker-compose up -d 命令。要查看日志,请使用 docker-compose logs -f server 命令。如果您重新启动服务器,则它会在构建完图像后的几秒钟内完成重启。然后将本地缓存构建层,因此下一次运行只需要几秒钟。

我知道这可能是一个复杂的解决方案,但我相信它具有最大的潜力/灵活性,并且在工业中被广泛使用。虽然对于以前没有使用过Docker的任何人来说需要学习一些东西,但在我谦逊的意见中,这是您问题的最佳解决方案。


在工作区进行更改后运行 npm run dev 似乎也非常缓慢。因此,尽管我可以通过 Docker 快速启动我的应用程序,但 npm 并不更快。 - rhand

3

对于我而言,没有什么比禁用杀毒软件(在我的情况下是Windows Defender)更有帮助的了。这样我从2分30秒缩短到1分钟之内。 使用npm-cache包,我能做到约30秒左右。 我尝试使用速度非常快的yarn,但在我的情况下它随机出现故障。


2
我们一直在努力解决这个问题,以加快我们的部署速度。
我们决定使用pac,它遵循其他答案中的原则。它会将npm模块压缩并包含在您的存储库中,因此您不必在提交和代码审核中拥有数百万个文件,只需为目标机器解压/重建即可。 https://www.npmjs.com/package/pac

2
你是说人们当时必须提交他们的 node_modules 文件夹吗? - zoran404

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接