npm install的整体流程:
检查 .npmrc 文件:优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的 .npmrc 文件
检查项目中有无 lock 文件:
-
无 lock 文件:
- 从 npm 远程仓库获取包信息
- 根据 package.json 构建依赖树,构建过程:
- 构建依赖树时,不管其是直接依赖还是子依赖的依赖,优先将其放置在 node_modules 根目录。
- 当遇到相同模块时,判断已放置在依赖树的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 node_modules 下放置该模块。
- 注意这一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包
-
在缓存中依次查找依赖树中的每个包
-
不存在缓存:
- 从 npm 远程仓库下载包
- 校验包的完整性
- 校验不通过: 重新下载
-
校验通过:
- 将下载的包复制到 npm 缓存目录
- 将下载的包按照依赖结构解压到 node_modules
-
存在缓存:
- 将缓存按照依赖结构解压到 node_modules
- 将包解压到 node_modules
-
- 生成 lock 文件
-
有 lock 文件:
- 检查 package.json 中的依赖版本是否和 package-lock.json 中的依赖有冲突。
- 如果没有冲突,直接跳过获取包信息、构建依赖树过程,开始在缓存中查找包信息,后续过程相同
npm 提供了几个命令来管理缓存数据:
npm cache add
:官方解释说这个命令主要是 npm 内部使用,但是也可以用来手动给一个指定的 package 添加缓存。
npm cache clean
:删除缓存目录下的所有数据,为了保证缓存数据的完整性,需要加上 --force 参数。
npm cache verify
:验证缓存数据的有效性和完整性,清理垃圾数据。
基于缓存数据,npm 提供了离线安装模式,分别有以下几种:
--prefer-offline
:优先使用缓存数据,如果没有匹配的缓存数据,则从远程仓库下载。
--prefer-online
:优先使用网络数据,如果网络数据请求失败,再去请求缓存数据,这种模式可以及时获取最新的模块。
--offline
:不请求网络,直接使用缓存数据,一旦缓存数据不存在,则安装失败。
使用建议
开发系统应用时,建议把 package-lock.json 文件提交到代码版本仓库,从而保证所有团队开发者以及 CI 环节可以在执行 npm install 时安装的依赖版本都是一致的。
在开发一个 npm包 时,你的 npm包 是需要被其他仓库依赖的,由于上面我们讲到的扁平安装机制,如果你锁定了依赖包版本,你的依赖包就不能和其他依赖包共享同一 semver 范围内的依赖包,这样会造成不必要的冗余。所以我们不应该把package-lock.json 文件发布出去( npm 默认也不会把 package-lock.json 文件发布出去)。
参考:https://cloud.tencent.com/developer/article/1555982