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 能精准找出当前模块依赖的其他模块(比如代码里的 import
或 require
语句),并把这些依赖信息统一保存到 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,生成相应的文件。

总过程

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