Webpack 学习笔记
适合目标:从零到深入掌握 Webpack,理解其依赖图、Loader、Plugin、分包、缓存、性能优化与面试答法。
学习定位:这一份偏“原理核心 + 面试核心 + 老项目必备”。
学习原则:Webpack 不是背配置,而是理解它如何构建和扩展整个打包过程。
目录
- Webpack 是什么
- 为什么 Webpack 仍然必须学
- 核心工作流程
- Entry、Output、Loader、Plugin
- 模块、Chunk、Bundle 关系
- 代码分割与缓存
- 性能优化
- 自定义 Loader 与 Plugin
- 常见问题排查
- 高频面试题
- 一页总结
1. Webpack 是什么
Webpack 官方定义可以概括为:
一个现代 JavaScript 应用的静态模块打包器。
这句话要拆开理解:
静态模块依赖图打包输出
Webpack 会从入口文件出发,递归分析依赖,形成依赖图,再把资源组织成浏览器能加载的 bundle。
2. 为什么 Webpack 仍然必须学
虽然很多新项目不再默认优先选 Webpack,但它仍然是构建工具学习的核心:
- 它最经典
- 它概念最完整
- Loader / Plugin 思想影响了很多后续工具
- 面试高频
- 老项目大量仍在使用
一句话:
学构建原理最经典的教材,依然是 Webpack。
3. 核心工作流程
可以记成这条主线:
Entry -> Module Graph -> Loader Transform -> Plugin Hooks -> Chunk -> Output
3.1 从入口出发
Webpack 从 entry 开始分析。
3.2 构建依赖图
解析:
importrequire- 动态导入
3.3 Loader 转换资源
比如:
- TS -> JS
- JSX -> JS
- Less -> CSS
- CSS -> JS 可识别模块
3.4 Plugin 在生命周期里扩展能力
比如:
- 生成 HTML
- 提取 CSS
- 压缩 JS
- 注入环境变量
3.5 输出产物
最终产出多个 chunk 和静态资源文件。
4. Entry、Output、Loader、Plugin
4.1 Entry
入口文件,依赖图起点。
典型配置:
module.exports = {
entry: './src/main.js'
}
4.2 Output
控制输出目录、文件名、hash 策略。
const path = require('path')
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash:8].js',
clean: true
}
}
4.3 Loader
本质是模块转换器。
你要记住一句话:
Loader 负责把 Webpack 不认识的内容,或者需要转换的内容,变成它能继续处理的模块。
常见 loader:
babel-loaderts-loadercss-loaderstyle-loadersass-loader
4.4 Plugin
Plugin 用于扩展整个构建生命周期。
常见 plugin:
HtmlWebpackPluginMiniCssExtractPluginDefinePluginCopyWebpackPlugin
一句话区分:
Loader 处理单个模块转换Plugin 介入整个构建过程
5. 模块、Chunk、Bundle 关系
这是 Webpack 面试里最爱考的点之一。
5.1 Module
项目中的最小处理单元。
比如:
- JS 文件
- CSS 文件
- 图片
5.2 Chunk
Webpack 根据依赖关系、入口和分包策略组织出来的代码块。
5.3 Bundle
最终输出到磁盘上的文件。
5.4 一句话理解
模块是原料,chunk 是打包过程中的组织单位,bundle 是最终产物。
6. 代码分割与缓存
6.1 代码分割
核心目标:
- 减少首屏包体积
- 按需加载
- 提高缓存利用率
方式:
- 多入口
import()SplitChunksPlugin
6.2 长缓存
要点:
- 文件名带
contenthash - runtime 单独拆分
- vendor 单独拆分
这样可以减少小改动导致整站资源缓存失效。
7. 性能优化
7.1 构建速度优化
- 缩小 loader 处理范围
- 使用缓存
- 用
thread-loader等并行策略 - 减少 plugin 数量
- 用
swc-loader或esbuild-loader替代 Babel 的部分工作
7.2 包体积优化
- tree shaking
- 代码分割
- 按需加载
- 压缩图片和字体
- 第三方依赖按需引入
7.3 线上性能优化
- CDN
- Gzip / Brotli
- 长缓存
- preload / prefetch
8. 自定义 Loader 与 Plugin
8.1 Loader 本质
Loader 就是一个函数,输入源代码,输出转换后的代码。
适合理解为:
模块级转换器
8.2 Plugin 本质
Plugin 本质是注册在编译生命周期钩子上的扩展逻辑。
适合理解为:
编译流程级扩展器
8.3 面试表达
如果问你两者区别:
- Loader 处理的是文件内容转换
- Plugin 处理的是整个构建过程扩展
9. 常见问题排查
9.1 打包很慢
看:
- Babel 转换量
- source map 配置
- 大型依赖是否重复处理
- loader 是否命中过多文件
9.2 首屏包很大
看:
- 是否代码分割
- 是否 vendor 过大
- 是否按需引入失败
9.3 缓存命中差
看:
- 文件名是否用
contenthash - runtime 是否拆分
- 公共 chunk 是否稳定
10. 高频面试题
10.1 Webpack 为什么能处理图片和 CSS
因为通过 Loader 把这些资源转换成 Webpack 能处理的模块。
10.2 Loader 和 Plugin 区别
- Loader 做模块转换
- Plugin 扩展编译流程
10.3 什么是 tree shaking
基于静态分析移除未使用代码,依赖 ESM。
10.4 Webpack 为什么配置复杂
因为它非常通用、可扩展、可深度定制,代价就是学习和维护成本高。
10.5 为什么新项目不一定首选 Webpack
因为现代工具在默认开发体验、启动速度和配置复杂度上通常更优。
11. 一页总结
11.1 Webpack 的价值
不是最新默认首选,但仍然是理解前端构建体系最经典的核心工具。
11.2 记忆口诀
入口起图,Loader 转换,Plugin 扩展,Chunk 组织,Bundle 输出。