本文介绍 各种包管理工具的简单原理(作者才疏学浅),各种优势和劣势
npm、yarn、pnpm 是常见的包管理工具
他们都是将一个一个的包下载并安装在项目的 node_modules
中
首先是 npm,它是 node.js
自带的包管理工具,但是在现代项目中并不常用,主要原因就是
node_modules
占用空间大npm install
原理npm 会首先处理项目根目录下的依赖,然后逐层处理每个依赖包的依赖,直到所有依赖都被处理完毕(广度优先算法)。在处理每个依赖时,npm 会检查该依赖的版本号是否符合依赖树中其他依赖的版本要求,如果不符合,则会尝试安装适合的版本
最终形成的目录结构应该是这样的
比如安装 express
npm install
流程npm2.x
和树形依赖目录在早期 npm2.x
时代,npm
还没有支持扁平化安装,因此得到的安装目录就如上图所示
npm3.x
和扁平化依赖目录npm3.x
引入了扁平化安装的方式,将所有的依赖都放到根目录来了
这会导致「幻影依赖/幽灵依赖」的问题,是指某个包未在 package.json 中定义,但项目中依然可以引用到的情况
但是因为 npm install
时,遍历 dependencies
是根据依赖的顺序生成的,如果顺序改变,就会导致生成的目录结构不一致
npm5.x
和依赖锁定npm5.x
引入了 package-lock.json
和缓存机制(当之前安装过这个包,就会从缓存目录中直接复制到 node_modules
中)
package-lock.json
只有 package.json
时,npm
无法保证每次安装都能生成一样的 node_modules
树,也就可能导致以下问题:
npm install
生成了和在本地开发时不一样的依赖树,就可能导致线上问题
原因主要有package.json
中声明的依赖:A: '^1.0.5'
,因为是 ^
,所以当 A
升级之后,就会安装新的依赖,导致依赖树不一致(依赖升级)A
,如果它依赖的 B
,升级了,也会导致依赖书不一致,(依赖的依赖升级)为了解决依赖不一致的问题,npm5.x
在 install
之后会生成一个 package-lock.json
文件
npm install
执行时,如果 package.json
和 package-lock.json
中的版本兼容,会根据 package-lock.json
中的版本下载;如果不兼容,将会根据 package.json
的版本,更新 package-lock.json
中的版本,然后再去下载实际包package-lock.json
文件锁定所有模块的版本号,包括主模块和所有依赖子模块package-lock.json
解决了 npm
无法保证每次安装都能生成一样的 node_modules
树的问题
dependencies
是无论开发环境还是生产环境都会安装的依赖devDependencies
是指可以在开发环境使用的依赖,一般指 ESLint
、Prettier
这些。在打包工具中都会排除开发依赖进行打包,可以使用 npm install --production
仅安装生产依赖optionalDependencies
指的是可以选择的依赖,这些依赖下载失败或者没有找到都不会影响 npm
的安装,但是不要和 dependencies
中重复peerDependencies
用于指定你当前的插件兼容的宿主必须要安装的包的版本,在 npm2.x
会自动安装,npm3.x
之后就只会警告了,需要自行安装^
插入符号,会匹配到当前 major version
的最新版本,比如 "vue": "^3.4.27"
相当于 "vue": "3.x.x"
~
波浪号,会匹配到当前 minor version
的最新版本,也就是 3.4.x
node_modules
node_modules
node_modules
的嵌套结构(依赖的相互依赖关系使用软连接链接)参考资料
本文作者:pepedd864
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!