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)

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


相关推荐
却尘14 分钟前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare15 分钟前
浅浅看一下设计模式
前端
Lee川18 分钟前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix1 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人1 小时前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl1 小时前
OpenClaw 深度技术解析
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人1 小时前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼1 小时前
shadcn/ui,给你一个真正可控的UI组件库
前端
布列瑟农的星空1 小时前
前端都能看懂的Rust入门教程(三)——控制流语句
前端·后端·rust