260 lines
8.4 KiB
TypeScript
260 lines
8.4 KiB
TypeScript
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,
|
||
},
|
||
},
|
||
},
|
||
});
|