CI环境下的npm优化及工程化问题解析

CI 环境下的 npm 优化

CI 环境下的 npm 配置 和 本地环境下的 npm 操作有些许不同,我们首先来看看 CI 环境下的 npm 优化方法

1. 合理使用 npm ci 命令 和 npm install 命令

顾名思义,npm ci 命令就是专门为 CI 环境准备的安装命令,相比于 npm install命令,它的不同之处有以下几点。

  • npm ci 命令要求项目中必须存在 package-lock.json 或 npm-shrinkwrap.json命令
  • npm ci 命令完全根据 package-lock.json 文件安装依赖,这样可以保证开发团队成员使用版本一致的依赖。
  • 因为 npm ci 命令完全根据 package-lock.json 文件安装依赖,因此在安装过程中,它不需要求解依赖满足问题及构造依赖树,安装过程更加迅速。
  • npm ci 命令在执行安装时会先删除项目中现有的 node_modules 目录,重新安装。
  • npm ci 命令只能一次性安装项目中所有的依赖包,无法安装单个依赖包。
  • 如果 package-lock.json 文件和 package.json 文件冲突,那么执行 npm ci 命令时会直接报错。
  • 执行 npm ci 命令永远不会改变 package.json 和 package-lock.json 文件的内容。

基于以上特效,我们在 CI 环境下使用 npm ci 命令代替 npm install 命令时,一般会获得更加稳定、一致、迅速的安装体验

2. 使用 package-lock.json 文件缩短依赖安装时间

项目中使用 package-lock.json 文件一般可以显著缩短依赖安装时间。这是因为 package-lock.json 文件中已经缓存了每个包的具体版本信息和下载链接,不要再去远程仓库进行查询即可直接进入文件完整性校验环节,减少大量网络请求。

除了以上内容之外,在 CI 环境下,缓存 node_modules 目录文件也是企业使用包管理工具常用的优化方法。

为什么有 xxxDependencies

npm 设计了以下几种依赖类型声明

  • dependencies: 项目依赖
  • devDependencies: 开发依赖
  • peerDependencies: 同版本依赖
  • bundledDependencies: 捆绑依赖
  • optionalDependencies: 可选依赖

1.dependencies: 项目依赖

这些依赖会成为线上生产环节中代码组成部分,当它关联的 npm 包会下载时,dependencies 下的模块也会作为依赖一起被下载。

2.devDependencies: 开发依赖

不会自动下载,因为 devDependencies 一般只在开发阶段起作用,或只在开发环境中被用到。 如 webpack,预处理器 babel-loader、scss-loader,测试工具 E2E、Chai 等,这些都是辅助开发的工具包,无须在生产环境中使用。

并不是只有 dependencies 下的模块才会被一起打包,而 devDependencies 下的模块一定不会被打包。实际上,模块是否作为依赖被打包,完全取决于项目里是否引入了该模块。

3.peerDependencies: 同版本依赖

简单来说: 如果你安装了我,最好你也安装我的依赖。

4.bundledDependencies: 捆绑依赖

和 npm pack 打包命令有关。

1
2
3
4
5
6
7
8
9
10
11
{
"name": "test",
"version": "1.0.0",
"dependencies": {
"dep": "^0.0.2"
},
"devDependencies": {
"devD1": "^0.0.2"
},
"bundledDependencies": ["bundleD1", "bundleD1"]
}

需要注意:bundledDependencies 中指定的依赖包必须先在 dependencies 和 devDependencies 中声明过,否则执行 npm pack 命令阶段会报错。

5.optionalDependencies: 可选依赖

该依赖如果安装失败,也不会影响整个安装过程。一般很少使用它,也不建议使用,会增加项目的不确定性和复杂性。