前端工程化实战指南(Vite 与 Webpack)
前端工程化是前端进阶的必经之路,也是 CSDN 前端板块的高频话题。前面讲过 React、Vue、TypeScript,这篇讲构建体系:模块化演进、Webpack 核心概念、Loader/Plugin、Vite 原理、性能优化、工程配置,全程带配置代码。
一、前端工程化是什么
1.1 解决的问题
十年前:一个 HTML 引一堆 script,全局变量满天飞
现在:模块化开发 + 构建打包 + 自动优化 + 规范协作
工程化 = 开发体验 + 产物质量 + 团队协作:
- 模块化:代码拆文件、按依赖组织;
- 构建:ES6 → 兼容代码、压缩、tree-shaking;
- 开发服务器:热更新(HMR);
- 规范化:lint、格式、提交检查。
1.2 构建工具演进
| 时代 | 工具 | 特点 |
|---|---|---|
| 2015-2020 | Webpack | 功能全、生态大、配置重 |
| 2018+ | Rollup | 库打包(tree-shaking 强) |
| 2020+ | Vite | 极速启动(esbuild 预构建)、开发体验好 |
| 现在 | Turbopack/Rspack | 性能更强的 Webpack 替代 |
现状:新项目默认 Vite;老项目/复杂生态还在用 Webpack。
二、Webpack 核心概念
2.1 核心思想
一切皆模块------JS、CSS、图片、字体都当作模块,按依赖图打包成静态资源。
entry(入口)→ 依赖图 → loader 转换 → plugin 优化 → output(出口)
2.2 基础配置
javascript
// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js', // 内容 hash:缓存友好
clean: true, // 清空 dist
},
mode: 'production', // development/production
module: {
rules: [ // Loader:转换文件
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader', // ES6+ → 兼容代码
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'], // 从右往左执行
},
{
test: /\.(png|jpg|svg)$/,
type: 'asset', // 小图内联,大图走文件
},
],
},
plugins: [
new HtmlWebpackPlugin({ template: './index.html' }),
],
devServer: {
port: 3000,
hot: true, // 热更新
proxy: { '/api': 'http://localhost:8080' },
},
};
2.3 Loader vs Plugin(面试必考)
| 维度 | Loader | Plugin |
|---|---|---|
| 作用 | 转换文件内容 | 扩展构建流程 |
| 对象 | 单个文件 | 整个构建过程 |
| 例子 | babel-loader、css-loader | HtmlWebpackPlugin、MiniCssExtractPlugin |
| 类比 | 翻译官 | 项目管理者 |
执行顺序:Loader 从右到左(逆序);Plugin 在构建生命周期各阶段钩子触发。
三、Vite 原理(为什么快)
3.1 开发模式:原生 ESM
Webpack 慢的原因 :启动时全量打包------项目越大越慢。
Vite 的思路 :开发时不打包,直接用浏览器原生 ESM:
Webpack:入口 → 打包全部模块 → 启动(秒~几十秒)
Vite:入口 → 按需加载(浏览器请求哪个编译哪个)→ 启动(毫秒级)
预构建 :node_modules 里的依赖用 esbuild 预打包(Go 写的,比 JS 快几十倍)。
3.2 HMR 为什么快
- Webpack:改一个文件 → 重新打包该模块及其依赖;
- Vite:原生 ESM 按需更新,改哪个热更哪个------大项目几乎瞬时。
3.3 生产构建:Rollup
text
开发:esbuild(极速预构建 + 按需加载)
生产:Rollup(tree-shaking 强、产物干净)
3.4 Vite 基础配置
javascript
// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'), // 路径别名
},
},
server: {
port: 5173,
proxy: { // 开发代理(解决跨域)
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
},
},
},
build: {
outDir: 'dist',
chunkSizeWarningLimit: 1000,
rollupOptions: {
output: {
manualChunks: { // 手动分包
vue: ['vue', 'vue-router', 'pinia'],
echarts: ['echarts'],
},
},
},
},
});
四、工程化核心实践
4.1 代码规范(ESLint + Prettier)
bash
npm install -D eslint prettier eslint-plugin-vue
json
// .eslintrc.json
{
"extends": ["eslint:recommended", "plugin:vue/vue3-recommended"],
"rules": {
"no-unused-vars": "error",
"vue/multi-word-component-names": "off"
}
}
bash
npx eslint src --fix # 检查并修复
npx prettier --write src # 统一格式
4.2 Git Hooks(提交前检查)
bash
npm install -D husky lint-staged
npx husky init
json
// package.json
{
"lint-staged": {
"*.{js,ts,vue}": ["eslint --fix", "prettier --write"]
}
}
效果 :git commit 前自动检查格式------坏代码进不了仓库。
4.3 环境变量
bash
# .env.development
VITE_API_BASE=/api
# .env.production
VITE_API_BASE=https://api.example.com
javascript
// 代码里用
const base = import.meta.env.VITE_API_BASE;
注意 :只有 VITE_ 前缀的变量会暴露给前端代码------密钥永远放后端。
五、构建性能优化
5.1 产物优化(让用户加载快)
| 手段 | 做法 | 效果 |
|---|---|---|
| Tree-shaking | 只打包用到的代码 | 减小体积 |
| 代码分割 | 路由级懒加载 | 首屏只加载需要的 |
| 分包 | 第三方库单独 chunk | 缓存命中率高 |
| 压缩 | terser/esbuild | 减小 50%+ |
| gzip/brotli | 服务端压缩 | 再减 60-80% |
| 图片压缩 | image-webpack-loader | 图片大幅减小 |
路由懒加载(Vite):
javascript
const routes = [
{
path: '/orders',
component: () => import('./pages/Orders.vue'), // 按需加载
},
];
5.2 开发体验优化
- 别名 :
@指向 src(上面配过); - 代理:dev server 转发 /api 解决跨域;
- mock:开发期用 vite-plugin-mock 模拟接口;
- 缓存 :webpack 持久化缓存(
cache: { type: 'filesystem' })。
5.3 构建速度优化
javascript
// Webpack
module.exports = {
cache: { type: 'filesystem' }, // 磁盘缓存
module: {
rules: [{ test: /\.js$/, use: 'babel-loader',
exclude: /node_modules/ }]
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: { '@': path.resolve(__dirname, 'src') },
},
};
原则:缩小构建范围(exclude node_modules)、开启缓存、减少插件、升级工具(Webpack 5 → Rspack/Turbopack)。
六、从零搭一个 Vite + Vue 项目
bash
# 创建项目
npm create vite@latest my-app -- --template vue
cd my-app
npm install
# 开发
npm run dev
# 构建
npm run build
# 预览产物
npm run preview
目录规范:
src/
├── api/ # 接口封装
├── assets/ # 静态资源
├── components/ # 公共组件
├── composables/ # 组合式函数
├── router/ # 路由
├── stores/ # Pinia 状态
├── styles/ # 全局样式
├── utils/ # 工具函数
└── views/ # 页面
七、常见坑速查
| 现象 | 原因 | 解决 |
|---|---|---|
| 改了代码不生效 | 缓存/HMR 失效 | 重启 dev server |
| 打包很大 | 没分包/没 tree-shaking | manualChunks + 懒加载 |
| 本地正常线上 404 | 路由模式 history | 服务端配置 fallback |
| 跨域报错 | 代理没配 | server.proxy |
| 图片引用失败 | 路径问题 | 用 import/alias 引入 |
| 构建报内存不足 | 项目大 | NODE_OPTIONS=--max-old-space-size=4096 |
| ESLint 与团队风格冲突 | 规则没统一 | 统一 .eslintrc + prettier |
| 老浏览器白屏 | 没做兼容 | @vitejs/plugin-legacy |
本章小结
前端工程化的核心能力:Webpack 懂原理(模块/loader/plugin)、Vite 懂优势(esbuild 极速开发)、两者都懂优化(分包、懒加载、压缩、缓存) 。工程化的终点不是工具本身,而是规范化的协作流程:代码规范自动检查、构建产物稳定可控、上线流程可回滚。
下一篇讲 MySQL 事务与锁------数据库面试的压轴高频题。
(全文完)