Files
hfb_sys/frontend/vite.config.ts
T
2026-07-25 16:31:42 +08:00

125 lines
3.6 KiB
TypeScript

import { fileURLToPath, URL } from 'node:url'
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { VantResolver } from '@vant/auto-import-resolver'
function elementPlusChunk(id: string) {
const normalized = id.replace(/\\/g, '/')
if (normalized.includes('@element-plus/icons-vue')) {
return 'vendor-element-plus-icons'
}
const componentMatch = normalized.match(/element-plus\/es\/components\/([^/]+)/)
if (!componentMatch) return undefined
const component = componentMatch[1]
if (
[
'table',
'table-column',
'form',
'form-item',
'select',
'option',
'input-number',
'date-picker',
'time-picker',
].includes(component)
) {
return 'vendor-element-plus-data-entry'
}
return undefined
}
function stripVantRemoteIconFont() {
return {
name: 'strip-vant-remote-icon-font',
generateBundle(_options, bundle) {
for (const chunk of Object.values(bundle)) {
if (chunk.type !== 'asset' || typeof chunk.source !== 'string') continue
if (!chunk.fileName.endsWith('.css')) continue
// Vant 图标字体已经内联了 woff2,这里去掉远程 woff 备用地址,避免触发 CSP 外链字体拦截。
chunk.source = chunk.source.replace(
/,url\(\/\/at\.alicdn\.com\/t\/c\/font_2553510_ciljc7axaw7\.woff\?t=1705587463221\) format\("woff"\)/g,
''
)
}
},
}
}
const frontendPort = Number(process.env.DEV_FRONTEND_PORT || process.env.PORT || 5189)
const backendPort = Number(process.env.DEV_BACKEND_PORT || 18088)
const apiProxyTarget = process.env.VITE_API_PROXY_TARGET || `http://127.0.0.1:${backendPort}`
export default defineConfig({
// 禁止 vite 清屏,避免把后端启动日志(GIN 路由、迁移等)从终端滚动缓冲里抹掉
clearScreen: false,
plugins: [
vue(),
stripVantRemoteIconFont(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
dirs: ['src/components'],
deep: true,
dts: 'components.d.ts',
syncMode: 'overwrite',
resolvers: [ElementPlusResolver(), VantResolver()],
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
port: frontendPort,
strictPort: true,
proxy: {
'/api': apiProxyTarget,
},
allowedHosts: [
'221329.cc.cd',
'd4aa-77-93-89-84.ngrok-free.app',
'frp-bus.com',
'www.u499731.nyat.app',
'fn.221329.xyz',
],
},
build: {
rollupOptions: {
onwarn(warning, warn) {
const isVueusePureWarning =
warning.message.includes('#__PURE__') &&
typeof warning.id === 'string' &&
warning.id.includes('node_modules/@vueuse/core/')
if (isVueusePureWarning) return
warn(warning)
},
output: {
manualChunks(id) {
if (!id.includes('node_modules')) return
if (id.includes('element-plus') || id.includes('@element-plus')) {
return elementPlusChunk(id)
}
if (id.includes('vant') || id.includes('@vant')) {
return 'vendor-vant'
}
if (id.includes('vue') || id.includes('pinia')) {
return 'vendor-vue'
}
if (id.includes('axios')) {
return 'vendor-axios'
}
return 'vendor'
},
},
},
},
})