npm安装命令是哪一个(一个问题引发的NPM安装机制补习)
npm安装命令是哪一个(一个问题引发的NPM安装机制补习)npm install 执行之后,首先,检查并获取 npm 配置。 这里的优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的 .npmrc 文件。然后检查项目中是否有 package-lock.json 文件。获取项目级的.npmrc 用户配置文件路径:看一下用户级别的配置文件内容是什么:3.2 首先检查配置对于 ^ 如图所示:对于 * 如图所示:3.1 npm安装流程图:
一、前言平常只会用到简单的 npm 命令,可是面试的时候,就有可能这样问了
- 请问 package.json 中版本 ~1.2.3和^1.2.3 有什么区别?
- 请问执行 npm install 时,是怎么安装依赖包的?相同的依赖包怎么处理?
猛地一问,大家是不是会有这样的表情?
- ~ 会匹 配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x版本,但是不包括1.3.0
- ^ 会匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,包括1.3.0,但是不包括2.0.0
- * 通配符,匹配所有的版本,安装最新的
相关示意图如下:
对于 ~ 如图所示:
对于 ^ 如图所示:
对于 * 如图所示:
3.1 npm安装流程图:
3.2 首先检查配置
npm install 执行之后,首先,检查并获取 npm 配置。
这里的优先级为:项目级的
.npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的
.npmrc 文件。然后检查项目中是否有 package-lock.json 文件。
- 获取项目级的.npmrc 用户配置文件路径:
看一下用户级别的配置文件内容是什么:
- 获取全局级的.npmrc 全局配置文件路径:
3.3 检查没有package-lock.json文件
- 从 npm 远程仓库获取包信息
- 根据 package.json 构建依赖树(构建依赖的方式在下面)
3.4 npm的模块依赖构建
3.4.1、npm2安装多级的依赖模块采用嵌套的安装方式
这样的依赖方式,可以想象有多么的不合适,那我们如何能在实现依赖间多版本兼容的前提下,减少这种模块冗余呢?于是npm3做了改进。
3.4.2、npm3下的模块依赖构建采用扁平化的安装方式
npm3会"尽量"把逻辑上某个层级的模块在物理结构上"全部"放在项目的第一层级里,具体概括为以下三种情况:
- 在安装某个二级模块时,若发现第一层级还没有相同名称的模块,便把这第二层级的模块放在第一层级
- 在安装某个二级模块时,若发现第一层级有相同名称,但版本不同的模块,便只能嵌套在自身的父模块下方
3.5 npm的模块依赖真实构建
注意:上一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包。
在缓存中依次查找依赖树中的每个包,
- 不存在缓存:
- 从 npm 远程仓库下载包
- 校验包的完整性
- 校验不通过: 重新下载
- 校验通过:
- 将下载的包复制到 npm 缓存目录
- 将下载的包按照依赖结构解压到 node_modules
- 存在缓存:
- 将缓存按照依赖结构解压到 node_modules
- 将包解压到 node_modules
再次看一下整个过程如图:
3.6 npm缓存
在执行 npm install 或 npm update 命令下载依赖后,除了将依赖包安装在node_modules目录下外,还会在本地的缓存目录缓存一份。
看一下cache的文件:
看一下这个_cacache文件:
content-v2 目录用于存储 tar 包的缓存,而 index-v5 目录用于存储 tar 包的 hash。
npm 在执行安装时,可以根据 package-lock.json 中存储的 integrity、version、name 生成一个唯一的 key 对应到 index-v5 目录下的缓存记录,从而找到 tar 包的 hash,然后根据 hash 再去找缓存的 tar包直接使用。
我们可以找一个包在缓存目录下搜索测试一下,在 index-v5 搜索一下包路径:
格式化一下数据:
上面的 _shasum 属性 5bf45e8e49ba4189e17d482789dfd15bd140b7b6 即为 tar 包的 hash, hash的前几位 6926 即为缓存的前两层目录,我们进去这个目录就可以找到的压缩后的依赖包:
- 本地项目安装:npm install xxx
本地安装是,所有的依赖都会放到 ./node_module 文件夹下面,同时每个依赖的可执行文件都会软链接到 ./node_module/bin/ 目录下,这样就可以在 package.json 中设置 script 时使用到这些命令,如精灵项目中
- 全局安装:npm install -g xxx
执行 npm root -g 输出全局安装路径为:
切到该路径下,瞧一瞧:
之所以能够全局使用,是因为将 /Users/mac/.nvm/versions/node/v12.13.1/lib/node_module 目录下每个依赖的可执行文件软链接 到/Users/mac/.nvm/versions/node/v12.13.1/bin 目录下。
如果我们在项目代码中引用了一个模块,模块查找流程如下:
- 在当前模块路径下搜索
- 在当前模块 node_modules路径下搜素
- 在上级模块的 node_modules 路径下搜索
- ...
- 直到搜索到全局路径中的 node_modules
daimai项目中,使用的是固定写死的版本2.1.0-pf.2,而@feitu/fsp-measure依赖的是^2.1.4,导致依赖版本不一致,所以其结果是,导致habo.perf({ttfp: 1212});打点的时候,name值取的是gaotu而不是gt-damai。
1212});打点的时候,name值取的是gaotu而不是gt-damai。