【依赖】重复依赖、幽灵依赖

256 阅读2分钟

重复依赖

npm V2 VS V3

npm v3(4、5、6...) 开始,依赖扁平化(解决了重复依赖?),npm v2是一种嵌套的方式

image.png

假设AV1.0依赖BV1.0

image.png

假设 CV1.0依赖于 BV2.0

image.png

不是说会拍平吗,那么右侧的npm3的BV2.0似乎是嵌套了,这是因为BV1.0是顶层依赖,所以不能继续将BV2.0作为顶层依赖,所以和npm V2的处理方式一样,将BV2.0嵌套在CV1.0下面

重复依赖

假设 DV1.0依赖于 BV2.0

image.png

同样的原因,BV2不能不做为顶层依赖,所以必须嵌套在DV1下面。从图上可以看出,二层树中出现了重复的依赖,

假设 EV1.0依赖于 BV1.0

image.png

因为在顶层依赖中,已经有了BV1 ,所以BV1不需要嵌套在EV1的层级下面

npm.github.io/how-npm-wor…

假设AV2依赖于BV2

image.png

假设EV2依赖于BV2

  • EV1会被删除,BV1也会被删除
  • 安装EV2
  • 安装BV2在顶层级中(因为V1已经被移除)

image.png

看起来不是很清晰,使用

npm dedupe
复制代码

image.png

结论

npm v2依赖层级过深,容易有重复依赖, npm V3采取拍平的方式,解决了重复依赖,但是如果有同一个npm有多个版本的话,依赖依然还是V2的方式,会有嵌套,可以使用npm dedupe解决

幽灵依赖

没有在 package.json 中声明的依赖,以及也没有以及也没有通过 aliasexternals 进行配置时,就叫幽灵依赖

{  
"name": "my-library",  
"version": "1.0.0",  
"main": "lib/index.js",  
"dependencies": {  
  "minimatch": "^3.0.4"  
},  
"devDependencies": {  
  "rimraf": "^2.6.2"  
 }  
}
复制代码

幽灵依赖就是 brace-expansionglob

var minimatch = require('minimatch');  
var expand = require('brace-expansion'); // ???  
var glob = require('glob'); // ???
复制代码

造成的问题

1、 由于没有明确声明版本,依赖更新会不确定

2、 缺失的版本(???)

解决办法

1、 在构建阶段 catch 幽灵依赖(???),答案参考umi源码,实现思路就是,在构建解决

  • 遍历 imports 语句,排除相对路径、alias、external
  • 判断package name是否在存在

2、 使用pnpm 包管理器, 默认已经解决这个问题

3、 如果使用了umi框架,则可以通过配置参数来解决

// .umirc.ts
export default {
  phantomDependency: {},
};
复制代码

umi源码

Tips

使用 npm ls --depth=1 查看依赖树(一层)

使用 npm dedupe 拍平你的🌲

参考

phantom_deps

duplication

npm-dedupe