大家好,我是Webpack,AKA打包老炮,我的slogan是:“打天下的包,让Rollup无包可打”。
今天我要带来的才艺是:webpack内部依赖关系以何种数据结构体现
如果还没看过这篇文章的话,建议先读完再看这里。
这次是要给大家讲解webpack内部是如何体现模块之间的依赖关系。
说到这个你可能会想到,无非就是一个js文件引用另一个js文件,或者引用图片文件。这个引用关系就是模块的依赖关系。
有一说一,这个理解非常对。
那么再思考,如果index.js引用了a.js、b.js、c.js;index.js又被app.js、main.js。那么我们该用怎么设计对象来实现这样的依赖关系呢?
你可能会有很多想法,但我们主要是来webpack是怎么设计的。
webpack的设计也不一定是最优的,因为webpack从2到5之间也是不断优化的过程。
而其中webpack4主要是通过depenency与module来实现这样的依赖关系。
但是在webpack5则进行大改造,增加进了ModuleGraph来实现这个依赖关系,同时还引入了ModuleGraphModule、ModuleGraphConnection这样的对象来细化依赖关系。
但是本质上都离不开几个几种关键信息:如一个module被哪些module引用,一个module又引用了哪些module…带着这样的思路有助于理解webpack的代码。
ModuleGraph是在webpack5真是存在的对象,他体现了各个模块之间的依赖关系。他在webpack内部源码中的出场率非常之高。
最为直接明显的作用就是通过ModuleGraph来构建ChunkGraph。以及在SplitChunkPlugin做分包时也要通过ModuleGraph查询模块依赖关系【这里带出了另一个问题:什么是ChunkGraph?这里可以先简单理解为ChunkGraph是Chunk的关系图,而ModuleGraph是Module的关系图】
以入口文件为index.js为例子,index.js 引用 a.js 、 b.js
先了解下ModuleGraph相关的两个类:
{
module: Module, // 当前module
originModule: Module// 引用当前module的module
}
{
inComingConnections:[], // 存放ModuleGraphConnection,表示一个有哪些modules引用了当前module
outComingConnections:[], // 存放ModuleGraphConnection,表示一个当前module引用了哪些modules
}
再来看看ModuleGraph内部属性:
//真实数据
_dependencyMap:{
<dep-index, connection{originModule: undefined, module: mod-index}>,
}
//真实数据
_moduleMap:{
<mod-index, moduleGraphModule{
inComingConnections:[
connection{originModule: undefined, module: mod-index},
],
outComingConnections:[
connection{originModule: mod-index, module: mod-a},
connection{originModule: mod-index, module: mod-b}
]
}>,
<mod-a, moduleGraphModule{
inComingConnections:[
connection{originModule: mod-index, module: mod-a}
],
outComingConnections:[]
}>,
<mod-b, moduleGraphModule{
inComingConnections:[
connection{originModule: mod-index, module: mod-b}
],
outComingConnections:[]
}>,
}
先说_dependencyMap的数据收集过程:
过程发生在addModule(module)内【如果不清楚addModule发生在什么时候的,请跳转到文章片头推荐的文章先了解】,
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bulh4JdK-1662011794718)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/52060d80e3a24ed7bab00b071221a592~tplv-k3u1fbpfcp-zoom-1.image)]](https://1000bd.com/contentImg/2023/10/29/031459460.png)
并且当module没有originModule时才会添加,所以说_dependencyMap只记录入口信息
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4NpWJYIe-1662011794720)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3c95c7c9c40e4a0090f4ac84b5844ac5~tplv-k3u1fbpfcp-zoom-1.image)]](https://1000bd.com/contentImg/2023/10/29/031459446.png)
然后是_moduleMap的收集过程
同样发生在ModuleGraph.js中的setResolvedModule函数内,逻辑也相对简单这里就不展开说了。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qWz92DXm-1662011794721)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d4ad9b4cf03446b2b94f1e556857eed4~tplv-k3u1fbpfcp-zoom-1.image)]](https://1000bd.com/contentImg/2023/10/29/031459366.png)
再次总结下关于ModuleGraph的数据结构:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OdNTmrSz-1662011794722)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1b4f3373b32f477eb155614307eff701~tplv-k3u1fbpfcp-zoom-1.image)]](https://1000bd.com/contentImg/2023/10/29/031459429.png)
到这里关于webpack内的模块依赖ModuleGraph的知识就讲完了,
接下来思考下一个问题?
什么是ChunkGraph?
如何通过ModuleGraph来绘制ChunkGraph?
下一篇文章将要着重分析webpack的另一个重要知识点:ChunkGraph…