npm install 相关过程及分析
作者:mmseoamin日期:2024-02-20

1、install 完整流程

1.1、根据 .npmrc 进行安装前环境配置

注意:镜像源就是在这个文件中配置的

优先级:

  1. 每个项目的配置文件(/path/to/my/project/.npmrc)
  2. 每个工作区的配置文件(包含 pnpm-workspace.yaml 文件的目录)
  3. 每位用户的配置文件( ~/.npmrc )
  4. 全局配置文件( /etc/npmrc )

1.2、检查有无 lock.json文件

注意:npm/pnpm 检查的是 package-lock.json,yarn检查的是 yarn.lock,cnpm没有对应的lock文件,所以不会进行对比检查

1.2.1、无 lock文件

此时会按照package.json文件,去远程仓库获取依赖包的最新信息(此时并未下载依赖,这是获取依赖包的相关信息)

1.2.2、有lock文件

来到重点了,package.json和package-lock.json的冲突,其实咱们现在npm版本估计都在v7左右了,所以不用考虑以前老版本的逻辑,按最新的来:

lock文件中依赖的版本在package.json的版本范围内,没有冲突,则按照lock文件的来,直接跳转步骤1.4。

否则按照package.json的来,有冲突(去远程仓库获取依赖包的最新信息)

1.3、构建依赖树

  • 构建依赖树时,不管其是直接依赖还是子依赖的依赖,优先将其放置在 node_modules 根目录。
  • 当遇到相同模块时,判断已放置在依赖树的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 node_modules 下放置该模块。
  • 注意这一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包

    1.4、检查缓存

    1.4.1、无缓存

    继续进行后续步骤 1.5

    1.4.2、有缓存

    跳转步骤到 1.6

    1.5、下载依赖包并添加到依赖

    去远程仓库下载包,并进行校验,校验未通过则重新下载,校验通过后会将包下载到npm缓存中

    1.6、解压到node_modules

    1.7、生成lock文件

    2、npm缓存策略

    在执行 npm install 或 npm update命令下载依赖后,除了将依赖包安装在node_modules 目录下外,还会在本地的缓存目录缓存一份。通过 npm config get cache 命令可以查询到

    缓存目录下又存在两个目录:content-v2、index-v5,content-v2 目录用于存储 tar包的缓存,而index-v5目录用于存储tar包的 hash,npm 在执行安装时,可以根据 package-lock.json 中存储的 integrity、version、name 生成一个唯一的 key 对应到 index-v5 目录下的缓存记录,从而找到 tar包的 hash,然后根据 hash 再去找缓存的 tar包直接使用。

    2.1、缓存管理

    • npm cache add:官方解释说这个命令主要是 npm 内部使用,但是也可以用来手动给一个指定的 package 添加缓存。
    • npm cache clean:删除缓存目录下的所有数据,为了保证缓存数据的完整性,需要加上 --force 参数。
    • npm cache verify:验证缓存数据的有效性和完整性,清理垃圾数据。

      3、npm ci

      npm ci 可以自动删除 node_modules 目录,无法安装单个依赖,且不会改变 package-lock.json 文件,但执行时 package-lock.json 必须存在且版本号与 package.json 要求一致,如果 package.json 中不存在依赖 A 或者依赖 A 版本和 lock 中不兼容,npm ci 就会报错。

      相对于 npm install 好处,我的理解是:不会主动更新版本,保持依赖在原有可掌握的范围内,这将大大保持所有开发者的统一性。一般情况下,使用npm install足够了,但是要是对依赖版本要求很严格的话,就使用npm ci

      4、疑难解答

      4.1、90%依赖报错解决方法?

      rm -rf node_modules && npm cache clean --force && npm i

      4.2、package.json被修改的原因?

      1. 新增或者删除了一些包,但是没有及时 install,比如 a 同学给 package.json 添加了一个 package,但是没有执行 npm install,代码被 push 上去后,b 同学执行 npm i,就会发现 lockfiles 被更改了
      2. 挪动了包的位置,将部分包的位置从 dependencies 移动到 devDependencies这种操作,虽然包未变,但是也会影响 lockfiles,会将部分包的 dev 字段设置为 true
      3. registry 的影响,经过实际使用发现,如果我们 node_modules 文件夹下的包中下载时的的 registry 与 lockfiles 中包即使 version 相同,但是registry是不同,执行 npm i 时也会修改。

      4.3、yarn.lock被修改的原因?

      1. 当package.json变化
      2. package.json中的包版本与yarn.lock中的版本不同
      3. 执行yarn add重新安装依赖
      4. 执行yarn upgrade更新所有依赖

       4.4、如何区分版本号呢?

       有童鞋对 版本号中的 ~ ^ 可能傻傻分不清,那林大大就分享下我自己的理解吧,~ 中文名叫波浪号,浪在海边,而海一般都在外面海边,所以是用来限定最后一位的,而 ^  是方向向上指向天空的,可以理解为 中天,所以用来限定中间那位的。位置记好后,再来记一下,这俩符号 都是 代表 大于等于 这个数字,所以是不是就理解到不会忘了呢~

      ~1.1.1 范围是 [1.1.1, 1.2.0)

      ^1.1.1 范围是 [1.1.1, 2.0.0)

      ------有不懂的可以相互讨论交流噢~我有错误的话,请指出噢~------