|
|
// @ts-expect-error connect-history-api-fallback 未提供类型声明
|
|
|
import history from 'connect-history-api-fallback'
|
|
|
import path from 'node:path'
|
|
|
import { fileURLToPath } from 'node:url'
|
|
|
import { defineConfig, loadEnv } from 'vite'
|
|
|
import vue from '@vitejs/plugin-vue'
|
|
|
import { viteStaticCopy } from 'vite-plugin-static-copy'
|
|
|
import type { Plugin } from 'vite'
|
|
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
|
|
|
|
function resolveBuildOutDir(rawPath: string | undefined): string {
|
|
|
const configured = rawPath?.trim()
|
|
|
if (!configured) {
|
|
|
return path.resolve(__dirname, 'dist/admin')
|
|
|
}
|
|
|
|
|
|
return path.isAbsolute(configured)
|
|
|
? configured
|
|
|
: path.resolve(__dirname, configured)
|
|
|
}
|
|
|
|
|
|
function spaHistoryFallback(): Plugin {
|
|
|
const middleware = history({ index: '/index.html' })
|
|
|
const skipFrontendThenHistory = (
|
|
|
req: { url?: string },
|
|
|
res: unknown,
|
|
|
next: (err?: unknown) => void,
|
|
|
) => {
|
|
|
/** 勿把 Laravel public/frontend 原型页回退成 SPA,否则打开为空白壳 */
|
|
|
if ((req.url || '').startsWith('/frontend')) {
|
|
|
next()
|
|
|
return
|
|
|
}
|
|
|
middleware(req, res, next)
|
|
|
}
|
|
|
return {
|
|
|
name: 'spa-history-fallback',
|
|
|
configureServer(server) {
|
|
|
return () => {
|
|
|
server.middlewares.use(skipFrontendThenHistory)
|
|
|
}
|
|
|
},
|
|
|
configurePreviewServer(server) {
|
|
|
return () => {
|
|
|
server.middlewares.use(skipFrontendThenHistory)
|
|
|
}
|
|
|
},
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// https://vite.dev/config/
|
|
|
export default defineConfig(({ mode }) => {
|
|
|
const env = loadEnv(mode, __dirname, '')
|
|
|
const adminOutDir = resolveBuildOutDir(env.FRONTEND_BUILD_OUT_DIR)
|
|
|
const laravelProxyTarget = (env.LARAVEL_DEV_URL || 'http://127.0.0.1:8002').replace(/\/$/, '')
|
|
|
const laravelDevProxy = {
|
|
|
'/api': {
|
|
|
target: laravelProxyTarget,
|
|
|
changeOrigin: true,
|
|
|
},
|
|
|
/** 登录页快捷入口等静态原型(layout / pages),需代理到 backend/public/frontend */
|
|
|
'/frontend': {
|
|
|
target: laravelProxyTarget,
|
|
|
changeOrigin: true,
|
|
|
},
|
|
|
'/storage': {
|
|
|
target: laravelProxyTarget,
|
|
|
changeOrigin: true,
|
|
|
},
|
|
|
} as const
|
|
|
|
|
|
return {
|
|
|
base: mode === 'production' ? '/admin/' : '/',
|
|
|
build: {
|
|
|
outDir: adminOutDir,
|
|
|
emptyOutDir: true,
|
|
|
},
|
|
|
plugins: [
|
|
|
vue(),
|
|
|
spaHistoryFallback(),
|
|
|
/** 勿在 dev 对 /frontend/prototype 挂 sirv:会与 import prototype.css 冲突(返回 text/css 导致动态 import .vue 失败) */
|
|
|
viteStaticCopy({
|
|
|
targets: [
|
|
|
{
|
|
|
src: 'frontend/prototype/**/*',
|
|
|
dest: 'frontend/prototype',
|
|
|
rename: { stripBase: 2 },
|
|
|
},
|
|
|
],
|
|
|
}),
|
|
|
],
|
|
|
server: {
|
|
|
open: '/',
|
|
|
proxy: { ...laravelDevProxy },
|
|
|
},
|
|
|
preview: {
|
|
|
proxy: { ...laravelDevProxy },
|
|
|
},
|
|
|
}
|
|
|
})
|