关于幽灵依赖问题
1. 什么是幽灵依赖?
在你的项目中,也许你没有安装某个包(在package.json中不存在),但是你在项目中却能够引入并正常运行。这种情况就被称为是幽灵依赖。
2. 幽灵依赖是如何引起的?
在回答这个问题之前,可以先看一看下图,Rush官网所给出的一张图片,可以很直观的展示了两种不同的node_modules结构。
Phatom结构导致了“幽灵依赖”的产生。例如使用 yarn/npm 对项目安装一个foo包,这个foo包同时依赖着bar包。那么这时,npm/yarn 的默认策略,会将依赖打散、铺平到node_modules中,形成了Phatom结构,因为foo包与bar包在同一层级,那么你能够import foo,自然也就能import bar了。但在package.json中,bar包不存在,这样就形成了幽灵依赖。如果某天foo包不再依赖bar包,而你在项目中引入了bar包,就会导致报错。
3. 如何解决幽灵依赖?
Doppelgangers的结构给我们提供了这样的一种不铺平依赖的策略,来解决幽灵依赖问题。但有一个很明显的问题,Doppelgangers的结构会导致安装的依赖数量过多。在Doppelgangers的结构下,假设foo包与bar包都依赖同版本的xxx包,那么在这种结构下,xxx包就会被安装两遍,我们不希望这种事情发生。
pnpm采取了建立本地仓库的方式。所有通过 pnpm install 安装的包都会被存放在本地仓库中。而node_modules里则是通过一种硬链接(hard link)的方式使得node_modules能够获取到本地仓库里的包的资源。因此也就不会发生多次安装相同的包了。并且它同样采取的是Doppelgangers的结构,解决了幽灵依赖问题。