本文介绍 各种包管理工具的简单原理(作者才疏学浅),各种优势和劣势
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.xnode_modulesnode_modulesnode_modules 的嵌套结构(依赖的相互依赖关系使用软连接链接)参考资料


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