是什么?
与 npm install 有什么不同?
- npm ci 要求项目必须存在 lockfile 文件(package-lock.json、yarn.lock、npm-shrinkwrap.json)。
- npm ci 完全根据 lockfile 文件按照依赖。
- npm ci 安全根据 lockfile 文件安装,所以按照的过程不需要求解依赖满足问题、构造依赖树,过程会更加快。
- npm ci 会一次性安装所有的依赖,不能一次安装一个。
- npm ci 安装时, 如果 package.json 和 package-lock.json 存在冲突,会报错。
npm ci 永远不会改变 package.json 和 lockfile 文件。
为什么需要 lockfile
从 npm v5 版本开始,增加了 package-lock.json 文件。我们知道package-lock.json 文件的作用是锁定依赖安装结构,目的是保证在任意机器上执行 npm install 都会得到完全相同的 node_modules 安装结果。
为什么单一的 lockfile 不能确定唯一的依赖树
不同的 npm 版本的安装算法和依赖安装策略不同
- npm install 将根据 package.json 中的 semver-range version 更新依赖,某些依赖项自上次安装以来,可能已发布了新版本。
因此,保证能够完整准确地还原项目依赖,就是 lockfiles 出现的原因。
要不要提交 lockfiles 到仓库?
- 开发一个应用,我建议把 package-lock.json 文件提交到代码版本仓库。这样可以保证项目组成员、运维部署成员或者 CI 系统,在执行 npm install 后,能得到完全一致的依赖安装内容。
- 如果目标是开发一个给外部使用的库,那就要谨慎考虑了,因为库项目一般是被其他项目依赖的,在不使用 package-lock.json 的情况下,就可以复用主项目已经加载过的包,减少依赖重复和体积。
- 如果我们开发的库依赖了一个精确版本号的模块,那么提交 lockfiles 到仓库可能会造成同一个依赖不同版本都被下载的情况。如果作为库开发者,真的有使用某个特定版本依赖的需要,一个更好的方式是定义 peerDependencies。
npm 早期使用的是 npm-shrinkwarp.json,它于 package-lock.json 最大的不同在于,npm 发布包的时候,默认是将 npm-shrinkwarp.json 一起发布的。
为什么会有 xxxDependencies?
- dependencies 项目依赖
- devDependencies 开发依赖
- peerDependencies 前置依赖
- bundleDependencies 绑定依赖
- optionalDependencies 可选依赖
dependencies 项目依赖
项目依赖,这些依赖会成为线上代码的一部分。关联的 npm 被下载时,项目依赖也会被一起下载。devDependencies 开发依赖
开发依赖,不会被自动下载,开发依赖只会在开发阶段和开发环境被用到,例如: webpack、babel-loader 等等。
这里需要特别说明的是:并不是只有在 dependencies 中的模块才会被一起打包,而在 devDependencies 中的依赖一定不会被打包。实际上,依赖是否被打包,完全取决于项目里是否被引入了该模块。dependencies 和 devDependencies 在业务中更多的只是一个规范作用,我们自己的应用项目中,使用 npm install 命令安装依赖时,dependencies 和 devDependencies 内容都会被下载。peerDependencies 前置依赖
不明思议,前置依赖就是当我们项目按照依赖 A 时,A 依赖了 B,所以我们同时需要 B。如果缺少了 B ,A 不能正常运行。所以这类依赖能正常运行的前提是核心依赖也要被提前安装。bundleDependencies 绑定依赖
绑定依赖和 npm pack 打包命令有关,例如:
当执行 npm pack 时会生成一个压缩包,{
"key": "value",
"name": "test_test-all",
"version": "0.0.1",
"description": "项目描述...",
"main": "index.js",
"license": "MIT",
"dependencies": {
"test_test-aaa": "link:../test-aaa"
},
"devDependencies": {
"test_test-bbb": "link:../test-bbb"
},
"bundledDependencies": [
"test_test-aaa",
"test_test-bbb"
]
}
压缩包中就包含 bundledDependencies 中声明的依赖。
业务方使用 npm install xxx.tgz 命令时,也会安装 bundledDependencies 中声明的依赖。要注意的是:在 bundledDependencies 中指定的依赖包,必须先在 dependencies 和 devDependencies 声明过,否则在 npm pack 阶段会进行报错。
optionalDependencies 可选依赖
可选依赖,不明思议即使按照失败,也不会影响整个按照过程。但是它会增加项目的不确定性和复杂性。所以一般很少使用。
Npm 团队最佳实践
- 优先使用 npm v5.4.2 版本以上的 npm 版本,目的是为了保证团队 npm 的先进性和稳定性。
- 项目第一次搭建时,使用 npm install 按照依赖,并提交 package.json 和 package-lock.json,不提交 node_modules。
- 项目其他成员首次 clone 项目是,执行一次 npm install。
- 项目中有需要升级的需求:
- 小版本使用 npm update @小版本
- 大版本使用 npm install @大版本
- 也可以手动修改 package.json,但是必须执行 npm install
- 升级完成之后提交 package.json 和 package-lock.json 文件。
- 项目中需要降级的需求:
- 执行 npm install @版本
- 降级完成之后提交 package.json 和 package-lock.json 文件
- 项目中有删除依赖的需求:
- 执行 npm uninstall xxx
- 验证无问题之后提交 package.json 和 package-lock.json 文件
- 项目中任何成员有提交 package.json 和 package-lock.json 文件的操作后,其他成员都需要拉取代码,执行 npm install 更新依赖
- 任何时候都不要修改 package-lock.json
- 如果 package-lock.json 出现冲突,建议本地删除 package-lock.json,再次拉远程的 package-lock.json 和 package.json,在执行 npm install 。