npm intall 原理
一、npm 采用扁平方式进行下载
1. 下载方式
1.1 扁平化-理想状态
假如项目中你用到vue框架和element框架 他们的依赖都用到了bable,此时vue和element两个用到一样
依赖并且用到依赖版本都是一样的这个时候npm 下载是通过扁平化方式进行下载排序规则 是@
排在第一位 然后是
abcd...依次排序
安装某个二级模块时,若发现第一层级有相同名称,相同版本的模块,便直接复用那个模块
1.2. 非理想状态下
此时A依赖用到C依赖1.0版本 而B依赖用到C依赖2.0版本 此时就没有办法进行扁平化只能都下载来了
1.2 广度优先
如上图 npm会把 A依赖先下载 下来 然后下载B依赖 然后再去下载 C依赖1.0版本和C依赖2.0版本
npm会首先把顶层的依赖解析完后才会去解析子级依赖 所以 npm采用的广度优先下载方式
二、执行了npm install 会做什么?
1.查找文件
- 查找项目中的
package.json
和package-lock.json
文件 - 当用户在项目根目录执行
npm install
npm首先回去查找package.json文件 - 查找有没有package-lock.json文件 - 如果有package-lock.json 检查package-lock.json文件中依赖与package.json依赖版本是否一致
- 如果不一样,并且
npm
版本是5.4.2(高版本)及以上,那么将会优先按照package.json
中记录的版本���安装,并且更新lock文件。 - 如果没有package-lock.json文件,会根据package.json文件生成一个package-lock.json文件
- 如果不一样,并且
2.找到对应的依赖项
-
npm找的package.json文件后,首先会找到
dependncies
和devdependncies
这两个对象,里面提供了项目中所需要的依赖和依赖的版本号
3.解析依赖项
- npm会根据package.json 提供的依赖项 去npm 注册中心 找到对应依赖项和依赖的版本号
- 如果依赖项中还有依赖项,npm会递归的解析里面子依赖项(采用广度优先策略)
4.查找缓存
- npm会根据package-lock.json文件中的
name(名字)
vesion(版本)
integrity (完整性)
信息生成一个唯一的key,这个key能找到对应的index-v5 下的缓存记录 也就是npm cache 文件夹下的
-
npm config get cache
我们可以用命令去查看npm缓存 -
如果有缓存就解压到node_modules
-
如果没有就会去npm 下载资源 检查包的完整性 将对应依赖根据
name(名字)
vesion(版本)
integrity (完整性)
添加到缓存中,更新package-lock.json 文件
5.npm install 下载完整图
三、package-lock.json
1. pack-lock.json是做什么的?
刚刚我们说到了安装依赖的时候会去检查缓存,就是根据package-lock.json文件依赖 name vesion integrity
生成唯一key去检查缓存 除了这三个以外还有其他属性吗?以及package-lock.json作用还有什么呢?
-
version
:该参数指定了当前包的版本号 -
resolved
:该参数指定了当前包的下载地址 -
integrity
:用于验证包的完整性 -
dev
:该参数指定了当前包是一个开发依赖包 -
bin
:该参数指定了当前包中可执行文件的路径和名称 -
engines
:该参数指定了当前包所依赖的Node.js版本范围在npm5.4.2版本之后如果pack-lock.json与package.json依赖版本不一样,会根据package.json依赖版本
更新pack-lock.json依赖
四、npmrc
1 .npmrc能做什么?
-
提供信息配置
-
.npmrc文件提供npm包搜索和安装所需配置信息,这些信息包括 包名、版本、源地址、私有仓库地址等
-
设置依赖包安装来源:
-
.npmrc可以设置package.json文件里面依赖项的来源
-
优先级管理
- 电脑有很多个.npmrc, npm会根据一定顺序去读取配置,首先是项目中根目录中的.npmrc,其次就是
用户的.npmrc 然后就是全局的.npmrc 最后就是npm内置.npmrc
-
支持注释
- .npmrc 文件支持以
:
或#
进行注释
- .npmrc 文件支持以
-
支持命令行操作
- 我们可以使用
npm config list
命令,查看和设置.npmrc文件中配置
- 我们可以使用
-
支持环境变量
-
在.npmrc文件中可以使用
${VARIABLE_NAME}
的形式来设置环境变量iniregistry.npmjs.org/:_authToken=${NPM_TOKEN}
-
在windows系统中设置环境变量 使用
cmd
或者PowerShell
arduinosetx NPM_TOKEN "your-token-goes-here"
-
在 Unix 或 Linux 系统中,在你的 shell 配置文件(如
~/.bashrc
或~/.zshrc
)中添加如下行iniexport NPM_TOKEN="your-token-goes-here"
-
如果是做项目单独配置.npmrc环境变量可以这样设置
-
在package.json 配置scripts
json{ "scripts": { "start": "NPM_TOKEN='your-token-goes-here' node app.js" } }
-
在这个例子中,当你运行
npm start
命令时,NPM_TOKEN
环境变量就会被设置为'your-token-goes-here'
,并且在app.js
文件中可用。 -
请注意,你需要将
'your-token-goes-here'
替换为你的实际 token。
-
-
-
2 .npmrc文件
ini
registry=http://registry.npmjs.org/
# 定义npm的registry,即npm的包下载源
proxy=http://proxy.example.com:8080/
# 定义npm的代理服务器,用于访问网络
https-proxy=http://proxy.example.com:8080/
# 定义npm的https代理服务器,用于访问网络
strict-ssl=true
# 是否在SSL证书验证错误时退出
cafile=/path/to/cafile.pem
# 定义自定义CA证书文件的路径
user-agent=npm/{npm-version} node/{node-version} {platform}
# 自定义请求头中的User-Agent
save=true
# 安装包时是否自动保存到package.json的dependencies中
save-dev=true
# 安装包时是否自动保存到package.json的devDependencies中
save-exact=true
# 安装包时是否精确保存版本号
engine-strict=true
# 是否在安装时检查依赖的node和npm版本是否符合要求
scripts-prepend-node-path=true
# 是否在运行脚本时自动将node的路径添加到PATH环境变量中