Skip to content

生产构建 ​

执行构建 ​

bash
## 构建
pnpm build

## 不使用缓存构建
pnpm build:no-cache

构建成功后终端输出类似:

bash
Building [████████████████████████████████████████] 100% | Time: 24.3s

Build successful. Please see dist directory

构建产物 ​

静态文件输出目录:

bash
dist/
├── favicon.ico              # 站点图标
├── index.html               # 入口 HTML(含 .br/.gz 预压缩副本)
├── logo.png                 # Logo 图片
├── stats.html               # 打包体积分析报表
├── assets/js/               # JS 资源(业务 chunk + 第三方依赖 + i18n,含 .br/.gz 压缩副本)
├── css/                     # 样式资源(入口、组件库、页面级样式)
├── png/                     # PNG 图片(404、大图等)
├── jpg/                     # JPG 背景图
├── gif/                     # GIF 动图(401 页)
├── woff/  / woff2/  / ttf/  # iconfont 字体文件
└── ...

WARNING

dist/ 目录为构建生成物,不要手动编辑;应修改源文件后重新 build。

本地预览 ​

bash
pnpm preview

默认访问:

bash
http://localhost:4000/

用于在部署前验证样式、路由与组件示例是否正常。

流程说明 ​

项目基于 Vite 6 + Rollup 的标准 SPA 构建流程,产出静态资源:

  • 依赖预构建(optimizeDeps):Vite 将 vue/vue-router/element-plus 等 include 列表里的依赖用 esbuild 预打成 ESM,加速后续构建。
  • 编译转换:@vitejs/plugin-vue(SFC)+ @vitejs/plugin-vue-jsx(TSX)+ unocss + vue-i18n 等插件链式处理源码。
  • 打包分块(Rollup):按 manualChunks 策略将业务代码与第三方依赖拆分为独立 chunk,业务按路由懒加载自动分块。
  • 资源处理:CSS 按页面拆分、SCSS 变量全局注入、小体积资源(<5KB)内联为 base64。
  • 压缩输出:esbuild 压缩 JS,可选 terser 二次压缩;同时对 >10KB 的文件预生成 .gz 和 .br 压缩副本。
  • 产物生成:输出到 dist/,含 index.html、hash 命名的 JS/CSS、图片字体、stats.html 体积分析报表。

优化配置 ​

1. JS 分包策略 ​

按依赖类型分层拆 chunk,避免单文件过大、提升缓存命中率:

chunk 名包含
vuevue / @vue / vue-router / pinia / vue-i18n / vue-types / @vueuse
elementPluselement-plus / @element-plus
echartsecharts / echarts-wordcloud / zrender
guavaUIguava-ui
独立分包axios / crypto-js / cropperjs / pinyin-pro / qrcode / @cropper/*
vendor其他未命中、体积 <80KB 的第三方包
自动分包node_modules 中 ≥80KB 且不在上述规则的包,按包名单独成 chunk

实际产物体积:

chunk大小
elementPlus-*.js936KB
echarts-*.js800KB
guavaUI-*.js268KB
pinyin-pro-*.js296KB
vue-*.js196KB
vendor-*.js96KB

2. Element Plus 按需样式 ​

通过 vite-plugin-style-import + 自定义 resolveElementPlusStyle,仅在用到组件时加载对应 CSS。同时 src/styles/element-plus-preload.ts 显式补充 guava-ui 内部使用但按需插件无法注入的 ~50 个组件样式。

对比全量引入 element-plus/dist/index.css(约350KB),实际产物:

文件大小
elementPlus-*.css272KB
guavaUI-*.css96KB
index-*.css64KB
各页面 CSS4–8KB

3. 静态资源压缩(gzip + brotli) ​

ts
compression({ algorithm: 'gzip', threshold: 10240 }); // >10KB 生成 .gz
compression({ algorithm: 'brotliCompress', threshold: 10240 }); // >10KB 生成 .br

产物中每个 JS/CSS/HTML 均附带 .gz 与 .br 副本,Nginx 可直接使用 gzip_static / brotli_static 实时返回,无需服务端即时压缩。

4. 环境变量驱动构建行为 ​

变量作用
VITE_DROP_CONSOLEtrue 时移除 console.log
VITE_DROP_DEBUGGERtrue 时移除 debugger
VITE_USE_ALL_ELEMENT_PLUS_STYLEfalse 启用 EP 按需样式,true 引入全量 CSS
VITE_SOURCEMAPtrue 输出 sourcemap
VITE_BUNDLE_ANALYZERtrue 输出 stats.html 体积分析
VITE_OUT_DIR自定义输出目录,默认 dist

5. 其他优化 ​

  • SCSS 全局变量自动注入:additionalData: @use "@/styles/styles.variables.scss",所有 SFC 无需手动 import。
  • 小资源内联:assetsInlineLimit: 5120,<5KB 资源转 base64 减少请求。
  • 构建目标:target: 'es2015' + cssTarget: ['chrome31'],兼容老浏览器(@vitejs/plugin-legacy 已注释,可按需开启)。
  • 告警阈值:chunkSizeWarningLimit: 2048(2MB),避免无意义的大包警告刷屏。
  • 最小 chunk:experimentalMinChunkSize: 20 * 1024,过小的模块合并以减少碎片请求。
  • 可视化分析:rollup-plugin-visualizer 生成 dist/stats.html,展示 gzip/brotli 体积。
  • SVG 图标:vite-plugin-svg-icons-ng 将 src/assets/svgs 下的 SVG 注册为 symbol sprite,class 规则 gv-icon-[dir]-[name]。
  • ESLint 不阻断构建:failOnError: false,开发期提示但不阻塞产出。
  • UnoCSS 扫描组件库:content.filesystem 包含 node_modules/guava-ui/**,组件库使用的原子类也能被正确生成。

体积参考 ​

资源大小
dist 总计8.3 MB
assets/js5.5 MB
css660 KB
业务页面 JS(60+ 个 chunk)合计 ~1.2 MB
入口 index.js~500KB(路由/布局/首屏)

失败排查 ​

错误可能原因处理
模块无法解析 @/ 别名alias 未生效 / 文件缺失检查 vite.config.ts resolve.alias 与目标文件
element-plus 样式丢失VITE_USE_ALL_ELEMENT_PLUS_STYLE 与按需引入混用按需模式下检查 element-plus-preload.ts 是否补全
brotli/gzip 未生成文件 <10KB 不压缩属正常调整 threshold 或忽略
UnoCSS 类未生效safelist 或扫描路径缺失检查 uno.config.ts content.filesystem 与 safelist
hash 频繁全量变更公共 chunk 内容随业务改动确保 vue/guavaUI 等框架 chunk 不被业务代码污染

下一步 ​

构建通过后,参见 部署上线 发布到服务器。