1、install 完整流程
1.1、根据 .npmrc 进行安装前环境配置
注意:镜像源就是在这个文件中配置的
优先级:
- 每个项目的配置文件(
/path/to/my/project/.npmrc
) - 每个工作区的配置文件(包含
pnpm-workspace.yaml
文件的目录) - 每位用户的配置文件(
~/.npmrc
) - 全局配置文件(
/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被修改的原因?
- 新增或者删除了一些包,但是没有及时 install,比如 a 同学给 package.json 添加了一个 package,但是没有执行 npm install,代码被 push 上去后,b 同学执行 npm i,就会发现 lockfiles 被更改了
- 挪动了包的位置,将部分包的位置从 dependencies 移动到 devDependencies这种操作,虽然包未变,但是也会影响 lockfiles,会将部分包的 dev 字段设置为 true
- registry 的影响,经过实际使用发现,如果我们 node_modules 文件夹下的包中下载时的的 registry 与 lockfiles 中包即使 version 相同,但是registry是不同,执行 npm i 时也会修改。
4.3、yarn.lock被修改的原因?
- 当package.json变化
- package.json中的包版本与yarn.lock中的版本不同
- 执行yarn add重新安装依赖
- 执行yarn upgrade更新所有依赖
4.4、如何区分版本号呢?
有童鞋对 版本号中的 ~ ^ 可能傻傻分不清,那林大大就分享下我自己的理解吧,~ 中文名叫波浪号,浪在海边,而海一般都在外面海边,所以是用来限定最后一位 的,而 ^ 是方向向上指向天空的,可以理解为 中天,所以用来限定中间那位 的。位置记好后,再来记一下,这俩符号 都是 代表 大于等于 这个数字,所以是不是就理解到不会忘了呢~
~1.1.1 范围是 [1.1.1, 1.2.0)
^1.1.1 范围是 [1.1.1, 2.0.0)
------有不懂的可以相互讨论交流噢~我有错误的话,请指出噢~------