谈谈包管理工具相关
npm和yarn都采用了铺平方案,有什么问题吗
1、幽灵依赖问题
-
幽灵依赖问题,造成了非法访问
-
幽灵依赖 就是在依赖里没有声明,但在代码里却可以引入 【如果 A 依赖 B, B 依赖 C,那么 A 当中是可以直接使用 C 的】
- 这种非法访问,是有隐患的,万一哪天别的包不依赖了这个包,你却引入了这个包,就会导致报错
2、一个包多版本问题
- 依赖包多个版本的时候,只会提升一个,其余的版本也还是会复制很多次,导致浪费磁盘空间
- 提升一个,就是说这个包会提升到顶层目录中,其余包的版本还是以嵌套的方式复制
- 所以就有了pnpm,pnpm就解决了这个问题
pnpm在软链接和硬链接作用是什么?
总结:
- pnpm在 硬链接的作用可以在不同项目之间共享pnpm的store目录
- pnpm在 软链接的作用 项目的node_modules这个文件夹中创建符号链接,包之间通过软链接的方式来相互引用依赖包,来复用相同版本的包依赖
- 如果项目A依赖于项目B中的某个包,pnpm会创建一个软链接,将该包链接到项目A的
node_modules中,而不是复制整个包。这可以节省磁盘空间
- 如果项目A依赖于项目B中的某个包,pnpm会创建一个软链接,将该包链接到项目A的
项目的所有的依赖都是从全局 store 硬链接到了 node_modules/.pnpm 下,然后之间通过软链接来相互依赖
硬链接:
.pnpm 中存放着所有的包。最终硬链接指向指向全局pnpm 仓库里的store目录下。
也就是说,我们所有的包,最终都以硬链接的形式,最终都在全局 pnpm/store 中,可以使得不同的项目从全局 store 寻找到同一个依赖,大大节省了磁盘空间。
- 硬链接的作用可以在不同项目之间共享store文件
与软链接相比,硬链接的好处是它创建的链接可以被看作是源文件的副本,对应的文件节点数会增加,但它不会占用额外的磁盘空间,因为硬链接和源文件共享磁盘上的同一个数据块,只有在硬链接被删除时,才会释放对应的数据块
软链接:
pnpm 的软链接就是将 node_modules 里的文件软链接到对应的 .pnpm/[package_name]@version/node_modules/[package_name] 中。【pnpm软链接就是将node_mudules的文件软链接到对应的pnpm某个包的某个版本】
- 软链接的设计保证不会出现幽灵依赖的问题
- 通过软链接可以把
.pnpm的包软链接到当前项目node_modules中,而不需要将包的源代码拷贝到当前项目,这种方式可以避免重复包拷贝和占用磁盘空间- 通过软链接来相互依赖
- 软链接的作用是将一个包的源代码链接到多个项目中,避免在每个项目中都拷贝一份源代码
node_modules/.pnpm 可以理解为虚拟 store
npm2 是通过嵌套的方式管理 node_modules 的,会有同样的依赖复制多次的问题。
npm3+ 和 yarn 是通过铺平的扁平化的方式来管理 node_modules,解决了嵌套方式的部分问题,但是引入了幽灵依赖的问题,并且同名的包只会提升一个版本的,其余的版本依然会复制多次。
为什么会出现复制多次?
- 多个包之间难免会有公共的依赖,这样嵌套的话,同样的依赖会复制很多次,会占据比较大的磁盘空间
pnpm 则是用了另一种方式,不再是复制了,而是都从全局 store 硬链接
到 node_modules/.pnpm,然后之间通过软链接来组织依赖关系。
pnpm是如何解决幽灵依赖问题
- pnpm采用了软链接的方式去引用依赖
- pnpm通过软链接在项目的node_modules这个文件夹中创建符号链接,包之间通过软链接的方式来相互引用依赖包,从而解决这个幽灵依赖问题
pnpm为何速度快?
-
下载安装依赖的时候,pnpm会先检查全局的
store目录,会从store目录硬链接到项目中,而不会重新安装依赖 -
一个包的不同版本,pnpm 可以复用之前版本的代码。只会下载新版本的新文件,会复用之前版本的文件
pnpm 为何节省空间?
- 1、它解决了 npm/yarn 平铺 node_modules 带来的依赖项重复的问题 (doppelgangers)
- 2、所有文件都保存在硬盘上的统一的位置。当安装软件包时, 其包含的所有文件都会硬链接自此位置,而不会占用 额外的硬盘空间。这让你可以在项目之间方便地共享相同版本的 依赖包。
- 3、通过软链接可以把
.pnpm的包软链接到当前项目node_modules中,而不需要在每个项目中复制依赖