一、什么是工程化、为什么需要 Webpack
1.1 前端工程的痛点
现代前端项目早已不是"一个 HTML 引几个 JS 文件"那么简单:
- 文件爆炸 :几十上百个模块互相依赖,手动管理
<script>标签顺序极易出错; - 依赖复杂:npm 安装的第三方库版本、依赖关系需要统一解析;
- 语法差异:ES Modules、TypeScript、JSX 等语法浏览器不能直接运行,需要转换;
- 资源优化:图片、字体、CSS 需要合并压缩,减少请求数。
1.2 工程化解决什么
| 问题 | 工程化方案 |
|---|---|
| 模块管理 | 用 ES Modules / CommonJS 按需引入 |
| 语法转换 | Babel 把新语法编译为兼容代码 |
| 资源打包 | 把 JS/CSS/图片合并为少量静态文件 |
| 性能优化 | 代码压缩、按需加载、缓存指纹 |
Webpack 就是把这些能力整合起来的"模块打包器"(module bundler):从入口文件出发,递归解析所有依赖,最终打包成浏览器可直接运行的静态资源。
1.3 打包核心原理:依赖图
flowchart LR
A[src/index.js 入口] --> B[模块A import]
A --> C[模块B import]
B --> D[模块C import]
C --> E[node_modules 第三方库]
D & E --> F[依赖图 Dependency Graph]
F --> G[dist/bundle.js 单一产物]
Webpack 以入口为根,沿着 import / require 递归收集所有依赖,形成一张依赖图,再按规则转换、合并、输出为浏览器可用的文件。
二、Webpack 核心四大概念
| 概念 | 作用 | 配置位置 |
|---|---|---|
| 入口(entry) | 打包的起点,告诉 Webpack 从哪个文件开始 | entry |
| 输出(output) | 打包产物的位置与文件名 | output |
| Loader | 处理非 JS 文件(CSS、图片、TS 等),将其转为模块 | module.rules |
| 插件(Plugin) | 在打包生命周期做额外操作(如生成 HTML、压缩) | plugins |
一句话记忆:入口定起点,输出定结果,Loader 管文件转换,Plugin 管流程增强。
三、环境准备:npm 初始化与安装
前置要求:安装 Node.js(建议 18+,含 npm)。可用
node -v验证。
bash
# 1. 创建项目目录并进入
mkdir webpack-demo && cd webpack-demo
# 2. 初始化 package.json(-y 跳过交互提问)
npm init -y
# 3. 安装 webpack 与命令行工具(开发依赖)
npm install -D webpack webpack-cli
安装完成后 package.json 中出现:
json
"devDependencies": {
"webpack": "^5.97.0",
"webpack-cli": "^6.0.0"
}
说明 :
-D(--save-dev)表示开发依赖,仅构建时需要;运行时不需要 Webpack 本身。
四、基础打包配置:entry / output
创建配置文件 webpack.config.js(Webpack 默认读取它):
js
const path = require("path");
module.exports = {
// 模式:development 开发(不压缩、有注释)/ production 生产(压缩)
mode: "development",
// 入口:打包起点
entry: "./src/index.js",
// 输出:产物位置与文件名
output: {
path: path.resolve(__dirname, "dist"), // 绝对路径,必须
filename: "bundle.js", // 产物文件名
clean: true, // 每次打包前清空 dist
},
};
| 配置项 | 含义 | 注意 |
|---|---|---|
entry |
入口文件 | 可写字符串(单入口)或对象(多入口) |
output.path |
输出目录 | 必须是绝对路径,用 path.resolve |
output.filename |
输出文件名 | 多入口时用 [name].js 占位 |
output.clean |
打包前清空输出目录 | Webpack 5 内置,无需插件 |
mode |
构建模式 | development / production / none |
五、首次打包实战:npx 打包命令
5.1 创建入口文件
bash
mkdir src
src/index.js------演示模块化引入(Webpack 的核心价值就在这):
js
// src/math.js
export function add(a, b) {
return a + b;
}
js
// src/index.js
import { add } from "./math.js";
console.log("2 + 3 =", add(2, 3));
5.2 执行打包
bash
# npx 会优先使用项目本地安装的 webpack
npx webpack
输出类似:
scss
asset bundle.js 36 bytes [emitted] [minimized] (name: main)
runtime modules 332 bytes 2 modules
./src/index.js 95 bytes [built] [code generated]
./src/math.js 86 bytes [built] [code generated]
webpack 5.97.0 compiled successfully in 92 ms
5.3 查看产物
打包后 dist/bundle.js 生成。在 dist 下放一个 index.html 引入它:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Webpack Demo</title>
</head>
<body>
<script src="./bundle.js"></script>
</body>
</html>
浏览器打开即可看到控制台输出 2 + 3 = 5------两个模块被打包进一个文件,浏览器直接运行。
5.4 把打包命令写进 npm scripts
json
"scripts": {
"build": "webpack"
}
之后执行 npm run build 即可,效果等同 npx webpack。
5.5 完整目录结构
bash
webpack-demo/
├── node_modules/
├── src/
│ ├── index.js # 入口
│ └── math.js # 被引入的模块
├── dist/ # 打包产物(自动生成)
│ └── bundle.js
├── package.json
└── webpack.config.js
六、开发环境简单认知
mode 直接影响产物形态:
| 模式 | 代码压缩 | 调试信息 | 用途 |
|---|---|---|---|
development |
不压缩 | 保留注释与 source-map | 日常开发调试 |
production |
压缩混淆 | 移除调试信息 | 上线发布 |
开发期真正的高效工具是 webpack-dev-server(热更新),可做到"改代码即刷新、局部替换"。它属于插件与开发环境范畴,将在系列第 3 篇《Webpack 常用插件与热更新》中详解。
七、总结
- 工程化解决模块管理、语法转换、资源打包、性能优化四大问题;
- 原理:从入口递归构建依赖图,打包为浏览器可运行的静态文件;
- 四大概念:入口(起点)、输出(结果)、Loader(文件转换)、Plugin(流程增强);
- 实战 :
npm init -y→ 安装webpack+webpack-cli→ 配置entry/output→npx webpack出包。