当前位置: 首页 > news >正文

webpack原理 - 5分钟了解ModuleGraph


theme: fancy

开场白

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

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

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

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
}
  • ModuleGraphModule:当前module与它引用的modules、以及引用它的modules的关系
{
	inComingConnections:[], // 存放ModuleGraphConnection,表示一个有哪些modules引用了当前module
	outComingConnections:[], // 存放ModuleGraphConnection,表示一个当前module引用了哪些modules
}

再来看看ModuleGraph内部属性:

  • _dependencyMap:Map(<Dependency, ModuleGraphConnection>):记录入口dependency与module连接关系的信息
//真实数据 
_dependencyMap:{
    <dep-index, connection{originModule: undefined, module: mod-index}>,
}
  • _moduleMap:Map(<Module, ModuleGraphModule>):记录当前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:[]
	}>,
}

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?

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

相关文章:

  • 几分钟来了解下什么是嵌入式开发?
  • 基于SpringBoot的自习室预约管理系统
  • 计算机毕业设计php_thinphp_vue的校园论坛网站(源码+系统+mysql数据库+Lw文档)
  • 分享大学生如何制作自己的网课答案查题搜题公众号
  • 每天技术扩展记录
  • springBoot 源码一:自动配置底层源码分析
  • Java基于SSM的功能学习系统
  • u-view的使用
  • Linux Shell 基础语法 流程控制 逻辑运算 字符串操作详细解析
  • 论文速览【RL - Exploration】—— 【Go-Explore】First return, then explore
  • C# 泛型详解(泛型类,方法,接口,委托,约束,反射 )
  • 【云原生】基于Kubernetes的阿里云ACK网络管理
  • Ant Design Vue3中DatePicker 日期选择框如何将接收的数据显示在日期选择框中
  • java计算机毕业设计体育城场地预定系统前台源码+系统+数据库+lw文档+mybatis+运行部署
  • 猿创征文|『单片机原理』程序存储器的结构
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【React系列】如何构建React应用程序
  • 【RocksDB】TransactionDB源码分析
  • DataBase in Android
  • Java|序列化异常StreamCorruptedException的解决方法
  • java小心机(3)| 浅析finalize()
  • Octave 入门
  • Vue2.x学习三:事件处理生命周期钩子
  • web标准化(下)
  • windows下mongoDB的环境配置
  • 创建一种深思熟虑的文化
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 分享几个不错的工具
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 强力优化Rancher k8s中国区的使用体验
  • 区块链分支循环
  • 山寨一个 Promise
  • 双管齐下,VMware的容器新战略
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 硬币翻转问题,区间操作
  • 在Unity中实现一个简单的消息管理器
  • 正则表达式小结
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • #HarmonyOS:软件安装window和mac预览Hello World
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (16)Reactor的测试——响应式Spring的道法术器
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (二)Eureka服务搭建,服务注册,服务发现
  • (算法二)滑动窗口
  • (译) 理解 Elixir 中的宏 Macro, 第四部分:深入化
  • (转)【Hibernate总结系列】使用举例
  • (转)http-server应用
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .libPaths()设置包加载目录
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端