文章目录

Webpack 学习笔记

适合目标:从零到深入掌握 Webpack,理解其依赖图、Loader、Plugin、分包、缓存、性能优化与面试答法。
学习定位:这一份偏“原理核心 + 面试核心 + 老项目必备”。
学习原则:Webpack 不是背配置,而是理解它如何构建和扩展整个打包过程。


目录

  1. Webpack 是什么
  2. 为什么 Webpack 仍然必须学
  3. 核心工作流程
  4. Entry、Output、Loader、Plugin
  5. 模块、Chunk、Bundle 关系
  6. 代码分割与缓存
  7. 性能优化
  8. 自定义 Loader 与 Plugin
  9. 常见问题排查
  10. 高频面试题
  11. 一页总结

1. Webpack 是什么

Webpack 官方定义可以概括为:

一个现代 JavaScript 应用的静态模块打包器。

这句话要拆开理解:

  1. 静态模块
  2. 依赖图
  3. 打包输出

Webpack 会从入口文件出发,递归分析依赖,形成依赖图,再把资源组织成浏览器能加载的 bundle。


2. 为什么 Webpack 仍然必须学

虽然很多新项目不再默认优先选 Webpack,但它仍然是构建工具学习的核心:

  1. 它最经典
  2. 它概念最完整
  3. Loader / Plugin 思想影响了很多后续工具
  4. 面试高频
  5. 老项目大量仍在使用

一句话:

学构建原理最经典的教材,依然是 Webpack。


3. 核心工作流程

可以记成这条主线:

Entry -> Module Graph -> Loader Transform -> Plugin Hooks -> Chunk -> Output

3.1 从入口出发

Webpack 从 entry 开始分析。

3.2 构建依赖图

解析:

  1. import
  2. require
  3. 动态导入

3.3 Loader 转换资源

比如:

  1. TS -> JS
  2. JSX -> JS
  3. Less -> CSS
  4. CSS -> JS 可识别模块

3.4 Plugin 在生命周期里扩展能力

比如:

  1. 生成 HTML
  2. 提取 CSS
  3. 压缩 JS
  4. 注入环境变量

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:

  1. babel-loader
  2. ts-loader
  3. css-loader
  4. style-loader
  5. sass-loader

4.4 Plugin

Plugin 用于扩展整个构建生命周期。

常见 plugin:

  1. HtmlWebpackPlugin
  2. MiniCssExtractPlugin
  3. DefinePlugin
  4. CopyWebpackPlugin

一句话区分:

  1. Loader 处理单个模块转换
  2. Plugin 介入整个构建过程

5. 模块、Chunk、Bundle 关系

这是 Webpack 面试里最爱考的点之一。

5.1 Module

项目中的最小处理单元。

比如:

  1. JS 文件
  2. CSS 文件
  3. 图片

5.2 Chunk

Webpack 根据依赖关系、入口和分包策略组织出来的代码块。

5.3 Bundle

最终输出到磁盘上的文件。

5.4 一句话理解

模块是原料,chunk 是打包过程中的组织单位,bundle 是最终产物。


6. 代码分割与缓存

6.1 代码分割

核心目标:

  1. 减少首屏包体积
  2. 按需加载
  3. 提高缓存利用率

方式:

  1. 多入口
  2. import()
  3. SplitChunksPlugin

6.2 长缓存

要点:

  1. 文件名带 contenthash
  2. runtime 单独拆分
  3. vendor 单独拆分

这样可以减少小改动导致整站资源缓存失效。


7. 性能优化

7.1 构建速度优化

  1. 缩小 loader 处理范围
  2. 使用缓存
  3. thread-loader 等并行策略
  4. 减少 plugin 数量
  5. swc-loaderesbuild-loader 替代 Babel 的部分工作

7.2 包体积优化

  1. tree shaking
  2. 代码分割
  3. 按需加载
  4. 压缩图片和字体
  5. 第三方依赖按需引入

7.3 线上性能优化

  1. CDN
  2. Gzip / Brotli
  3. 长缓存
  4. preload / prefetch

8. 自定义 Loader 与 Plugin

8.1 Loader 本质

Loader 就是一个函数,输入源代码,输出转换后的代码。

适合理解为:

模块级转换器

8.2 Plugin 本质

Plugin 本质是注册在编译生命周期钩子上的扩展逻辑。

适合理解为:

编译流程级扩展器

8.3 面试表达

如果问你两者区别:

  1. Loader 处理的是文件内容转换
  2. Plugin 处理的是整个构建过程扩展

9. 常见问题排查

9.1 打包很慢

看:

  1. Babel 转换量
  2. source map 配置
  3. 大型依赖是否重复处理
  4. loader 是否命中过多文件

9.2 首屏包很大

看:

  1. 是否代码分割
  2. 是否 vendor 过大
  3. 是否按需引入失败

9.3 缓存命中差

看:

  1. 文件名是否用 contenthash
  2. runtime 是否拆分
  3. 公共 chunk 是否稳定

10. 高频面试题

10.1 Webpack 为什么能处理图片和 CSS

因为通过 Loader 把这些资源转换成 Webpack 能处理的模块。

10.2 Loader 和 Plugin 区别

  1. Loader 做模块转换
  2. Plugin 扩展编译流程

10.3 什么是 tree shaking

基于静态分析移除未使用代码,依赖 ESM。

10.4 Webpack 为什么配置复杂

因为它非常通用、可扩展、可深度定制,代价就是学习和维护成本高。

10.5 为什么新项目不一定首选 Webpack

因为现代工具在默认开发体验、启动速度和配置复杂度上通常更优。


11. 一页总结

11.1 Webpack 的价值

不是最新默认首选,但仍然是理解前端构建体系最经典的核心工具。

11.2 记忆口诀

入口起图,Loader 转换,Plugin 扩展,Chunk 组织,Bundle 输出。