Webpack打包构建流程

发布于:2025-03-04 ⋅ 阅读:(21) ⋅ 点赞:(0)

webpack的打包构建流程

为什么需要打包?

  1. 在前端有非常多的资源,如css、js、vue、vue、 图片、字体等。

  2. 有些资源需要加工处理

1. ts -> js ts-loader

2. css -> css-loader + style-loader

3. 图片 -> file-loader + url-loader

4. html -> html-webpack-plugin

  1. 需要对产物进行优化

optimization(webpack优化配置)

splitChunksPlugin(优化配置的重要部分插件)

分包和压缩代码,合并代码,代码分割,缓存,css提取

  1. 输出产物

打包构建流程

核心模块

webpack-cli 和 webpack-dev-server webpack

初始化

1.读取配置文件 webpack.config.js

- entry

- 单入口

- 多入口

- 动态入口

- 依赖解析,生成依赖图,deepGraph

- 模块处理

识别对应的目标文件,然后匹配对应的loader,进行解析

2.初始化 compiler 对象  compiler -> 编译器(中文语义)

运行 Webpack 时,它会根据你的配置文件(通常是 webpack.config.js)创建一个 compiler 对象。这个对象包含了 Webpack 进行编译所需的所有信息和方法,例如配置信息、文件系统的访问、插件的应用等。它是webpack工作的核心。

Webpack 配置中的插件会被逐一执行并挂载到 Compiler 对象的钩子上。插件可以在 Webpack 的生命周期中的不同阶段执行自定义逻辑,比如在打包前清理目录、在打包后生成 HTML 文件等。

3.插件挂载

Webpack 配置中的插件会被逐一执行并挂载到 Compiler 对象的钩子上。插件可以在 Webpack 的生命周期中的不同阶段执行自定义逻辑,比如在打包前清理目录、在打包后生成 HTML 文件等。

解析入口文件

- 确定入口​

Webpack 根据配置中的 entry 属性确定构建的入口文件,可以是单一文件,也可以是多入口配置。​

entry 可以是字符串、数组或对象,不同的形式会影响后续生成的 Chunk 数量。​

- 递归解析依赖​

从入口文件开始,Webpack 使用内部的 Webpack Resolver 递归解析模块的依赖关系。​

Webpack 会根据文件的类型和文件后缀名,选择不同的处理方式。它使用 fs 模块来读取文件内容,并通过 AST(抽象语法树)解析出文件中 import、require、import() 等依赖声明,确定依赖模块的路径。​

对于解析到的每个依赖模块,Webpack 会继续递归处理,直至所有依赖模块都被解析为止。​

模块编译

识别文件类型​

Webpack 默认只识别 JavaScript 和 JSON 文件,对于其他类型的文件,如 TypeScript、SCSS、图片等,必须通过相应的 Loader 进行预处理。​

在解析到一个模块时,Webpack 根据配置中的 module.rules 来匹配合适的 Loader,从而决定该模块如何被处理。​

使用 Loader 处理模块​

每个匹配到的 Loader 会按照配置顺序对模块内容进行转换。例如,babel-loader 会将 ES6+ 代码转换为 ES5,css-loader 解析 CSS 文件,file-loader 处理文件资源等。​

Loader 的执行是有顺序的,通常是“从右到左”或“从下到上”的顺序执行(如果在配置中使用了数组表示多个 Loader)。​

转换为 Webpack 能识别的模块​

Loader 转换后的文件内容被 Webpack 视为标准的 JavaScript 模块,进一步通过内部模块机制(如 CommonJS、ESM)进行处理。

分包生成chunk

确定chunk

Webpack 会根据入口文件及其所有依赖文件生成一个或多个 Chunk。​

每个 Chunk 是一组相关联模块的集合。默认情况下,每个入口文件会生成一个对应的 Chunk。​

代码分割(Code Splitting)​

在生成 Chunk 的过程中,Webpack 可以根据配置(如 SplitChunksPlugin)将某些公共模块抽取到一个单独的 Chunk 中,以便在多个入口间共享,从而优化加载性能。

优化阶段

模块去重和合并​

Webpack 会分析模块之间的依赖关系,消除模块中的冗余代码,将重复引用的模块进行合并。​

压缩代码​

在生产环境模式下,Webpack 会使用内置的 TerserPlugin 来压缩 JavaScript 代码,去除注释、空白、未引用的代码等。​

对于 CSS 文件,也可以使用 css-minimizer-webpack-plugin 进行压缩。​

Tree Shaking​(树摇)

Webpack 会自动移除未使用的模块和代码,通过静态分析 import 和 export,保留实际使用的部分。这在使用 ES6 模块时非常有效。​

生成输出文件

输出文件配置​

Webpack 根据配置中的 output 选项决定生成文件的名称和路径。常用的占位符包括 [name](入口名称)、[hash](模块内容的 hash 值)、[chunkhash](Chunk 的 hash 值)等。​

如果有多个 Chunk 或者使用了代码分割,Webpack 会生成多个文件。​

写入文件系统​

Webpack 最终将所有的 Chunk 转换为文件,并将它们写入到文件系统中的指定目录中(通常是 dist 目录)。​

输出的文件包括 JavaScript、CSS、HTML(如果使用了相应插件)以及其他资源文件。​

结束构建

触发完成钩子​

Webpack 在完成打包后,会触发 done 钩子,允许插件或自定义代码在构建完成后执行操作。​

例如,HtmlWebpackPlugin 会在构建完成后生成对应的 HTML 文件,CleanWebpackPlugin 会在构建开始前清理输出目录。​

打印打包结果​

Webpack 会在终端中输出构建信息,包括打包时间、生成文件的大小、模块数量、依赖关系图等。

热更新(HMR,Hot Module Replacement,可选)->属于webpack-dev-server

监听文件变化​

在开发模式下,Webpack 可以通过 webpack-dev-server 或 webpack-dev-middleware 监听源文件的变化。当文件内容发生改变时,Webpack 会触发重新构建。​

局部更新模块​

通过 HMR,Webpack 能够将更新后的模块发送到浏览器,并替换页面上对应的旧模块,而无需刷新整个页面。这样可以加快开发效率和调试体验。​

更新状态和重新编译​

在 HMR 过程中,Webpack 会保存当前模块的状态,并在重新编译后,将新代码应用到现有的模块实例上,实现无缝更新。