您现在的位置是:亿华云 > 域名
有点难的知识点: Webpack Chunk 分包规则详解
亿华云2025-10-09 12:50:11【域名】5人已围观
简介背景在前面系列文章提到,webpack 实现中,原始的资源模块以 Module 对象形式存在、流转、解析处理。而 Chunk 则是输出产物的基本组织单位,在生成阶段 webpack 按规则将 entr
背景
在前面系列文章提到,有点webpack 实现中,知识则详原始的包规资源模块以 Module 对象形式存在、流转、有点解析处理。知识则详
而 Chunk 则是包规输出产物的基本组织单位,在生成阶段 webpack 按规则将 entry 及其它 Module 插入 Chunk 中,有点之后再由 SplitChunksPlugin 插件根据优化规则与 ChunkGraph 对 Chunk 做一系列的知识则详变化、拆解、包规合并操作,有点重新组织成一批性能(可能)更高的知识则详 Chunks 。运行完毕之后 webpack 继续将 chunk 一一写入物理文件中,包规完成编译工作。有点
综上,知识则详Module 主要作用在 webpack 编译过程的包规前半段,解决原始资源“「如何读」”的问题;而 Chunk 对象则主要作用在编译的后半段,解决编译产物“「如何写」”的问题,两者合作搭建起 webpack 搭建主流程。
Chunk 的编排规则非常复杂,涉及 entry、optimization 等诸多配置项,我打算分成两篇文章分别讲解基本分包规则、SplitChunksPlugin 分包优化规则,本文将集中在第一部分,云南idc服务商讲解 entry、异步模块、runtime 三条规则的细节与原理。
默认分包规则
Webpack 4 之后编译过程大致上可以拆解为四个阶段(参考:[万字总结] 一文吃透 Webpack 核心原理):
在构建(make) 阶段,webpack 从 entry 出发根据模块间的引用关系(require/import) 逐步构建出模块依赖关系图(ModuleDependencyGraph),依赖关系图表达了模块与模块之间互相引用的先后次序,基于这种次序 webpack 就可以推断出模块运行之前需要先执行那些依赖模块,也就可以进一步推断出那些模块应该打包在一起,那些模块可以延后加载(异步执行),关于模块依赖图的更多信息,可以参考我另一篇文章 《有点难的 webpack 知识点:Dependency Graph 深度解析》。
到了生成(seal) 阶段,webpack 会根据模块依赖图的内容组织分包 —— Chunk 对象,默认的分包规则有:
同一个 entry 下触达到的模块组织成一个 chunk 异步模块单独组织为一个 chunk entry.runtime 单独组织成一个 chunk默认规则集中在 compilation.seal 函数实现,seal 核心逻辑运行结束后会生成一系列的 Chunk、ChunkGroup、ChunkGraph 对象,后续如 SplitChunksPlugin 插件会在 Chunk 系列对象上做进一步的拆解、优化,最终反映到输出上才会表现出复杂的分包结果。
我们聊聊默认生成规则。
Entry 分包处理
重点:seal 阶段遍历 entry 对象,服务器托管为每一个 entry 单独生成 chunk,之后再根据模块依赖图将 entry 触达到的所有模块打包进 chunk 中。
在生成阶段,Webpack 首先根据遍历用户提供的 entry 属性值,为每一个 entry 创建 Chunk 对象,比如对于如下配置:
module.exports = { entry: { main: "./src/main", home: "./src/home", } };Webpack 遍历 entry 对象属性并创建出 chunk[main] 、chunk[home] 两个对象,此时两个 chunk 分别包含 main 、home 模块:
初始化完毕后,Webpack 会读取 ModuleDependencyGraph 的内容,将 entry 所对应的内容塞入对应的 chunk (发生在 webpack/lib/buildChunkGrap.js 文件)。比如对于如下文件依赖:
main.js 以同步方式直接或间接引用了 a/b/c/d 四个文件,分析 ModuleDependencyGraph 过程会逐步将 a/b/c/d 模块逐步添加到 chunk[main] 中,最终形成:
PS: 基于动态加载生成的 chunk 在 webpack 官方文档中,通常称之为 「Initial chunk」 。
异步模块分包处理
重点:分析 ModuleDependencyGraph 时,每次遇到异步模块都会为之创建单独的 Chunk 对象,单独打包异步模块。
Webpack 4 之后,只需要用异步语句 require.ensure("./xx.js") 或 import("./xx.js") 方式引入模块,就可以实现模块的动态加载,这种能力本质也是基于 Chunk 实现的。
Webpack 生成阶段中,b2b供应网遇到异步引入语句时会为该模块单独生成一个 chunk 对象,并将其子模块都加入这个 chunk 中。例如对于下面的例子:
// index.js, entry 文件 import sync-a import sync-b import(async-c)在 index.js 中,以同步方式引入 sync-a、sync-b;以异步方式引入 async-a 模块;同时,在 async-a 中以同步方式引入 sync-c 模块。对应的模块依赖如:
此时,webpack 会为入口 index.js、异步模块 async-a.js 分别创建分包,形成如下数据:
这里需要引入一个新的概念 —— Chunk 间的父子关系。由 entry 生成的 Chunk 之间相互孤立,没有必然的前后依赖关系,但异步生成的 Chunk 则不同,引用者(上例 index.js 块)需要在特定场景下使用被引用者(上例 async-a 块),两者间存在单向依赖关系,在 webpack 中称引用者为 parent、被引用者为 child,分别存放在 ChunkGroup._parents 、ChunkGroup._children 属性中。
上述分包方案默认情况下会生成两个文件:
入口 index 对应的 index.js 异步模块 async-a 对应的 src_async-a_js.js运行时,webpack 在 index.js 中使用 promise 及 __webpack_require__.e 方法异步载入并运行文件 src_async-a_js.js ,从而实现动态加载。
PS: 基于异步模块的 chunk 在 webpack 官方文档中,通常称之为 「Async chunk」。
Runtime 分包
重点:Webpack 5 之后还能根据 entry.runtime 配置单独打包运行时代码。
除了 entry、异步模块外,webpack 5之后还支持基于 runtime 的分包规则。除业务代码外,Webpack 编译产物中还需要包含一些用于支持 webpack 模块化、异步加载等特性的支撑性代码,这类代码在 webpack 中被统称为 runtime。举个例子,产物中通常会包含如下代码:
/很赞哦!(3286)
相关文章
- 为了避免将来给我们的个人站长带来的麻烦,在选择域名后缀时,我们的站长最好省略不稳定的后缀域名,比如n,因为我们不知道策略什么时候会改变,更不用说我们将来是否还能控制这个域名了。因此,如果站长不是企业,或者有选择的话,如果不能选择域名的cn类,最好不要选择它。
- Linux基础命令:作为开发人员,你还不知道嘛?
- 看了这么多代码,谈一谈代码风格!
- 代码不止|Google 助你打造优质移动端用户体验
- 当投资者经过第二阶段的认真学习之后又充满了信心,认为自己可以在市场上叱咤风云地大干一场了。但没想到“看花容易绣花难”,由于对理论知识不会灵活运用.从而失去灵活应变的本能,就经常会出现小赢大亏的局面,结果往往仍以失败告终。这使投资者很是困惑和痛苦,不知该如何办,甚至开始怀疑这个市场是不是不适合自己。在这种情况下,有的人选择了放弃,但有的意志坚定者则决定做最后的尝试。
- SpringCloud中Zuul网关原理及其配置,看它就够了!
- 不可不知的三种缓冲类型
- 华为凤凰引擎:从GT走向RT
- 2、根据用户基础选择访问提供程序。由于互联问题的存在,接入商的选择也非常重要,如果用户群主要在联通,尽量选择联通接入较好的接入商,如果用户群主要在电信,那么选择电信接入较好的接入商。如果用户组位于国家/地区,则选择更好的访问提供程序进行交互。
- Google 面馆营业啦!揭秘拉面背后的机器学习技术