• webpack原理 - 5分钟了解ModuleGraph



    theme: fancy

    开场白

    大家好,我是Webpack,AKA打包老炮,我的slogan是:“打天下的包,让Rollup无包可打”。

    今天我要带来的才艺是:webpack内部依赖关系以何种数据结构体现    
    
    • 1

    如果还没看过这篇文章的话,建议先读完再看这里。

    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是什么?

       ModuleGraph是在webpack5真是存在的对象,他体现了各个模块之间的依赖关系。他在webpack内部源码中的出场率非常之高。

    ModuleGraph的作用?

       最为直接明显的作用就是通过ModuleGraph来构建ChunkGraph。以及在SplitChunkPlugin做分包时也要通过ModuleGraph查询模块依赖关系【这里带出了另一个问题:什么是ChunkGraph?这里可以先简单理解为ChunkGraph是Chunk的关系图,而ModuleGraph是Module的关系图】

    ModuleGraph的数据结构?

    以入口文件为index.js为例子,index.js 引用 a.js 、 b.js

    先了解下ModuleGraph相关的两个类:

    • ModuleGraphConnection:两个module之间的依赖关系。
    {
    	module:  Module, // 当前module
    	originModule: Module// 引用当前module的module
    }
    
    • 1
    • 2
    • 3
    • 4
    • ModuleGraphModule:当前module与它引用的modules、以及引用它的modules的关系
    {
    	inComingConnections:[], // 存放ModuleGraphConnection,表示一个有哪些modules引用了当前module
    	outComingConnections:[], // 存放ModuleGraphConnection,表示一个当前module引用了哪些modules
    }
    
    • 1
    • 2
    • 3
    • 4

    再来看看ModuleGraph内部属性:

    • _dependencyMap:Map():记录入口dependency与module连接关系的信息
    //真实数据 
    _dependencyMap:{
        <dep-index, connection{originModule: undefined, module: mod-index}>,
    }
    
    • 1
    • 2
    • 3
    • 4
    • _moduleMap:Map():记录当前module被谁引用以及引用了谁
    
    //真实数据
    _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:[]
    	}>,
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    ModuleGraph的构建过程?

       先说_dependencyMap的数据收集过程:

    过程发生在addModule(module)内【如果不清楚addModule发生在什么时候的,请跳转到文章片头推荐的文章先了解】,
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bulh4JdK-1662011794718)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/52060d80e3a24ed7bab00b071221a592~tplv-k3u1fbpfcp-zoom-1.image)]

    并且当module没有originModule时才会添加,所以说_dependencyMap只记录入口信息
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4NpWJYIe-1662011794720)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3c95c7c9c40e4a0090f4ac84b5844ac5~tplv-k3u1fbpfcp-zoom-1.image)]

       然后是_moduleMap的收集过程

    同样发生在ModuleGraph.js中的setResolvedModule函数内,逻辑也相对简单这里就不展开说了。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qWz92DXm-1662011794721)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d4ad9b4cf03446b2b94f1e556857eed4~tplv-k3u1fbpfcp-zoom-1.image)]

       再次总结下关于ModuleGraph的数据结构:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OdNTmrSz-1662011794722)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1b4f3373b32f477eb155614307eff701~tplv-k3u1fbpfcp-zoom-1.image)]

    到这里关于webpack内的模块依赖ModuleGraph的知识就讲完了,

    接下来思考下一个问题?
    
    什么是ChunkGraph?
    如何通过ModuleGraph来绘制ChunkGraph?
    
    • 1
    • 2
    • 3
    • 4

    下一篇文章将要着重分析webpack的另一个重要知识点:ChunkGraph…

  • 相关阅读:
    深度学习 anaconda 安装问题
    初识测开/测试
    民安智库(第三方满意度调研公司)医院满意度调查:用数据说话,让服务更贴心
    普冉PY32系列(九) GPIO模拟和硬件SPI方式驱动无线收发芯片XL2400
    湖仓一体技术解读|多模数据的融合管理
    uniapp集成个推
    双节前把我的网站重构了一遍
    leetcode/狒狒吃香蕉
    Android studio 调整jar包顺序
    11.8知识总结(web应用程序、手写web框架、Django框架等)
  • 原文地址:https://blog.csdn.net/bigname22/article/details/126613963