Vite 插件与构建分析
📦 Vite 插件与 Rollup 插件 API 兼容。理解构建产物分析能让你准确切入优化点。
Vite 插件框架
// 自定义插件示例
import type { Plugin } from 'vite'
function myPlugin(): Plugin {
return {
name: 'my-plugin',
// 构建开始
buildStart() {
console.log('构建开始')
},
// 转换单个模块
transform(code, id) {
if (!id.endsWith('.vue')) return
return code.replace(/debug:/g, 'console.log:')
},
// 路径解析
resolveId(id) {
if (id === 'virtual:my-module') {
return '\0virtual:my-module'
}
},
// 加载虚拟模块
load(id) {
if (id === '\0virtual:my-module') {
return `export const data = ${JSON.stringify(fetchData())}`
}
},
// 修改 HTML
transformIndexHtml(html) {
return html.replace('<title>App</title>', '<title>My App</title>')
}
}
}
常用内置配置
// vite.config.ts
export default defineConfig({
build: {
// 指定入口
rollupOptions: {
input: {
main: 'index.html',
admin: 'admin.html'
},
output: {
// 手动分包
manualChunks: {
vendor: ['react', 'react-dom'],
utils: ['lodash', 'date-fns']
},
// 输出文件命名
chunkFileNames: 'assets/[name]-[hash].js',
assetFileNames: 'assets/[name]-[hash][extname]'
}
},
// 超过指定大小报警
chunkSizeWarningLimit: 500,
}
})
构建产物分析
rollup-plugin-visualizer
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [
visualizer({
open: true, // 构建后自动打开
gzipSize: true, // 显示 gzip 大小
brotliSize: true, // 显示 brotli 大小
filename: 'dist/stats.html'
})
]
})
分析要点
| 问题 | 表现 | 解决方式 |
|---|---|---|
| 依赖过大 | 单个 chunk > 500KB | 按需加载或 CDN |
| 重复依赖 | 同一库被多个 chunk 包含 | manualChunks 合并 |
| 未使用代码 | bundle 包含未导入模块 | Tree Shaking 检查 |
| 图片过大 | 原始图片 > 100KB | 将大图移到 CDN |
Tree Shaking 调试
// 检查是否有副作用
package.json:
{
"sideEffects": false // 告知构建工具所有模块都无副作用
// "sideEffects": ["*.css", "src/polyfills.ts"]
}
// 常见破坏 Tree Shaking 的情况:
// 1. 使用 require() 而非 ES Module
// 2. 模块内有副作用但没有声明
// 3. Babel 将 import 转化为 require
常见插件
| 插件 | 用途 |
|---|---|
@vitejs/plugin-react | React + HMR |
vite-plugin-pwa | PWA + Service Worker |
vite-tsconfig-paths | tsconfig 路径别名 |
unplugin-auto-import | 自动导入 API |
unplugin-vue-components | Vue 组件自动导入 |
常见误区
- manualChunks 分包前没有分析实际包大小,導致过度分包反而增加请求数
- 插件顺序错误导致冲突,注意 vite-only 插件和 rollup 插件的阶段区分
- 构建分析没有包含 gzip 压缩大小,导致错误估算实际加载大小