4. 搭建前端构建流程
任务说明
本案例为企业前端工程搭建一个基于 Vite 的生产级构建流程,实现 JavaScript(含 JSX)、CSS(含 CSS Modules)、图片资源的打包与基础优化。选择 Vite 而非 Webpack,是因为其基于原生 ES Module 的开发服务器启动更快、配置更简洁,且内置了 Rollup 生产构建能力,足以覆盖本案例所需的资源打包与代码分割优化目标。
项目结构与依赖
在空目录中创建以下文件结构:
vite-demo/
├── index.html
├── package.json
├── vite.config.js
├── src/
│ ├── main.jsx
│ ├── App.jsx
│ ├── styles/
│ │ ├── global.css
│ │ └── app.module.css
│ └── assets/
│ └── logo.svg
在 package.json 中声明依赖与脚本:
{
"name": "vite-demo",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^4.2.1",
"vite": "^5.2.0"
}
}
构建配置
创建 vite.config.js,配置 React 插件、CSS 代码分割、图片内联阈值与打包体积提示:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
// 小于 4KB 的图片转为 base64 内联,减少 HTTP 请求
assetsInlineLimit: 4096,
// 开启 CSS 代码分割,按需加载
cssCodeSplit: true,
// 构建提示:当 chunk 超过 500KB 时输出警告
chunkSizeWarningLimit: 500,
rollupOptions: {
output: {
// 手动分包:将 react 相关依赖单独打包,利用浏览器缓存
manualChunks: {
'react-vendor': ['react', 'react-dom']
}
}
}
},
server: {
port: 5173,
open: true
}
});
应用源码
index.html 作为入口模板:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite 构建流程示例</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
src/main.jsx 引入全局 CSS 并挂载 React 应用:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
import './styles/global.css';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
src/App.jsx 使用 CSS Modules 与图片资源:
import React from 'react';
import styles from './styles/app.module.css';
import logoSvg from './assets/logo.svg';
function App() {
return (
<div className={styles.container}>
<img src={logoSvg} alt="logo" className={styles.logo} />
<h1 className={styles.title}>Vite 构建流程已生效</h1>
<p className={styles.description}>
此页面由 React + Vite 构建,包含 JSX、CSS Modules 与 SVG 资源。
</p>
</div>
);
}
export default App;
src/styles/global.css 全局样式:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f5f7fa;
color: #333;
}
src/styles/app.module.css 模块化样式:
.container {
max-width: 600px;
margin: 80px auto;
padding: 40px;
background: #fff;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
text-align: center;
}
.logo {
width: 120px;
height: 120px;
margin-bottom: 24px;
}
.title {
font-size: 28px;
color: #2c3e50;
margin-bottom: 16px;
}
.description {
font-size: 16px;
line-height: 1.6;
color: #666;
}
src/assets/logo.svg 示例图片资源:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="45" fill="#646cff" />
<text x="50" y="65" text-anchor="middle" font-size="40" fill="#fff">V</text>
</svg>
构建流程与优化机制
Vite 在开发模式下利用浏览器原生 ES Module 按需编译,无需预打包;生产构建时通过 Rollup 执行以下优化:
- JS 打包与压缩:将 JSX 编译为浏览器可执行的 JavaScript,并压缩为 ES5 兼容代码(默认目标为现代浏览器,可通过
build.target调整)。 - CSS 处理:
global.css被提取为独立样式文件;app.module.css通过 CSS Modules 机制生成带哈希的局部类名,避免样式冲突,同样被提取到产物 CSS 中。 - 图片优化:小于 4KB 的 SVG 被转为 base64 内联到 JS 包中,减少请求数;大于阈值的图片会输出到
dist/assets目录并自动加哈希指纹。 - 代码分割:通过
manualChunks将 React 相关依赖单独拆分为react-vendorchunk,利用浏览器长期缓存减少重复下载。
运行与验证
在项目根目录执行以下命令:
npm install
npm run build
构建完成后,检查 dist/ 目录结构,预期应包含:
index.html:入口 HTML,自动注入打包后的 JS/CSS 引用。assets/目录:包含index-*.js、react-vendor-*.js、index-*.css等文件,文件名带内容哈希。- SVG 文件不会单独出现在
dist/assets中,因为它小于 4KB 已被内联。
执行 npm run preview 启动本地预览服务器,浏览器访问 http://localhost:4173,页面应正常显示蓝色圆形 V 字 Logo 与标题文字。打开浏览器开发者工具的网络面板,刷新页面,可观察到:
- JS 被拆分为两个请求(业务代码与 react-vendor),CSS 为单独请求。
- 没有单独的 SVG 网络请求,证明图片已内联。
判定标准:若页面渲染正常、网络面板中无 SVG 请求、且 JS 被拆分为两个 chunk,则说明构建流程配置成功,JS/CSS/图片资源的打包与优化目标达成。