Files
eacp_webapp/vite.config.js
T
2026-07-24 18:09:36 +08:00

150 lines
4.2 KiB
JavaScript

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const cesiumSource = path.join(__dirname, 'node_modules', 'cesium', 'Build', 'Cesium')
const modelSource = path.join(__dirname, 'model')
function copyDir(source, target) {
fs.mkdirSync(target, { recursive: true })
for (const entry of fs.readdirSync(source, { withFileTypes: true })) {
const sourcePath = path.join(source, entry.name)
const targetPath = path.join(target, entry.name)
if (entry.isDirectory()) {
copyDir(sourcePath, targetPath)
} else {
fs.copyFileSync(sourcePath, targetPath)
}
}
}
function cesiumAssetsPlugin() {
let outDir = path.join(__dirname, 'wwwroot')
const serveStatic = (root, req, res, next) => {
const urlPath = decodeURIComponent((req.url || '').split('?')[0]).replace(/^\/+/, '')
const filePath = path.normalize(path.join(root, urlPath))
if (!filePath.startsWith(root) || !fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
next()
return
}
const contentType = filePath.endsWith('.js') ? 'application/javascript' :
filePath.endsWith('.css') ? 'text/css' :
filePath.endsWith('.json') ? 'application/json' :
filePath.endsWith('.glb') ? 'model/gltf-binary' :
'application/octet-stream'
res.setHeader('Content-Type', contentType)
fs.createReadStream(filePath).pipe(res)
}
return {
name: 'ecap-cesium-assets',
configResolved(config) {
outDir = path.isAbsolute(config.build.outDir) ? config.build.outDir : path.join(config.root, config.build.outDir)
},
configureServer(server) {
server.middlewares.use('/ui/cesium', (req, res, next) => {
serveStatic(cesiumSource, req, res, next)
})
server.middlewares.use('/ui/model', (req, res, next) => {
serveStatic(modelSource, req, res, next)
})
},
closeBundle() {
copyDir(cesiumSource, path.join(outDir, 'cesium'))
copyDir(modelSource, path.join(outDir, 'model'))
}
}
}
const spaAliasPaths = new Set([
'/map',
'/map3d',
'/dsp',
'/aircraftlist',
'/settings',
'/ui/map',
'/ui/map3d',
'/ui/dsp',
'/ui/aircraftlist',
'/ui/settings'
])
function spaAliasesPlugin() {
return {
name: 'ecap-spa-aliases',
configureServer(server) {
server.middlewares.use(async (req, res, next) => {
const urlPath = decodeURIComponent((req.url || '').split('?')[0])
if (!spaAliasPaths.has(urlPath)) {
next()
return
}
try {
const indexPath = path.join(__dirname, 'index.html')
let html = fs.readFileSync(indexPath, 'utf-8')
html = await server.transformIndexHtml('/ui/index.html', html)
res.statusCode = 200
res.setHeader('Content-Type', 'text/html')
res.end(html)
} catch (error) {
next(error)
}
})
}
}
}
// https://vite.dev/config/
export default defineConfig({
base: '/ui/',
publicDir: 'public', // 默认就是 public
define: {
CESIUM_BASE_URL: JSON.stringify('/ui/cesium/')
},
plugins: [react(), cesiumAssetsPlugin(), spaAliasesPlugin()],
server: {
proxy: {
'/map/imagery': {
target: 'http://127.0.0.1',
changeOrigin: true,
},
'/map/terrain': {
target: 'http://127.0.0.1',
changeOrigin: true,
},
'/map/resources': {
target: 'http://127.0.0.1',
changeOrigin: true,
},
'/map/graphics': {
target: 'http://127.0.0.1',
changeOrigin: true,
},
'/map/view': {
target: 'http://127.0.0.1',
changeOrigin: true,
},
'/tiles': {
target: 'http://127.0.0.1',
changeOrigin: true,
},
'/api': {
target: 'http://127.0.0.1',
changeOrigin: true,
},
'/ws': {
target: 'http://127.0.0.1', // drogon 的端口!!
ws: true, // ☆ 必须 ☆
changeOrigin: true
},
'/aircraftlist.json': {
target: 'http://127.0.0.1'
},
},
fs:{
strict: false
}
},
build: {
outDir: 'wwwroot'
}
})