front/vite.config.ts
2025-12-03 19:26:02 +08:00

260 lines
8.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.

import { resolve } from 'path';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import svgLoader from 'vite-svg-loader';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import UnoCSS from 'unocss/vite';
import configArcoStyleImportPlugin from './config/plugin/arcoStyleImport';
import configCompressPlugin from './config/plugin/compress';
export default defineConfig({
server: {
open: true,
fs: {
strict: true,
},
historyApiFallback: true,
proxy: {
// 对应 nginx: location /api/trackApi -> http://43.139.210.35:8889
'/api/trackApi': {
target: 'http://43.139.210.35:8889',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/trackApi/, ''),
configure: (proxy, options) => {
proxy.on('error', (err, req, res) => {
console.log('proxy error', err);
});
proxy.on('proxyReq', (proxyReq, req, res) => {
console.log('[trackApi-8889] Sending Request to the Target:', req.method, req.url);
});
proxy.on('proxyRes', (proxyRes, req, res) => {
console.log(
'[trackApi-8889] Received Response from the Target:',
proxyRes.statusCode,
req.url
);
});
},
},
// SimpleAdmin 服务代理 - http://43.139.210.35:5566
// 需要放在 /api 之前,因为路径匹配是从上到下的
'/api/userCenter': {
target: 'http://43.139.210.35:5566',
changeOrigin: true,
// SimpleAdmin 后端路径是 /userCenter/xxx,所以需要去掉 /api 前缀
rewrite: (path) => path.replace(/^\/api/, ''),
timeout: 30000,
proxyTimeout: 30000,
configure: (proxy, options) => {
proxy.on('proxyReq', (proxyReq, req, res) => {
console.log('[SimpleAdmin-5566-userCenter] Sending Request:', req.method, req.url);
console.log('[SimpleAdmin-5566-userCenter] Proxy Target:', proxyReq.path);
});
proxy.on('proxyRes', (proxyRes, req, res) => {
console.log(
'[SimpleAdmin-5566-userCenter] Received Response:',
proxyRes.statusCode,
req.url
);
});
},
},
'/api/sys': {
target: 'http://43.139.210.35:5566',
changeOrigin: true,
// SimpleAdmin 后端路径是 /sys/xxx,所以需要去掉 /api 前缀
rewrite: (path) => path.replace(/^\/api/, ''),
timeout: 30000,
proxyTimeout: 30000,
configure: (proxy, options) => {
proxy.on('proxyReq', (proxyReq, req, res) => {
console.log('[SimpleAdmin-5566-sys] Sending Request:', req.method, req.url);
console.log('[SimpleAdmin-5566-sys] Proxy Target:', proxyReq.path);
});
proxy.on('proxyRes', (proxyRes, req, res) => {
console.log(
'[SimpleAdmin-5566-sys] Received Response:',
proxyRes.statusCode,
req.url
);
});
},
},
// 对应 nginx: location /api -> http://43.139.210.35:8888
// 注意:更具体的路径(如 /api/userCenter, /api/sys)已经在上面配置
'/api': {
target: 'http://43.139.210.35:8888',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
timeout: 30000,
proxyTimeout: 30000,
configure: (proxy, options) => {
proxy.on('proxyReq', (proxyReq, req, res) => {
console.log('[8888] Sending Request:', req.method, req.url);
console.log('[8888] Proxy Target:', proxyReq.path);
});
proxy.on('proxyRes', (proxyRes, req, res) => {
console.log(
'[8888] Received Response:',
proxyRes.statusCode,
req.url
);
});
},
},
},
},
plugins: [
// eslint({
// cache: false,
// include: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.vue'],
// exclude: ['node_modules'],
// }),
vue(),
vueJsx(),
svgLoader({ svgoConfig: {} }),
configArcoStyleImportPlugin(),
UnoCSS(),
AutoImport({
imports: ['vue', 'vue-router', 'vue-i18n', 'pinia', '@vueuse/core'],
dts: 'src/auto-imports.d.ts',
dirs: ['src/composables', 'src/store'],
vueTemplate: true,
eslintrc: {
enabled: true,
},
}),
Components({
extensions: ['vue'],
include: [/\.vue$/, /\.vue\?vue/],
dts: 'src/components.d.ts',
dirs: ['src/components'],
resolvers: [],
// directoryAsNamespace: true,
}),
// 生产环境启用gzip压缩
...(process.env.NODE_ENV === 'production' ? configCompressPlugin('gzip') : []),
],
resolve: {
alias: [
{
find: '@',
replacement: resolve(__dirname, './src'),
},
{
find: 'assets',
replacement: resolve(__dirname, './src/assets'),
},
{
find: 'vue-i18n',
replacement: 'vue-i18n/dist/vue-i18n.cjs.js', // Resolve the i18n warning issue
},
{
find: 'vue',
replacement: 'vue/dist/vue.esm-bundler.js', // compile template
},
{
find: 'xe-utils',
replacement: resolve(
__dirname,
'./node_modules/.pnpm/xe-utils@3.7.5/node_modules/xe-utils'
), // Add xe-utils alias
},
],
extensions: ['.ts', '.js'],
},
define: {
'process.env': {},
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
__VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: 'false',
},
optimizeDeps: {
include: ['monaco-editor', 'vue', 'vue-router', 'pinia'],
// 确保 Vue 相关依赖的预构建顺序
esbuildOptions: {
target: 'es2015',
},
},
build: {
// 启用压缩(使用esbuild,Vite默认,性能更好)
minify: 'esbuild',
// 生产环境移除console和debugger
esbuild: {
drop: process.env.NODE_ENV === 'production' ? ['console', 'debugger'] : [],
},
// 启用CSS代码分割
cssCodeSplit: true,
// 生成source map(可选,生产环境可以关闭以减小体积)
sourcemap: false,
// 构建输出配置
rollupOptions: {
output: {
// 手动代码分割,优化缓存
manualChunks: (id) => {
// node_modules中的包单独打包
if (id.includes('node_modules')) {
// vue核心库和vue相关库打包在一起,确保加载顺序
if (id.includes('vue') || id.includes('vue-router') || id.includes('pinia') || id.includes('@vue')) {
return 'vue-vendor';
}
// monaco-editor单独打包
if (id.includes('monaco-editor')) {
return 'monaco-editor';
}
// arco-design相关
if (id.includes('@arco-design')) {
return 'arco-vendor';
}
// echarts相关
if (id.includes('echarts')) {
return 'echarts-vendor';
}
// vxe-table相关
if (id.includes('vxe-table')) {
return 'vxe-vendor';
}
// 其他第三方库
return 'vendor';
}
},
// 确保文件名包含hash,便于浏览器缓存
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: (assetInfo) => {
const info = assetInfo.name.split('.');
const ext = info[info.length - 1];
if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/i.test(assetInfo.name)) {
return `assets/media/[name]-[hash].${ext}`;
}
if (/\.(png|jpe?g|gif|svg|webp|avif)(\?.*)?$/.test(assetInfo.name)) {
return `assets/img/[name]-[hash].${ext}`;
}
if (/\.(woff2?|eot|ttf|otf)(\?.*)?$/i.test(assetInfo.name)) {
return `assets/fonts/[name]-[hash].${ext}`;
}
return `assets/[name]-[hash].${ext}`;
},
},
},
// 设置chunk大小警告限制
chunkSizeWarningLimit: 1000,
},
css: {
preprocessorOptions: {
less: {
modifyVars: {
hack: `true; @import (reference) "${resolve(
'./src/assets/style/breakpoint.less'
)}";`,
},
javascriptEnabled: true,
},
},
},
});