深入理解:Webpack编译原理

WebPack是什么?

Webpack是基于模块化的打包(构建)工具,它把一切视为模块

它通过一个开发时态的入口模块为起点,分析出所有的依赖关系,然后经过一系列的过程(压缩,合并),最终生成运行时状态的文件。

Webpack的特点:

  • 为前端工程化而生:webpack致力于解决前端工程化,特别是浏览器端工程化中遇到的问题,让开发者集中注意力编写业务代码,而把工程化过程中的问题全部交给webpack来处理

  • 简单易用:支持零配置,可以不用写任何一行额外的代码就使用webpack

  • 强大的生态:webpack是非常灵活、可以扩展的,webpack本身的功能并不多,但它提供了一些可以扩展其功能的机制,使得一些第三方库可以融于到webpack中

  • 基于nodejs:由于webpack在构建的过程(基于node)中需要读取文件,因此它是运行在node环境中的

  • 基于模块化:webpack在构建过程中要分析依赖关系,方式是通过模块化导入语句进行分析的,它支持各种模块化标准,包括但不限于CommonJS、ES6 Module

Webpack编译原理

Webpack的作用是源代码编译(构建,打包)成最终代码

👆上面的图片可见,我们开发时态和运行时态中间的部分是Webpack构建工具,那webpack 的编译过程是什么样的呢???

Webpack的编译构建过程,大致分为三个步骤:

三个过程分别,在做什么?

一 、 初始化

此阶段,webpack会将CLI参数、配置文件、默认配置进行融合,形成一个最终的配置对象。

对配置的处理过程是依托一个第三方库yargs完成的

此阶段相对比较简单,主要是为接下来的编译阶段做必要的准备

目前,可以简单的理解为,初始化阶段主要用于产生一个最终的配置

二、 编译

第一步:创建chunk

根据入口模块(默认为./src/index.js)创建一个chunk

chunk是webpack在内部构建过程中的一个概念,译为,它表示通过某个入口找到的所有依赖的统称。

每个chunk都有至少两个属性:

  • name:默认为main
  • id:唯一编号,开发环境和name相同,生产环境是一个数字,从0开始

第二步:构建所有依赖模块

此图中,构建所有依赖模块的时,根据入口文件,构建出所有模块

那么他是如何去构建这些模块的呢? 看图就立刻明白他的原理!!

它构建依赖模块的完整流程,可以拆解为以下几个清晰步骤,按顺序逐步推进:

1. 从 "入口文件" 开始,先查 "模块记录"

Webpack 会以开发者指定的 "入口模块"(比如 src/index.js)为起点,第一步先检查内部的 "模块记录"------ 这个记录就像一张 "已处理模块清单"。

如果入口文件已经在清单里,说明之前已经处理过,直接返回结果,不用重复执行后续步骤;如果不在清单里,就进入下一个环节。

2. 读文件、分析语法,找出 "依赖关系"

接下来 Webpack 会读取入口文件的内容,然后通过语法分析工具把代码转换成 "AST 抽象语法树"(可以理解为把代码拆成计算机能看懂的 "结构化图纸")。

通过分析这张 "图纸",Webpack 能精准找出当前模块依赖的其他模块(比如代码里的 importrequire 语句),并把这些依赖信息统一保存到 dependencies(依赖列表)里。

3. 改代码、存模块,标记 "已处理"

为了让后续步骤能正确识别依赖,Webpack 会对当前模块的代码做一点 "改造"------ 比如替换掉 import 这类开发时的模块化语法,换成它能识别的内部函数。

改造后的代码会被保存起来,同时把当前模块加入 "模块记录" 和 "chunk 模块"(chunk 是 Webpack 临时用来整合模块的容器),标记为 "已处理",避免重复处理。

4. 递归加载依赖,直到 "无遗漏"

最后,Webpack 会拿着 dependencies 里的依赖列表,逐个对这些依赖模块重复上面的 1-3 步:查记录→读文件→析依赖→改代码→存模块。

这个 "递归加载" 的过程会一直持续,直到所有依赖的模块(包括依赖的依赖)都被处理完,最终形成一个完整的依赖树。

第三步:产生chunk assets

在第二步完成后,chunk中会产生一个模块列表,列表中包含了模块id和模块转换后的代码

接下来,webpack会根据配置为chunk生成一个资源列表,即chunk assets,资源列表可以理解为是生成到最终文件的文件名和文件内容

chunk hash是根据所有chunk assets的内容生成的一个hash字符串

hash:一种算法,具体有很多分类,特点是将一个任意长度的字符串转换为一个固定长度的字符串,而且可以保证原始内容不变,产生的hash字符串就不变

第四步:合并chunk assets

将多个chunk的assets合并到一起,并产生一个总的hash

我们平常使用的前端框架,基本情况下,入口文件是一个的所以,很容易误解为,入口文件只能一个的想法

但是入口文件可以有多个的,所以chunk也会存在多个的时候;

三、 输出

此步骤非常简单,webpack将利用node中的fs模块(文件处理模块),根据编译产生的总的assets,生成相应的文件。

总过程

涉及术语

  1. module:模块,分割的代码单元,webpack中的模块可以是任何内容的文件,不仅限于JS
  2. chunk:webpack内部构建模块的块,一个chunk中包含多个模块,这些模块是从入口模块通过依赖分析得来的
  3. bundle:chunk构建好模块后会生成chunk的资源清单,清单中的每一项就是一个bundle,可以认为bundle就是最终生成的文件
  4. hash:最终的资源清单所有内容联合生成的hash值
  5. chunkhash:chunk生成的资源清单内容联合生成的hash值
  6. chunkname:chunk的名称,如果没有配置则使用main
  7. id:通常指chunk的唯一编号,如果在开发环境下构建,和chunkname相同;如果是生产环境下构建,则使用一个从0开始的数字进行编号

上期知识点

上期知识点:你知道Webpack解决的问题是什么嘛?

相关推荐
雲墨款哥4 小时前
一个前端开发者的救赎之路-JS基础回顾(五)-数组
前端·javascript·面试
朱程4 小时前
深入JS(一):手写 Promise
前端·javascript
Hierifer4 小时前
跨端技术:浅聊双线程原理和实现
前端
FreeBuf_4 小时前
加密货币武器化:恶意npm包利用以太坊智能合约实现隐蔽通信
前端·npm·智能合约
java水泥工5 小时前
基于Echarts+HTML5可视化数据大屏展示-图书馆大屏看板
前端·echarts·html5
半夏陌离5 小时前
SQL 实战指南:电商订单数据分析(订单 / 用户 / 商品表关联 + 统计需求)
java·大数据·前端
子兮曰5 小时前
🚀Vue3异步组件:90%开发者不知道的性能陷阱与2025最佳实践
前端·vue.js·vite
牛十二5 小时前
mac-intel操作系统go-stock项目(股票分析工具)安装与配置指南
开发语言·前端·javascript
whysqwhw5 小时前
Kuikly 扩展原生 API 的完整流程
前端