「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」
很久以前:嵌套结构
在 npmv2 时,node_modules 对于各个 package 的拓扑为嵌套结构。
假设:
- 项目依赖
package-a与package-b两个 package package-a与package-b均依赖lodash@4.17.4
依赖关系以 Markdown 列表表示:
+ package-a
+ `lodash@4.17.4`
+ package-b
+ `lodash@4.17.4`
此时 node_modules 目录结构如下:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
A ---> C("lodash@4.17.4")
B ---> D("lodash@4.17.4")
此时最大的问题
- 嵌套过深
- 占用空间过大
现在阶段: 平铺结构
在 npmv3 之后 node_modules 为平铺结构,拓扑结构如下:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
app ---> C("lodash@4.17.4")
一个问题: 以下依赖最终 node_modules 结果如何?
可参考该示例
依赖关系以 Markdown 列表表示
+ package-a
+ `lodash@^4.17.4`
+ package-b
+ `lodash@^4.16.1`
答: 与上拓扑结构一致,因为二者为 ^ 版本号,他们均会下载匹配该版本号范围的最新版本,比如 @4.17.4,因此二者依赖一致。
此时如果有 lock,会有一点小问题,待稍后讨论
node_modules 目录结构如下图:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
app ---> C("lodash@4.17.4")
再一个问题: 以下依赖最终 node_modules 结果如何?
可参考该示例
+ package-a
+ `lodash@4.17.4`
+ package-b
+ `lodash@4.16.1`
答:package-b 先从自身 node_modules 下寻找 lodash,找到 lodash@4.16.1
node_modules 目录结构如下图:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
app ---> C("lodash@4.17.4")
B ---> D("lodash@4.16.1")
再一个问题: 以下依赖最终 node_modules 结果如何
+ package-a
+ `lodash@4.0.0`
+ package-b
+ `lodash@4.0.0`
+ package-c
+ `lodash@3.0.0`
+ package-d
+ `lodash@3.0.0`
答:package-d 只能从自身的 node_modules 下寻找 lodash@3.0.0,而无法从 package-c 下寻找,此时 lodash@3.0.0 不可避免地会被安装两次
node_modules 目录结构如下图:
graph
app(node_modules) ---> A(package-a)
app ---> B(package-b)
app ---> C(package-c)
app ---> D(package-d)
app ---> X("lodash@4.0.0")
C ---> Y("lodash@3.0.0")
D ---> Z("lodash@3.0.0")
现在阶段问题: 重复的版本依赖有什么问题?
- Install Size,安装体积变大,浪费磁盘空间
- Build Size,构建打包体积变大,浪费带宽,网站打开延迟,破坏用户体验 (PS: 支持 Tree Shaking 会好点)
- 破坏单例模式,破坏缓存,如 postcss 的许多插件将 postcss 扔进 dependencies,重复的版本将导致解析 AST 多次