当前端项目从编写几个简单的HTML
、CSS
、JS
文件,过渡到开发需要成千上百个模块、依赖各种第三方库、甚至需要处理less
、TypeScript
、图片
等资源的项目时,随之而来的问题和麻烦接踵而至:如何组织文件
、浏览器不识别的语法如何处理
以及如何高效加载文件
等等。
Webpack正是在这样的背景下诞生的。它不仅前端开发的基础工具,更是打通开发便捷性
与生产性能
的关键桥梁。无论你是前端的小白,还是想夯实工程化基础的进阶者,理解Webpack
的工作逻辑和使用方法,都让你在项目少走弯路,更好的应对其复杂场景。
接下来,让我们从Webpack是什么
开始,一步一步揭开其神秘面纱,从原理到基础实战,彻底搞懂这个前端工程化工具。
Webpack是什么
Webpack是一个静态模块打包工具 。它视所有文件为模块
(JS、sass/less、图片、字体、TS),通过分析它们之间的依赖关系,最终打包成浏览器能直接识别的静态资源(JS或CSS等文件)。

可以将Webpack
理解成为工厂
:原料是项目中各种文件(js、css、less、ts等),按照依赖关系和特定规则处理它们,最后生成浏览器可以识别的产品
(bundle文件)。
Webpack底层原理
Webpack
的核心工作简单地说:从入口文件,递归解析所有依赖,处理后打包成输出文件。一步一步了解它的构建过程。
1. 确定规则
Webpack运行构建时,会默认读取项目根目录下webpack.config.js
文件或读取命令行--config
后的参数的配置文件。有如下核心配置:
- 入口(entry):定义从哪个文件开始解析依赖
- 出口(output):确定打包后文件名称和放入位置
- 解释器(loader) :由于Webpack只能识别JS和JSON文件,webpack通过配置
loader
,将非JS文件转化为JS模块 - 插件(plugin):在Webpack的构建的生命周期中额外处理。如自动生成HTML,压缩代码等等。
2, 编译阶段
这是Webpack最为核心的阶段。分为构建依赖图
和模块转换
- 构建依赖图 Webpack会从
webpack.config.js
配置文件中的entry
定义的入口文件地址开始,一层层地解析文件。- 先读取入口文件的内容,分析出依赖了哪些文件。
- 递归解析被依赖的文件,直到所有关联的文件都被找到
- 最后形成一张Graph,记录了所有文件的路径、内容以及它们之间的依赖关系
举个例子 :如果 index.js
依赖 a.js
,a.js
依赖 b.css
和 c.png
,依赖图就会清晰记录这层关系。

js
// 构建类似如下伪代码
{
"./src/index.js": () => {
// 加载a.js
},
"./src/a.js": () => {
// 加载b.css和c.png
},
"./src/b.css": () => { // 读取文件},
"./src/c.png": () => { // 读取图片}
}
- 模块转换
Wepack本身只能识别JS和JSON文件,如遇到其他文件就需要Loader
进行翻译
。
loader
的作用是转换
:将非JS文件转换为JS模块- 处理顺序是
从右到左
或从下往上
js
{
test: /.css$/,
// 从右到左 依次执行
use: ['style-loader', 'css-loader'],
// use: [
// 'style-loader',
// 'css-loader'
//]
},
-
插件介入
在编译的各个环节,插件都可以介入进行处理。
-
插件是 "扩展器":可以做 loader 做不到的事情,比如自动生成 HTML 文件(
HtmlWebpackPlugin
)、压缩代码(TerserPlugin
)、清除旧文件(CleanWebpackPlugin
)等。 -
插件基于 "事件钩子" 工作:Webpack 在打包过程中会触发很多事件(比如
beforeCompile
、afterCompile
),插件可以监听这些事件,在特定时机执行逻辑。
Webpack基础使用
在使用Webpack之前,确保项目安装Webpack
bash
npm init -y // 初始化项目
npm i webpack webpack-cli -D // 开发依赖下安装webapck
指定入口
入口用于告诉Webpack
从哪个文件开始解析依赖。
js
module.exports = {
entry: "./src/index.js" // 单入口文件
/* 适合多页面应用
entry: {
index: "./src/index.js",
print: "./src/print.js"
}
*/
}
指定出口
js
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
// 多入口时: filename: '[name].bundle.js'
path: path.resolve(__dirname, "dist"),
clean: true, // 清理dist目录
},
}
加载资源
Webpack处理非JS文件需要在module.rules
配置,通过test
匹配文件类型,用use
指定对应的loader
1. 处理CSS文件
需要借助css-loader
转换CSS文件变为JS
模块;style-loader
将CSS插入到页面的style
标签
- 安装loader
bash
npm i css-loader style-loader -D # 开发依赖
- 配置
js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
// loader 执行顺序:从右到左(先 css-loader 再 style-loader)
use:["style-loader", 'css-loader']
}
]
}
}
如果使用sass
还需要sass-loader
和sass
bash
npm i sass sass-loader -D
js
{
test: "/\.scss$/",
use: ["style-loader", "css-loader", "scss-loader"]
}
如果使用less
还需要less-loader
和less
bash
npm i less less-loader -D
js
{
test: "/\.less$/",
use: ["style-loader", "css-loader", "less-loader"]
}
2. 处理图片/字体
Webpack5
内置通过Rule.type
处理字体和图片,无需额外配置loader。Rule.type
的值如下:
asset/resource
将资源作为单独文件输出,并返回URLasset/inline
将文件作为Data URL内联到bundle中asset/source
将文件作为原始源码导入asset
根据配置决定是inline
还是resource
js
module.exports = {
module: {
rules: [
test: /\.(png|jpg|gif|svg)$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024 // 8kb
}
}
]
}
}
开发模式
开发时需要方便调试和自动刷新,以便提高开发效率。
1. 基础开发配置
js
module.exports = {
mode: 'development', // 定义为开发模式
devtool: 'inline-source-map' // 生成source-map 方便调试
}
2. 开发服务器
webpack-dev-server
提供热更新(修改代码后自动刷新页面),无需手动重新打包:
bash
npm i webpack-dev-server -D
配置
js
module.exports = {
devServer: {
static: './dist', // 服务器根目录
port: 3000, // 服务器端口号
open: true, // 启动服务后自动打开浏览器
hot: true // 开启热模块替换 修改代码后自动刷新页面
}
}
在package.json
的scripts
字段中配置运行指令
json
{
"scripts": {
"dev": "webpack serve" // 启动开发服务器
}
}
🎯 本文小结
💡 核心要点回顾
Webpack 的本质:静态模块打包工具,将各种资源转化为浏览器可识别的静态文件
四大核心概念:
- 入口(Entry) :构建起点
- 出口(Output) :打包结果位置
- 加载器(Loader) :非JS文件转换器
- 插件(Plugin) :构建过程扩展器
构建两大阶段:
- 依赖图构建:从入口开始,递归分析模块依赖关系
- 模块转换:通过Loader将各类资源转为JS模块
开发效率提升:
webpack-dev-server
提供热更新mode: 'development'
优化开发体验