152 lines
4.2 KiB
TypeScript
152 lines
4.2 KiB
TypeScript
import { fileURLToPath, URL } from 'node:url'
|
|
|
|
import { defineConfig, loadEnv } from 'vite'
|
|
import vue from '@vitejs/plugin-vue'
|
|
import vueJsx from '@vitejs/plugin-vue-jsx'
|
|
import UnoCSS from 'unocss/vite'
|
|
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
|
import VueRouter from 'unplugin-vue-router/vite'
|
|
import Layouts from 'vite-plugin-vue-layouts'
|
|
import AutoImport from 'unplugin-auto-import/vite'
|
|
import { VueRouterAutoImports } from 'unplugin-vue-router'
|
|
import Components from 'unplugin-vue-components/vite'
|
|
import vueI18n from '@intlify/unplugin-vue-i18n/vite'
|
|
import path from 'node:path'
|
|
import { compression } from 'vite-plugin-compression2'
|
|
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer'
|
|
import legacy from '@vitejs/plugin-legacy'
|
|
import { visualizer } from 'rollup-plugin-visualizer'
|
|
import vueDevTools from 'vite-plugin-vue-devtools'
|
|
|
|
// https://vite.dev/config/
|
|
export default defineConfig(({ mode }) => {
|
|
const env = loadEnv(mode, process.cwd(), 'VITE_')
|
|
// 如果你有其他场景判断,可修改此处,本文假设只针对生产环境
|
|
const isProd = mode === 'prod'
|
|
|
|
return {
|
|
build: {
|
|
outDir: 'dist',
|
|
assetsDir: 'assets',
|
|
assetsInlineLimit: 4096,
|
|
reportCompressedSize: true,
|
|
minify: 'terser',
|
|
cssCodeSplit: true,
|
|
sourcemap: !isProd,
|
|
terserOptions: isProd
|
|
? {
|
|
// 代码压缩配置
|
|
compress: {
|
|
drop_console: true, // 移除 console
|
|
drop_debugger: true, // 移除 debugger
|
|
},
|
|
// 代码混淆配置
|
|
mangle: {
|
|
toplevel: true, // 混淆顶层变量名
|
|
eval: true, // 混淆 eval 中的变量
|
|
},
|
|
// 输出配置
|
|
format: {
|
|
comments: false,
|
|
},
|
|
}
|
|
: {},
|
|
olldownOptions: {
|
|
output: {
|
|
codeSplitting: {
|
|
groups: [
|
|
{
|
|
name: 'vue',
|
|
test: /node_modules[\\/]vue/,
|
|
priority: 20,
|
|
},
|
|
{
|
|
name: 'vue-router',
|
|
test: /node_modules[\\/]vue-router/,
|
|
priority: 15,
|
|
},
|
|
{
|
|
name: 'pinia',
|
|
test: /node_modules[\\/]pinia/,
|
|
priority: 10,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
plugins: [
|
|
VueRouter({}),
|
|
// ⚠️ Vue must be placed after VueRouter()
|
|
vue(),
|
|
vueJsx(),
|
|
UnoCSS(), // 配置 SVG 图标插件
|
|
createSvgIconsPlugin({
|
|
// SVG 图标目录
|
|
iconDirs: [fileURLToPath(new URL('./src/assets/icons', import.meta.url))],
|
|
// 生成的 symbol ID 格式
|
|
symbolId: 'icon-[dir]-[name]',
|
|
}),
|
|
Layouts({
|
|
layoutsDirs: 'src/layouts',
|
|
defaultLayout: 'default',
|
|
}),
|
|
AutoImport({
|
|
include: [
|
|
/\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
|
|
/\.vue$/,
|
|
/\.vue\?vue/, // .vue
|
|
/\.md$/, // .md
|
|
],
|
|
imports: ['vue', VueRouterAutoImports, 'pinia', '@vueuse/core'],
|
|
}),
|
|
Components({
|
|
deep: true,
|
|
directoryAsNamespace: false,
|
|
}),
|
|
vueI18n({
|
|
// 语言包目录
|
|
include: path.resolve(__dirname, './src/i18n/locales/**'),
|
|
// 开发模式下也启动编译时处理
|
|
runtimeOnly: false,
|
|
// 仅使用组合式 API
|
|
compositionOnly: true,
|
|
// 完整安装
|
|
fullInstall: true,
|
|
}),
|
|
// Gzip 压缩
|
|
compression({
|
|
algorithms: ['gzip'],
|
|
threshold: 10240, // 超过 10KB 的文件才压缩
|
|
deleteOriginalAssets: false, // 不删除原文件
|
|
}),
|
|
ViteImageOptimizer({
|
|
png: {
|
|
quality: 80,
|
|
},
|
|
jpeg: {
|
|
quality: 80,
|
|
},
|
|
webp: {
|
|
quality: 80,
|
|
},
|
|
}),
|
|
legacy({
|
|
targets: ['defaults', 'not IE 11'],
|
|
}),
|
|
visualizer({
|
|
filename: 'stats.html',
|
|
}),
|
|
vueDevTools(),
|
|
],
|
|
resolve: {
|
|
alias: {
|
|
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
|
},
|
|
},
|
|
optimizeDeps: {
|
|
include: ['vue', 'vue-router', 'pinia', '@vueuse/core'],
|
|
},
|
|
}
|
|
})
|