npm i 机制
-
检查 .npmrc 文件。
.npmrc 里是一些配置信息。优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的 .npmrc 文件。 -
确定首层依赖。 确定工程中的首层依赖,也就是
dependencies和devDependencies属性中直接指定的模块。工程本身是整棵依赖树的根节点,每个首层依赖模块都是根节点下面的一棵子树,npm 会开启多进程从每个首层依赖模块开始逐步寻找更深层级的节点。 -
检查项目中有无版本描述文件(npm-shrinkwrap.json 或 package-lock.json)文件。(npm5项目默认生成package-lock.json)
- 无版本描述文件文件。
从 npm 远程仓库获取包信息。 - 有版本描述文件文件。
检查 package.json 中的依赖版本是否和 package-lock.json 中的依赖有冲突。 如果没有冲突,直接跳过获取包信息、构建依赖树过程,根据 package.json 构建依赖树,直接跳到第六步。
- 无版本描述文件文件。
-
模块扁平化(
dedupe)
上一步获取到的是一棵完整的依赖树,其中可能包含大量重复模块。 npm3 以前会严格按照依赖树的结构进行安装,因此会造成模块冗余。yarn和从npm5开始默认加入了一个dedupe的过程。它会遍历所有节点,逐个将模块放在根节点下面,也就是node-modules的第一层。当发现有重复模块时,则将其丢弃。这里需要对重复模块进行一个定义,它指的是模块名相同且semver兼容。每个semver都对应一段版本允许范围,如果两个模块的版本允许范围存在交集,那么就可以得到一个兼容版本,而不必版本号完全一致,这可以使更多冗余模块在dedupe过程中被去掉。 -
检查缓存。
在缓存中依次查找依赖树中的每个包 ,如果不存在缓存,从 npm 远程仓库下载包,需校验包的完整性,校验通过,将下载的包复制到 npm 缓存目录,然后进行下一步。如果存在缓存,直接进行下一步。 -
解压到 node_modules。
-
生成lock 文件。
参考文档: