npm install 相关过程及分析

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 installnpm update命令下载依赖后,除了将依赖包安装在node_modules 目录下外,还会在本地的缓存目录缓存一份。通过 npm config get cache 命令可以查询到

缓存目录下又存在两个目录:content-v2index-v5content-v2 目录用于存储 tar包的缓存,而index-v5目录用于存储tar包的 hashnpm 在执行安装时,可以根据 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)

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


相关推荐
林小白的日常几秒前
uniapp中wx.getFuzzyLocation报错如何解决
前端·javascript·uni-app
傻小胖20 分钟前
React 脚手架配置代理完整指南
前端·react.js·前端框架
EterNity_TiMe_31 分钟前
【论文复现】农作物病害分类(Web端实现)
前端·人工智能·python·机器学习·分类·数据挖掘
余生H1 小时前
深入理解HTML页面加载解析和渲染过程(一)
前端·html·渲染
吴敬悦1 小时前
领导:按规范提交代码conventionalcommit
前端·程序员·前端工程化
ganlanA1 小时前
uniapp+vue 前端防多次点击表单,防误触多次请求方法。
前端·vue.js·uni-app
卓大胖_1 小时前
Next.js 新手容易犯的错误 _ 性能优化与安全实践(6)
前端·javascript·安全
m0_748246351 小时前
Spring Web MVC:功能端点(Functional Endpoints)
前端·spring·mvc
SomeB1oody2 小时前
【Rust自学】6.4. 简单的控制流-if let
开发语言·前端·rust
云只上2 小时前
前端项目 node_modules依赖报错解决记录
前端·npm·node.js