webpack原理 - ModuleGraph原理

583 阅读3分钟

开场白

大家好,我是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发生在什么时候的,请跳转到文章片头推荐的文章先了解】, 在这里插入图片描述

并且当module没有originModule时才会添加,所以说_dependencyMap只记录入口信息 在这里插入图片描述    然后是_moduleMap的收集过程

同样发生在ModuleGraph.js中的setResolvedModule函数内,逻辑也相对简单这里就不展开说了。 在这里插入图片描述

   再次总结下关于ModuleGraph的数据结构: 在这里插入图片描述

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

接下来思考下一个问题?

什么是ChunkGraph?
如何通过ModuleGraph来绘制ChunkGraph

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