webpack_0">webpack的打包构建流程
为什么需要打包?
-
在前端有非常多的资源,如css、js、vue、vue、 图片、字体等。
-
有些资源需要加工处理
1. ts -> js ts-loader
2. css -> css-loader + style-loader
3. 图片 -> file-loader + url-loader
4. html -> html-webpack-plugin
- 需要对产物进行优化
optimization(webpack优化配置)
splitChunksPlugin(优化配置的重要部分插件)
分包和压缩代码,合并代码,代码分割,缓存,css提取
- 输出产物
打包构建流程
核心模块
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 会在终端中输出构建信息,包括打包时间、生成文件的大小、模块数量、依赖关系图等。
webpackdevserver_212">热更新(HMR,Hot Module Replacement,可选)->属于webpack-dev-server
监听文件变化
在开发模式下,Webpack 可以通过 webpack-dev-server 或 webpack-dev-middleware 监听源文件的变化。当文件内容发生改变时,Webpack 会触发重新构建。
局部更新模块
通过 HMR,Webpack 能够将更新后的模块发送到浏览器,并替换页面上对应的旧模块,而无需刷新整个页面。这样可以加快开发效率和调试体验。
更新状态和重新编译
在 HMR 过程中,Webpack 会保存当前模块的状态,并在重新编译后,将新代码应用到现有的模块实例上,实现无缝更新。