Files
happy-life-star/web-new/vite.config.ts
T

224 lines
5.5 KiB
TypeScript

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { VitePWA } from 'vite-plugin-pwa'
import { visualizer } from 'rollup-plugin-visualizer'
import viteCompression from 'vite-plugin-compression'
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
// https://vitejs.dev/config/
export default defineConfig(({ mode, command }) => {
const isProduction = mode === 'production'
const isAnalyze = mode === 'analyze'
return {
base: isProduction ? '/emotion-museum/' : '/',
plugins: [
vue(),
// 自动导入
AutoImport({
imports: [
'vue',
'vue-router',
'pinia',
'@vueuse/core',
{
'vue-i18n': ['useI18n']
}
],
resolvers: [ElementPlusResolver()],
dts: true,
eslintrc: {
enabled: true
}
}),
// 组件自动导入
Components({
resolvers: [ElementPlusResolver()],
dts: true
}),
// PWA支持
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.ico', 'apple-touch-icon.png'],
manifest: {
name: '情绪博物馆',
short_name: '情绪博物馆',
description: '记录情绪,分享心情的温暖空间',
theme_color: '#4A90E2',
background_color: '#ffffff',
display: 'standalone',
icons: [
{
src: 'pwa-192x192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png'
}
]
},
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg}']
}
}),
// 国际化支持
VueI18nPlugin({
include: resolve(__dirname, './src/i18n/locales/**')
}),
// Gzip压缩(仅生产环境)
isProduction && viteCompression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: 'gzip',
ext: '.gz'
}),
// 构建分析(仅分析模式)
isAnalyze && visualizer({
filename: 'dist/stats.html',
open: true,
gzipSize: true,
brotliSize: true
})
].filter(Boolean),
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'~': resolve(__dirname, 'src')
}
},
define: {
global: 'globalThis',
__VUE_I18N_FULL_INSTALL__: true,
__VUE_I18N_LEGACY_API__: false,
__INTLIFY_PROD_DEVTOOLS__: false
},
server: {
port: 5173,
open: true,
proxy: {
'/api': {
target: 'http://localhost:19089',
changeOrigin: true,
secure: false
},
'/ws': {
target: 'ws://localhost:19089',
ws: true,
changeOrigin: true
}
}
},
build: {
outDir: 'dist',
sourcemap: !isProduction,
minify: isProduction ? 'terser' : false,
terserOptions: isProduction ? {
compress: {
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log', 'console.info', 'console.debug']
},
mangle: {
safari10: true
}
} : {},
rollupOptions: {
external: (id) => {
if (id.includes('echarts') && id.includes('extension')) {
return true
}
return false
},
output: {
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: (assetInfo) => {
const fileName = assetInfo.name || 'asset'
const info = fileName.split('.')
const ext = info[info.length - 1]
if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)$/.test(fileName)) {
return `media/[name]-[hash].${ext}`
}
if (/\.(png|jpe?g|gif|svg|webp|ico)$/.test(fileName)) {
return `images/[name]-[hash].${ext}`
}
if (/\.(woff2?|eot|ttf|otf)$/.test(fileName)) {
return `fonts/[name]-[hash].${ext}`
}
return `assets/[name]-[hash].${ext}`
},
manualChunks: (id) => {
// 第三方库分包
if (id.includes('node_modules')) {
if (id.includes('vue') || id.includes('pinia') || id.includes('vue-router')) {
return 'vue-vendor'
}
if (id.includes('element-plus')) {
return 'element-plus'
}
if (id.includes('echarts')) {
return 'echarts'
}
if (id.includes('lodash') || id.includes('dayjs') || id.includes('axios')) {
return 'utils'
}
return 'vendor'
}
// 业务模块分包
if (id.includes('/src/views/')) {
const pathSegments = id.split('/src/views/')[1].split('/')
if (pathSegments.length > 1) {
return `pages-${pathSegments[0]}`
}
}
if (id.includes('/src/components/')) {
return 'components'
}
}
}
},
// 构建性能优化
chunkSizeWarningLimit: 1000,
reportCompressedSize: !isProduction,
// 目标浏览器
target: ['es2015', 'chrome63', 'firefox67', 'safari12']
},
optimizeDeps: {
include: [
'vue',
'vue-router',
'pinia',
'element-plus',
'echarts',
'vue-echarts',
'@vueuse/core',
'dayjs',
'lodash-es'
]
}
}
})