232 lines
7.4 KiB
JavaScript
232 lines
7.4 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')
|
|
const adminiveFrontend = path.join(__dirname, '..', 'Adminive', 'frontend')
|
|
const amisSdkSource = path.join(adminiveFrontend, 'node_modules', 'amis', 'sdk')
|
|
const amisPackage = JSON.parse(fs.readFileSync(path.join(adminiveFrontend, 'node_modules', 'amis', 'package.json'), 'utf8'))
|
|
const amisSdkUrlPrefix = `/ui/vendor/amis/${amisPackage.version}/`
|
|
function amisContentType(fileName) {
|
|
const extension = path.extname(fileName).toLowerCase()
|
|
if (extension === '.css') return 'text/css; charset=utf-8'
|
|
if (extension === '.js') return 'text/javascript; charset=utf-8'
|
|
if (extension === '.json') return 'application/json; charset=utf-8'
|
|
if (extension === '.svg') return 'image/svg+xml'
|
|
if (extension === '.woff') return 'font/woff'
|
|
if (extension === '.woff2') return 'font/woff2'
|
|
if (extension === '.ttf') return 'font/ttf'
|
|
return 'application/octet-stream'
|
|
}
|
|
function serveAmisSdk(server) {
|
|
server.middlewares.use((request, response, next) => {
|
|
const pathname = new URL(request.url || '/', 'http://localhost').pathname
|
|
if (!pathname.startsWith(amisSdkUrlPrefix)) {
|
|
next()
|
|
return
|
|
}
|
|
const relativePath = decodeURIComponent(pathname.slice(amisSdkUrlPrefix.length))
|
|
const sourcePath = path.resolve(amisSdkSource, relativePath)
|
|
if (sourcePath !== amisSdkSource && !sourcePath.startsWith(`${amisSdkSource}${path.sep}`)) {
|
|
next()
|
|
return
|
|
}
|
|
try {
|
|
response.statusCode = 200
|
|
response.setHeader('Content-Type', amisContentType(sourcePath))
|
|
response.end(fs.readFileSync(sourcePath))
|
|
} catch {
|
|
next()
|
|
}
|
|
})
|
|
}
|
|
function amisSdkPlugin() {
|
|
return {
|
|
name: 'ecap-adminive-amis-sdk',
|
|
enforce: 'pre',
|
|
resolveId(source) {
|
|
if (source === 'amis' || source.startsWith('amis/')) {
|
|
this.error(`Do not import ${source} into the Vite module graph; use the AMIS SDK runtime`)
|
|
}
|
|
return null
|
|
},
|
|
buildStart() {
|
|
const emitDirectory = (directory, prefix) => {
|
|
for (const entry of fs.readdirSync(directory)) {
|
|
const sourcePath = path.join(directory, entry)
|
|
const relativePath = `${prefix}${entry}`
|
|
if (fs.statSync(sourcePath).isDirectory()) {
|
|
emitDirectory(sourcePath, `${relativePath}/`)
|
|
} else {
|
|
this.emitFile({type: 'asset', fileName: `vendor/amis/${amisPackage.version}/${relativePath}`, source: fs.readFileSync(sourcePath)})
|
|
}
|
|
}
|
|
}
|
|
emitDirectory(amisSdkSource, '')
|
|
},
|
|
transformIndexHtml: {
|
|
order: 'post',
|
|
handler() {
|
|
return [
|
|
{tag: 'link', attrs: {rel: 'stylesheet', href: `${amisSdkUrlPrefix}sdk.css`}, injectTo: 'head-prepend'},
|
|
{tag: 'link', attrs: {rel: 'stylesheet', href: `${amisSdkUrlPrefix}helper.css`}, injectTo: 'head-prepend'},
|
|
{tag: 'link', attrs: {rel: 'stylesheet', href: `${amisSdkUrlPrefix}iconfont.css`}, injectTo: 'head-prepend'},
|
|
{tag: 'script', attrs: {src: `${amisSdkUrlPrefix}sdk.js`}, injectTo: 'head-prepend'}
|
|
]
|
|
}
|
|
},
|
|
configureServer(server) {
|
|
serveAmisSdk(server)
|
|
},
|
|
configurePreviewServer(server) {
|
|
serveAmisSdk(server)
|
|
}
|
|
}
|
|
}
|
|
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',
|
|
'/aircraftlist',
|
|
'/settings',
|
|
'/ui/map',
|
|
'/ui/map3d',
|
|
'/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(), amisSdkPlugin(), 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,
|
|
},
|
|
'/map/models': {
|
|
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'
|
|
}
|
|
})
|
|
|