优化Vue 3 + Vite项目中@vue与vuetify/lib的打包体积
Vue3 + Vuetify3 打包体积优化问题解答
问题概况
- 技术栈:Vue 3.2.45、Vite 4.0.4、Vuetify 3.1.4、vite-plugin-vuetify 1.0.1
- 打包问题:node_modules总大小约900kB(gzip后245kB),
@vue相关包占比偏高;已开启Tree Shaking,src目录代码优化生效,但vuetify/lib仍包含全部组件,不确定是否正常。
当前配置代码
vite.config.ts
import { fileURLToPath, URL } from 'url' import type { PluginOption } from 'vite' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { version } from './package.json' import vuetify from 'vite-plugin-vuetify' import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' import { dirname, resolve } from 'node:path' import { visualizer } from 'rollup-plugin-visualizer' export default defineConfig({ base: './', plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.includes('xx-'), }, }, }), vuetify(), VueI18nPlugin({ /* options */ // locale messages resource pre-compile option include: resolve(dirname(fileURLToPath(import.meta.url)), './locales/**'), }), visualizer({ template: 'treemap', // or sunburst open: true, gzipSize: true, brotliSize: true, }) as PluginOption, ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, build: { rollupOptions: { output: { entryFileNames: `something.js`, chunkFileNames: `something.js`, assetFileNames: `assets/something.[ext]`, }, }, }, })
vuetify.ts
import { createVuetify } from 'vuetify' export default createVuetify()
main.ts
import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import vuetify from '@/plugins/vuetify' import VueDOMPurifyHTML from 'vue-dompurify-html' const app = createApp(App) const pinia = createPinia() app.use(pinia) app.use(vuetify) app.use(VueDOMPurifyHTML) app.mount('#app')
打包体积分析图

问题解决与说明
1. vuetify/lib包含全量组件的问题
这不是预期行为,vite-plugin-vuetify默认会开启Tree Shaking,自动导入仅用到的组件和样式。按以下步骤修复:
显式配置自动导入
修改vite.config.ts中的vuetify插件配置,确保自动导入逻辑生效:vuetify({ autoImport: true, }),修正Vuetify初始化代码
补充样式导入,确保按需加载基础样式:import { createVuetify } from 'vuetify' import 'vuetify/styles' export default createVuetify()自动导入生效后,无需手动声明组件,插件会根据模板中使用的组件自动导入对应代码。
检查版本兼容性
运行npm list vuetify vite-plugin-vuetify确认版本无冲突,若存在依赖问题,更新vite-plugin-vuetify到最新兼容版本。
2. @vue打包体积偏大的问题
启用更优压缩
在vite.config.ts的build选项中配置terser压缩,比默认esbuild压缩效果更好:build: { minify: 'terser', rollupOptions: { output: { entryFileNames: `something.js`, chunkFileNames: `something.js`, assetFileNames: `assets/something.[ext]`, }, }, },拆分Vue生态公共模块
通过Rollup配置将Vue、Pinia等核心包拆分为单独chunk,利用浏览器缓存:rollupOptions: { output: { entryFileNames: `something.js`, chunkFileNames: `something.js`, assetFileNames: `assets/something.[ext]`, manualChunks: { vue: ['vue', 'pinia'], }, }, },确保使用Vue Runtime版本
若项目仅使用单文件组件,无需包含模板编译器,显式指定runtime版本:resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), 'vue': 'vue/dist/vue.runtime.esm-bundler.js', }, },
验证优化效果
修改配置后重新执行构建命令,通过rollup-plugin-visualizer查看:
vuetify/lib应仅包含项目实际使用的组件@vue相关体积会有明显下降
内容的提问来源于stack exchange,提问作者lando
相关产品推荐
相关产品推荐

