快捷搜索:  汽车  科技

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 时,是怎么安装依赖包的?相同的依赖包怎么处理?

猛地一问,大家是不是会有这样的表情?

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(1)

二、开篇了解之NPM依赖包版本号的区别
  • ~ 会匹 配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x版本,但是不包括1.3.0
  • ^ 会匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,包括1.3.0,但是不包括2.0.0
  • * 通配符,匹配所有的版本,安装最新的


相关示意图如下:

对于 ~ 如图所示:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(2)

对于 ^ 如图所示:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(3)

对于 * 如图所示:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(4)

三、npm的安装机制

3.1 npm安装流程图:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(5)

3.2 首先检查配置

npm install 执行之后,首先,检查并获取 npm 配置。 这里的优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的 .npmrc 文件。然后检查项目中是否有 package-lock.json 文件。

  • 获取项目级的.npmrc 用户配置文件路径:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(6)

看一下用户级别的配置文件内容是什么:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(7)

  • 获取全局级的.npmrc 全局配置文件路径:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(8)

3.3 检查没有package-lock.json文件

  • 从 npm 远程仓库获取包信息
  • 根据 package.json 构建依赖树(构建依赖的方式在下面)

3.4 npm的模块依赖构建
3.4.1、npm2安装多级的依赖模块采用嵌套的安装方式

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(9)

这样的依赖方式,可以想象有多么的不合适,那我们如何能在实现依赖间多版本兼容的前提下,减少这种模块冗余呢?于是npm3做了改进。


3.4.2、npm3下的模块依赖构建采用扁平化的安装方式

npm3会"尽量"把逻辑上某个层级的模块在物理结构上"全部"放在项目的第一层级里,具体概括为以下三种情况:

  • 在安装某个二级模块时,若发现第层级还没有相同名称的模块,便把这第二层级的模块放在第一层级

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(10)

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(11)

  • 在安装某个二级模块时,若发现第层级有相同名称,但版本不同的模块,便只能嵌套在自身的父模块下方

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(12)

3.5 npm的模块依赖真实构建

注意:上一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包。

在缓存中依次查找依赖树中的每个包,

  • 不存在缓存:
    • 从 npm 远程仓库下载包
    • 校验包的完整性
    • 校验不通过: 重新下载
    • 校验通过:
      • 将下载的包复制到 npm 缓存目录
      • 将下载的包按照依赖结构解压到 node_modules
  • 存在缓存:
    • 将缓存按照依赖结构解压到 node_modules
    • 将包解压到 node_modules

再次看一下整个过程如图:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(13)

3.6 npm缓存

在执行 npm install 或 npm update 命令下载依赖后,除了将依赖包安装在node_modules目录下外,还会在本地的缓存目录缓存一份。

看一下cache的文件:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(14)

看一下这个_cacache文件:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(15)

content-v2 目录用于存储 tar 包的缓存,而 index-v5 目录用于存储 tar 包的 hash。

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

我们可以找一个包在缓存目录下搜索测试一下,在 index-v5 搜索一下包路径:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(16)

格式化一下数据:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(17)

上面的 _shasum 属性 5bf45e8e49ba4189e17d482789dfd15bd140b7b6 即为 tar 包的 hash, hash的前几位 6926 即为缓存的前两层目录,我们进去这个目录就可以找到的压缩后的依赖包:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(18)

安装位置
  • 本地项目安装:npm install xxx

本地安装是,所有的依赖都会放到 ./node_module 文件夹下面,同时每个依赖的可执行文件都会软链接到 ./node_module/bin/ 目录下,这样就可以在 package.json 中设置 script 时使用到这些命令,如精灵项目中

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(19)

  • 全局安装:npm install -g xxx

执行 npm root -g 输出全局安装路径为:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(20)

切到该路径下,瞧一瞧:

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(21)

之所以能够全局使用,是因为将 /Users/mac/.nvm/versions/node/v12.13.1/lib/node_module 目录下每个依赖的可执行文件软链接 到/Users/mac/.nvm/versions/node/v12.13.1/bin 目录下。

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(22)

模块检查流程

如果我们在项目代码中引用了一个模块,模块查找流程如下:

  • 在当前模块路径下搜索
  • 在当前模块 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。

npm安装命令是哪一个(一个问题引发的NPM安装机制补习)(23)

1212});打点的时候,name值取的是gaotu而不是gt-damai。

猜您喜欢: