发布于 2026-01-06 3 阅读
0

How Webpack uses dependency graph to build modules

Webpack 如何使用依赖图构建模块

在前两篇文章中,我讨论了 Webpack 及其核心概念。这两篇文章主要介绍了Webpack 的架构以及如何通过构建自定义插件来扩展 Webpack 的功能。在本文中,我将详细讨论 Webpack 用于模块打包的依赖关系图。

我在之前的文章中用“依赖关系图”来描述 Webpack 打包过程。Webpack 使用依赖关系图来解析模块之间的依赖关系,并优先构建其他模块所需的模块。让我们沿用我在第一篇文章中举的例子,以便更准确地理解这一点。

替代文字

在上面的示例中,文件bootstrap.main.ts用作构建依赖关系图的入口点。上述示例中的其他文件都是主文件中必需的。

那么,让我们看看这个依赖关系图是如何解析和渲染的,以便所有文件都能按正确的顺序加载。

关于依赖关系图的更多信息

这里我们讨论的是有向无环图,其中的边以单向方式连接。由于有向无环图的无特性,从图中的一个点出发遍历整个图非常困难。

但是依赖关系图是如何排序的呢?
答案:拓扑排序

所以,你接下来的问题肯定是拓扑排序是什么😅

什么是拓扑排序?它是如何工作的?

让我们考虑一个有向无环图的例子来理解这个算法。

在拓扑排序中,我们使用两个数据结构:一个集合和一个,来维护顺序并跟踪顶点。

集合将跟踪所有已访问的顶点,而将按拓扑排序顺序存储所有顶点。

替代文字

我将参考上面提到的图。我们从节点E开始。一开始,我们的已访问集合为空,所以我们直接将E放入已访问集合中。之后,我们将探索E的子节点FH。由于H不在已访问集合中,并且没有子节点,这意味着它已被完全探索,所以我们将H从集合中移到栈中。

替代文字

接下来,我们移动到E的下一个子节点F,并检查它是否在集合中。由于 F 不在集合中,所以我们将其添加到集合中,并查找它的子节点。F有一个子节点G,所以我们检查 G 是否在集合中,并将其添加到集合中。同样,G没有子节点,所以我们将其添加到栈中

替代文字

G移入栈后,我们返回到它的父元素F。F的所有子元素都已遍历完毕,所以我们将 F 放入,然后移动到它的父元素E。由于所有子元素都已移入栈中,所以我们将E 也添加到栈中。

替代文字

现在我们选择另一个未访问过的节点,比如B,它有两个子节点CD。我们首先检查C是否在集合中,如果不在,则将其添加到集合中。将C添加到集合后,我们再次检查C的子节点。E是C唯一子节点,由于它已经在集合中,所以我们将C移到栈中。

替代文字

接下来,我们移动到B的下一个子节点D。首先检查集合,由于集合中不存在D,我们将D添加到集合中。D有一个子节点F,由于 F 已存在于集合中,我们将D添加到栈中。

替代文字

至此,B的所有子节点都已完全探索完毕,因此我们将B添加到堆栈中。

替代文字

完成此循环后,我们将移动到下一个未访问的节点A。由于A只有一个子节点,且该子节点已存在于集合中,因此我们将A添加到栈中。集合和栈的最终顺序大致如下所示。

替代文字

节点的渲染顺序为A、B、D、C、E、F、G、H

注意:拓扑排序的顺序可能不同,这取决于你如何选择未访问节点。

将图中的所有节点视为相互依赖的模块。有向顶点表示模块之间的依赖关系。Webpack使用拓扑排序来解决依赖关系,并按照算法提供的顺序渲染模块

希望这能让您对webpack的依赖关系图的执行和使用有一个基本的了解。

祝您阅读愉快!📖

文章来源:https://dev.to/jasmin/how-dependancy-graph-in-webpack-resolve-module-dependency-5ej4