128 lines
3.8 KiB
TypeScript
128 lines
3.8 KiB
TypeScript
import { fileURLToPath, URL } from 'node:url'
|
||
import { loadEnv, defineConfig, ConfigEnv } from 'vite'
|
||
import type { UserConfig } from 'vite'
|
||
import vue from '@vitejs/plugin-vue'
|
||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||
import basicSsl from '@vitejs/plugin-basic-ssl'
|
||
|
||
// 自动导入插件
|
||
import AutoImport from 'unplugin-auto-import/vite'
|
||
import Components from 'unplugin-vue-components/vite'
|
||
|
||
// Element Plus 组件自动导入
|
||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||
|
||
// 自定义插件:修复 face-api.js 模型文件的 MIME 类型
|
||
function faceModelsMimeTypePlugin() {
|
||
return {
|
||
name: 'face-models-mime-type',
|
||
configureServer(server) {
|
||
server.middlewares.use((req, res, next) => {
|
||
const url = req.url || ''
|
||
if (url.includes('.shard1') || url.includes('.shard2')) {
|
||
res.setHeader('Content-Type', 'application/wasm')
|
||
} else if (url.includes('.weights_manifest.json')) {
|
||
res.setHeader('Content-Type', 'application/json')
|
||
}
|
||
next()
|
||
})
|
||
},
|
||
}
|
||
}
|
||
|
||
// https://vite.dev/config/
|
||
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
|
||
const isProduction = mode === 'production'
|
||
const env = loadEnv(mode, process.cwd())
|
||
return {
|
||
// 解决 face-api.js 模型文件 MIME 类型问题
|
||
assetsInclude: ['**/*.shard1', '**/*.shard2', '**/*.weights_manifest.json'],
|
||
esbuild: {
|
||
drop: isProduction ? ['console', 'debugger'] : [],
|
||
// minifyIdentifiers: true,
|
||
minifySyntax: true,
|
||
minifyWhitespace: true,
|
||
},
|
||
plugins: [
|
||
vue(),
|
||
// 生产环境移除 devTools 插件(减少产物体积)
|
||
...(!isProduction ? [vueDevTools()] : []),
|
||
// face-api.js 模型文件 MIME 类型修复插件
|
||
faceModelsMimeTypePlugin(),
|
||
AutoImport({
|
||
resolvers: [ElementPlusResolver()],
|
||
imports: ['vue', 'vue-router', 'pinia', '@vueuse/core'],
|
||
dts: 'src/auto-imports.d.ts',
|
||
eslintrc: { enabled: true },
|
||
}),
|
||
Components({
|
||
resolvers: [ElementPlusResolver()],
|
||
dts: 'src/components.d.ts',
|
||
dirs: ['src/components'],
|
||
}),
|
||
basicSsl(),
|
||
],
|
||
resolve: {
|
||
alias: {
|
||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||
},
|
||
},
|
||
|
||
// ====== 增强版生产构建配置 ======
|
||
build: {
|
||
outDir: 'dist',
|
||
assetsDir: 'assets',
|
||
|
||
// 生产环境 sourcemap 配置(可选:隐藏源码但保留行映射)
|
||
sourcemap: isProduction ? 'hidden' : true,
|
||
|
||
// chunk 分割策略(优化加载性能)
|
||
rollupOptions: {
|
||
output: {
|
||
manualChunks: {
|
||
// 将第三方库单独分包
|
||
'element-plus': ['element-plus', '@element-plus/icons-vue'],
|
||
vendor: ['vue', 'vue-router', 'pinia'],
|
||
utils: ['axios', 'dayjs', 'crypto-js', '@vueuse/core'],
|
||
},
|
||
// 文件名带 hash(缓存优化)
|
||
chunkFileNames: 'assets/js/[name]-[hash].js',
|
||
entryFileNames: 'assets/js/[name]-[hash].js',
|
||
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
|
||
},
|
||
},
|
||
|
||
// 压缩配置
|
||
minify: 'esbuild',
|
||
|
||
// 大文件警告阈值(默认500KB,可调整)
|
||
chunkSizeWarningLimit: 1000,
|
||
},
|
||
|
||
// 生产环境不显示错误遮罩
|
||
define: {
|
||
__VUE_PROD_DEVTOOLS__: 'false',
|
||
},
|
||
|
||
server: {
|
||
host: true,
|
||
port: 9999,
|
||
open: true,
|
||
https: {},
|
||
proxy: {
|
||
'/api': {
|
||
target: env.VITE_API_BASE_URL,
|
||
changeOrigin: true,
|
||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||
},
|
||
// 将 /config.json 代理到 h5 域名,避免开发环境跨域
|
||
'/config.json': {
|
||
target: env.VITE_EXE_DOWNLOAD_BASE_URL || env.VITE_UPDATE_URL,
|
||
changeOrigin: true,
|
||
secure: true,
|
||
},
|
||
},
|
||
},
|
||
}
|
||
})
|