第十六章:Webpack 基础配置
一、为什么需要 Webpack?
1. 前端开发的痛点
模块化问题:浏览器原生不支持 import/export 等 ES6 模块语法
资源依赖管理:手动处理 CSS、图片、字体等非 JS 资源
性能优化需求:代码压缩、按需加载、Tree Shaking 等
开发效率:实时刷新、热更新(HMR)、Source Map
2. Webpack 的核心作用
将所有资源(JS、CSS、图片等)视为模块,通过依赖分析打包成浏览器可识别的静态文件。
二、快速上手 Webpack
1. 安装
npm init -y
npm install webpack webpack-cli --save-dev
这两行命令需要在项目目录下执行。
原因:
npm init -y:
该命令会在当前目录下初始化一个 npm 项目。
自动生成一个 package.json 文件,用于记录项目的依赖、版本等信息。
如果不在项目目录下执行,可能会在错误的位置生成 package.json,导致项目配置混乱。
npm install webpack webpack-cli --save-dev:
该命令会在当前目录下的 node_modules 文件夹中安装 webpack 和 webpack-cli。
同时,会将它们作为开发依赖(devDependencies)记录到 package.json 文件中。
如果不在项目目录下执行,安装的包不会被正确关联到你的项目,后续使用时可能会找不到依赖。
正确操作步骤:
进入你的项目目录(包含 src 文件夹和其他项目文件的目录)。
执行以下命令:
npm init -y
npm install webpack webpack-cli --save-dev
- 确保在项目目录下创建 webpack.config.js 文件并进行配置。
这样可以确保项目的依赖管理和配置是正确的。
2. 基础配置
创建 webpack.config.js:
const path = require('path');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js', // 输出文件名
path: path.resolve(__dirname, 'dist') // 输出目录
},
mode: 'production' // 模式:development 或 production
};
3. 运行打包
npx webpack
三、核心概念
1. Entry(入口)
定义依赖分析的起点:
entry: {
main: './src/index.js',
vendor: './src/vendor.js'
}
2. Output(出口)
指定打包文件的位置和命名规则:
output: {
filename: '[name].[contenthash].js', // 使用哈希避免缓存
path: path.resolve(__dirname, 'dist')
}
3. Loader(加载器)
处理非 JS 文件(Webpack 默认只理解 JS):
module: {
rules: [
{
test: /\.css$/, // 匹配 .css 文件
use: ['style-loader', 'css-loader'] // 从右向左执行
},
{
test: /\.(png|svg|jpg)$/,
type: 'asset/resource' // Webpack 5 内置资源处理
}
]
}
4. Plugin(插件)
扩展 Webpack 功能(如 HTML 模板生成):
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
四、Webpack 工作原理
1. 整体流程
graph TD
A[入口文件] --> B[解析模块依赖]
B --> C[构建依赖图]
C --> D[分割 Chunk]
D --> E[应用 Loader 转换]
E --> F[应用 Plugin 优化]
F --> G[生成最终文件]
2. 关键步骤详解
(1) 模块解析
从 entry 开始,递归分析 import/require 语句
生成 AST(抽象语法树) 分析依赖关系
(2) 依赖图构建
- 将所有模块及其依赖关系组合成 依赖图(Dependency Graph)
(3) Chunk 生成(详见附录:深入理解Chunk)
根据配置(如 splitChunks)将代码分割成多个 Chunk
常见的 Chunk 类型:
Initial Chunk(入口直接依赖)
Async Chunk(动态导入的模块)
Runtime Chunk(Webpack 运行时代码)
(4) 输出文件
将 Chunk 转换为最终文件
应用 Loader 转换(如 SCSS → CSS → JS 内联)
执行 Plugin 的优化逻辑(如压缩、添加 Hash)
五、配置实战
1. 开发服务器配置
devServer: {
static: './dist',
hot: true, // 热更新
port: 8080,
open: true // 自动打开浏览器
}
2. 处理样式
// 安装:npm install style-loader css-loader sass-loader sass --save-dev
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
3. Babel 转译
// 安装:npm install babel-loader @babel/core @babel/preset-env --save-dev
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
六、高级特性
1. 代码分割(Code Splitting)
// 动态导入(自动生成 Async Chunk)
import(/* webpackChunkName: "lodash" */ 'lodash').then(...);
2. Tree Shaking
自动删除未使用的代码(需配合 ES6 模块语法)
在 package.json 中添加:
"sideEffects": false
七、常见问题
1. 路径配置错误
// 错误:找不到模块
import MyComponent from './components/MyComponent';
// 正确:明确文件扩展名
import MyComponent from './components/MyComponent.js';
2. Loader 执行顺序
// 从后向前执行(先执行 sass-loader,最后 style-loader)
use: ['style-loader', 'css-loader', 'sass-loader']
3. 旧浏览器兼容
使用 @babel/preset-env + core-js:
// .babelrc
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}]
]
}
八、总结
✅ Webpack 核心能力:模块打包、资源转换、代码优化
✅ 关键配置:entry/output/loader/plugin
✅ 工作流程:依赖分析 → 构建依赖图 → 生成 Chunk → 输出文件
🔥 进阶方向:自定义 Loader/Plugin、性能优化、微前端集成