编辑
2025-02-24
前端
00
请注意,本文编写于 75 天前,最后修改于 59 天前,其中某些信息可能已经过时。

目录

1. npm
1.1 npm install 原理
1.2 npm install 流程
1.3 npm2.x 和树形依赖目录
1.4 npm3.x 和扁平化依赖目录
1.5 npm5.x 和依赖锁定
1.6 依赖的区别
1.7 依赖匹配符号
2. yarn
2.1 特点
3. pnpm
3.1 pnpm 特点
3.2 如何生成 node_modules

本文介绍 各种包管理工具的简单原理(作者才疏学浅),各种优势和劣势

npm、yarn、pnpm 是常见的包管理工具

他们都是将一个一个的包下载并安装在项目的 node_modules

1. npm

首先是 npm,它是 node.js 自带的包管理工具,但是在现代项目中并不常用,主要原因就是

  1. 安装速度慢
  2. node_modules 占用空间大

1.1 npm install 原理

npm 会首先处理项目根目录下的依赖,然后逐层处理每个依赖包的依赖,直到所有依赖都被处理完毕(广度优先算法)。在处理每个依赖时,npm 会检查该依赖的版本号是否符合依赖树中其他依赖的版本要求,如果不符合,则会尝试安装适合的版本

最终形成的目录结构应该是这样的

比如安装 express

1.2 npm install 流程

1.3 npm2.x 和树形依赖目录

在早期 npm2.x 时代,npm 还没有支持扁平化安装,因此得到的安装目录就如上图所示

1.4 npm3.x 和扁平化依赖目录

npm3.x 引入了扁平化安装的方式,将所有的依赖都放到根目录来了

这会导致「幻影依赖/幽灵依赖」的问题,是指某个包未在 package.json 中定义,但项目中依然可以引用到的情况

但是因为 npm install 时,遍历 dependencies 是根据依赖的顺序生成的,如果顺序改变,就会导致生成的目录结构不一致

1.5 npm5.x 和依赖锁定

npm5.x 引入了 package-lock.json 和缓存机制(当之前安装过这个包,就会从缓存目录中直接复制到 node_modules 中)

package-lock.json

只有 package.json 时,npm 无法保证每次安装都能生成一样的 node_modules 树,也就可能导致以下问题:

  1. 多人协作时,依赖不一样导致开发不一致
  2. 发布上线时,服务器运行 npm install 生成了和在本地开发时不一样的依赖树,就可能导致线上问题 原因主要有
  3. 比如 package.json 中声明的依赖:A: '^1.0.5',因为是 ^,所以当 A 升级之后,就会安装新的依赖,导致依赖树不一致(依赖升级)
  4. 还是依赖 A,如果它依赖的 B,升级了,也会导致依赖书不一致,(依赖的依赖升级)

为了解决依赖不一致的问题,npm5.xinstall 之后会生成一个 package-lock.json 文件

  1. npm install 执行时,如果 package.jsonpackage-lock.json 中的版本兼容,会根据 package-lock.json 中的版本下载;如果不兼容,将会根据 package.json 的版本,更新 package-lock.json 中的版本,然后再去下载实际包
  2. package-lock.json 文件锁定所有模块的版本号,包括主模块和所有依赖子模块

package-lock.json 解决了 npm 无法保证每次安装都能生成一样的 node_modules 树的问题

1.6 依赖的区别

  1. dependencies 是无论开发环境还是生产环境都会安装的依赖
  2. devDependencies 是指可以在开发环境使用的依赖,一般指 ESLintPrettier 这些。在打包工具中都会排除开发依赖进行打包,可以使用 npm install --production 仅安装生产依赖
  3. optionalDependencies 指的是可以选择的依赖,这些依赖下载失败或者没有找到都不会影响 npm 的安装,但是不要和 dependencies 中重复
  4. peerDependencies 用于指定你当前的插件兼容的宿主必须要安装的包的版本,在 npm2.x 会自动安装,npm3.x 之后就只会警告了,需要自行安装

1.7 依赖匹配符号

  1. ^ 插入符号,会匹配到当前 major version 的最新版本,比如 "vue": "^3.4.27" 相当于 "vue": "3.x.x"
  2. 波浪号,会匹配到当前 minor version 的最新版本,也就是 3.4.x

2. yarn

2.1 特点

  1. yarn 使用多线程的方式安装依赖,而 npm 是单线程
  2. yarn 可以复用本地缓存的依赖包,相比于 npm 的缓存机制,它支持离线安装

3. pnpm

3.1 pnpm 特点

  1. 极大节省了硬盘空间
  2. 生成树形结构目录,而非扁平化目录,防止幽灵依赖

3.2 如何生成 node_modules

  1. 使用硬连接,将已安装的包链接到 node_modules
  2. 使用符号链接生成 node_modules 的嵌套结构(依赖的相互依赖关系使用软连接链接)

参考资料

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:pepedd864

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!