npm install
refer: https://cloud.tencent.com/developer/article/1555982
npm install 的结构经历了以下几个过程,
一, 嵌套结构 -
node_modules 结构和package.json 结构一一对应,层级结构明显,每次安装目录结构都是相同的;
在不同的层级依赖中,可能引用了同一个模块,导致大量冗余;
在windows系统中,文件路径最大长度为260个字符,嵌套层级过深可能导致不可预知的问题
二, 扁平结构 -
3.X版本 安装模块时,不管是直接依赖还是子依赖的依赖,优先将其安装在node_modules根目录
相同模块不同版本的安装顺序未知
三, Lock文件 - 参考yarn(2016)
5.X版本 package-lock.json锁定依赖结构。每次安装生成的目录结构保持一致;缓存了每个包具体版本和下载链接,不需要再去远程仓库进行查询,直接进入文件完整性校验环节,减少了大量的网络请求,显著加速依赖安装时间
package-lock.json文件基本组成:
version: 包版本 resolved: 包具体安装来源 integrity: 包hash值,用来验证包是否有效 requires:对应依赖 dependencies:依赖包
四, Lock文件与package文件的共生 -
自npm 5.0版本发布以来,npm i的规则发生了三次变化。
1、npm 5.0.x 版本,不管package.json怎么变,npm i 时都会根据package-lock文件下载
2、5.1.0版本后 npm install 会无视package-lock文件 去下载最新的npm
3、5.4.2版本后 如果改了package.json,且package.json和package-lock文件不同,那么执行`npm i`时npm会根据package中的版本号以及语义含义去下载最新的包,并更新至lock。如果两者是同一状态,那么执行`npm i `都会根据lock下载,不会理会package实际包的版本是否有新。
总结 -
1.检查.npmrc文件:优先级为:项目级的.npmrc文件 > 用户级的.npmrc文件> 全局级的.npmrc文件 > npm 内置的.npmrc文件
2.检查项目中有无lock文件。
------无lock文件:
3.从npm远程仓库获取包信息
4.根据package.json构建依赖树:构建依赖树时,不管其是直接依赖还是子依赖的依赖,优先将其放置在node_modules根目录。当遇到相同模块时,判断已放置在依赖树的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的node_modules下放置该模块。(只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包)
5.在缓存中依次查找依赖树中的每个包 不存在缓存则从npm远程仓库下载包;校验包的完整性;校验不通过则重新下载,校验通过则将下载的包复制到npm缓存目录;将下载的包按照依赖结构解压到node_modules 。 若存在缓存:将缓存按照依赖结构解压到 node_modules
6.生成lock文件
--------有lock文件:
3.检查package.json中的依赖版本是否和package-lock.json中的依赖有冲突。
4.如果没有冲突,直接跳过获取包信息、构建依赖树过程,开始在缓存中查找包信息,后续过程相同