Files
mokeegateway/mokee-gateway-web/vite.config.ts
2026-07-15 23:18:24 +08:00

82 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Vite 构建配置文件
*
* 核心职责:
* 1. Element Plus 按需加载 — 通过 unplugin-vue-components 自动解析组件,无需手动 import
* 2. 分包策略 — 将 node_modules 拆分为独立 chunk区分基础组件与后台组件
* 3. 首屏优化 — 去除 Element Plus modulepreload 标签,避免登录页加载后台 JS/CSS
*
* 分包设计:
* - echarts: 单独打包,仪表盘页按需加载
* - vue-vendor: Vue/Router/Pinia 核心框架,长期缓存
* - el-admin: 后台管理页的 Element Plus 组件,进后台后一次性加载
* - 基础组件button/input/icon等: 不单独分包,保持独立小 chunk供 login/select 页面按需加载
*/
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// login/select 页面用到的 Element Plus 基础组件,保持独立不打包进 el-admin
// 这些组件体积小、首屏即用,独立分包可避免登录页下载后台才用的 JS
const EL_BASE = [
'button', 'input', 'form', 'form-item',
'icon', 'avatar', 'empty',
'message', 'notification', 'loading',
'popper', 'tooltip', 'overlay', 'config-provider',
'scrollbar', 'focus-trap', 'collection',
]
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [ElementPlusResolver({ importStyle: 'css' })],
dts: 'src/types/components.d.ts',
}),
// 去掉 Element Plus 预加载:登录/选系统页不预下载后台才用的 JS/CSS
// 原理Vite 默认会对所有动态 import 的模块生成 <link rel="modulepreload"> 标签
// Element Plus 按需加载时也会被预加载,导致首屏下载大量无用 JS
// 本插件在构建 HTML 时去除这些标签,让组件在真正使用时才加载
{
name: 'strip-el-preloads',
transformIndexHtml(html) {
// 去掉所有 modulepreloadElement Plus 组件全部按需加载)
html = html.replace(/<link rel="modulepreload"[^>]*>/g, '')
// 去掉 el-admin CSS后台组件样式login/select 不需要)
html = html.replace(/<link[^>]*el-admin[^>]*>/g, '')
return html
},
},
],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
server: {
port: 31001,
},
build: {
target: 'es2015',
cssTarget: 'chrome61',
rollupOptions: {
output: {
manualChunks(id) {
// ECharts 体积大(~1MB独立分包仅在仪表盘页面才动态加载
if (id.includes('node_modules/echarts')) return 'echarts'
// Vue 核心框架长期不变,独立分包以获得最佳缓存命中率
if (id.includes('node_modules/vue') || id.includes('node_modules/vue-router') || id.includes('node_modules/pinia')) return 'vue-vendor'
if (id.includes('node_modules/element-plus')) {
// 基础组件保持独立小 chunklogin/select 页面按需加载),不打包进 el-admin
if (EL_BASE.some(c => id.includes(`/${c}/`) || id.includes(`/${c}.`) || id.endsWith(`/${c}`))) return
// 管理后台组件打成一个 el-admin chunk进后台一次性加载减少后续页面切换的网络请求
return 'el-admin'
}
},
},
},
},
})