feat: 增强情绪博物馆项目功能 - 新增用户评论和帖子功能,优化前端架构和WebSocket通信 - 更新文档和部署配置
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
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'
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user