Files
NODEDC_MISSION_CORE/apps/control-station/vite.config.ts
T

134 lines
4.4 KiB
TypeScript

import { createReadStream, cpSync, existsSync, statSync } from "node:fs";
import { createRequire } from "node:module";
import { dirname, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig, loadEnv, type Plugin } from "vite";
import react from "@vitejs/plugin-react";
import wasm from "vite-plugin-wasm";
const mapAdapterEntry = fileURLToPath(import.meta.resolve("@nodedc/map-cesium-react"));
const cesiumPackageJson = createRequire(mapAdapterEntry).resolve("cesium/package.json");
const cesiumBuildRoot = resolve(
dirname(cesiumPackageJson),
"Build",
"Cesium",
);
const cesiumRuntimeDirectories = ["Assets", "ThirdParty", "Widgets", "Workers"] as const;
function cesiumRuntimeAssets(): Plugin {
return {
name: "mission-core-cesium-runtime-assets",
config: () => ({
define: {
CESIUM_BASE_URL: JSON.stringify("/cesium"),
},
}),
configureServer(server) {
server.middlewares.use("/cesium", (request, response, next) => {
const pathname = new URL(request.url ?? "/", "http://localhost").pathname;
const target = resolve(cesiumBuildRoot, `.${decodeURIComponent(pathname)}`);
if (!target.startsWith(`${cesiumBuildRoot}${sep}`) || !existsSync(target)) {
next();
return;
}
const stats = statSync(target);
if (!stats.isFile()) {
next();
return;
}
if (target.endsWith(".js")) response.setHeader("Content-Type", "text/javascript");
else if (target.endsWith(".json")) response.setHeader("Content-Type", "application/json");
else if (target.endsWith(".css")) response.setHeader("Content-Type", "text/css");
else if (target.endsWith(".wasm")) response.setHeader("Content-Type", "application/wasm");
else if (target.endsWith(".png")) response.setHeader("Content-Type", "image/png");
else if (target.endsWith(".svg")) response.setHeader("Content-Type", "image/svg+xml");
else if (target.endsWith(".jpg") || target.endsWith(".jpeg")) {
response.setHeader("Content-Type", "image/jpeg");
}
createReadStream(target).pipe(response);
});
},
writeBundle(options) {
const outputDirectory = resolve(
process.cwd(),
typeof options.dir === "string" ? options.dir : "dist",
"cesium",
);
cesiumRuntimeDirectories.forEach((directory) => {
cpSync(
resolve(cesiumBuildRoot, directory),
resolve(outputDirectory, directory),
{ recursive: true },
);
});
},
};
}
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), "");
const apiTarget = env.VITE_API_TARGET || "http://127.0.0.1:8000";
return {
plugins: [react(), wasm(), cesiumRuntimeAssets()],
resolve: {
alias: {
"@mission-core/plugin-sdk": fileURLToPath(
new URL("./src/core/device-plugins/frontendSdk.ts", import.meta.url),
),
"@xgrids-k1/frontend": fileURLToPath(
new URL("../../plugins/xgrids-k1/frontend/src", import.meta.url),
),
},
dedupe: ["react", "react-dom", "@nodedc/ui-react"],
},
optimizeDeps: {
// Rerun resolves its WASM asset relative to the package entrypoint. Vite's
// dependency pre-bundler flattens that entrypoint and leaves the WASM URL
// pointing at the SPA fallback, which browsers reject as text/html.
exclude: ["@rerun-io/web-viewer"],
},
build: {
target: "esnext",
rollupOptions: {
input: {
app: fileURLToPath(new URL("./index.html", import.meta.url)),
rerun: fileURLToPath(new URL("./rerun-runtime.html", import.meta.url)),
},
},
},
server: {
host: "127.0.0.1",
port: 5173,
strictPort: true,
fs: {
allow: [
fileURLToPath(new URL(".", import.meta.url)),
fileURLToPath(new URL("../../plugins/xgrids-k1", import.meta.url)),
fileURLToPath(new URL("../../../NODEDC_DESIGN_GUIDELINE/packages", import.meta.url)),
],
},
proxy: {
"/api": {
target: apiTarget,
changeOrigin: false,
ws: true,
},
},
},
preview: {
host: "127.0.0.1",
port: 4173,
strictPort: true,
proxy: {
"/api": {
target: apiTarget,
changeOrigin: false,
ws: true,
},
},
},
};
});