forked from phenom/healer-man
131 lines
5.5 KiB
TypeScript
131 lines
5.5 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import path from "node:path";
|
|
import { configDefaults, defineConfig } from "vitest/config";
|
|
import react from "@vitejs/plugin-react";
|
|
// @ts-expect-error Shared Node HTTP middleware also serves production bundles.
|
|
import { createBundledContentHandler } from "./server/bundled-content.mjs";
|
|
// @ts-expect-error Local-only Node middleware is activated only in balance-lab-gui mode.
|
|
import { createLocalBalanceLabApi } from "./server/local-balance-lab-api.mjs";
|
|
|
|
const packageVersion = (JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8")) as { version: string }).version;
|
|
|
|
export default defineConfig(({ mode }) => {
|
|
const androidBuild = mode === "android";
|
|
const shelvedModesEnabled = mode === "shelved";
|
|
const balanceLabRuntime = mode === "balance-lab";
|
|
const localBalanceLabGui = mode === "balance-lab-gui";
|
|
const downloadableBuild = androidBuild || mode === "production" || shelvedModesEnabled;
|
|
return {
|
|
plugins: [react(), {
|
|
name: "local-balance-lab-api",
|
|
configureServer(server) {
|
|
if (!localBalanceLabGui) return;
|
|
const api = createLocalBalanceLabApi();
|
|
server.httpServer?.once("close", () => api.close());
|
|
server.middlewares.use((request, response, next) => {
|
|
void api.handle(request, response).then((handled: boolean) => {
|
|
if (!handled) next();
|
|
}).catch(next);
|
|
});
|
|
},
|
|
}, {
|
|
name: "bundled-content-preview",
|
|
configurePreviewServer(server) {
|
|
const serve = createBundledContentHandler(path.resolve(androidBuild ? "dist-android" : "dist"));
|
|
server.middlewares.use((request, response, next) => {
|
|
if (!serve(request, response, new URL(request.url ?? "/", "http://localhost").pathname)) next();
|
|
});
|
|
},
|
|
}, {
|
|
name: "bundle-module-report",
|
|
generateBundle(_options, bundle) {
|
|
const chunks = Object.values(bundle)
|
|
.filter((entry): entry is Extract<typeof entry, { type: "chunk" }> => entry.type === "chunk")
|
|
.map((chunk) => ({
|
|
file: chunk.fileName,
|
|
entry: chunk.isEntry,
|
|
dynamicEntry: chunk.isDynamicEntry,
|
|
modules: Object.keys(chunk.modules).map((moduleId) => (
|
|
path.relative(process.cwd(), moduleId).split(path.sep).join("/")
|
|
)).sort(),
|
|
}));
|
|
this.emitFile({
|
|
type: "asset",
|
|
fileName: "bundle-module-report.json",
|
|
source: `${JSON.stringify({ shelvedModesEnabled, chunks }, null, 2)}\n`,
|
|
});
|
|
},
|
|
}],
|
|
publicDir: balanceLabRuntime ? false : androidBuild ? ".android-public" : downloadableBuild ? ".web-public" : "public",
|
|
define: {
|
|
"import.meta.env.VITE_APP_VERSION": JSON.stringify(packageVersion),
|
|
"import.meta.env.VITE_CONTENT_MODE": JSON.stringify(downloadableBuild ? "downloadable" : "bundled"),
|
|
"import.meta.env.VITE_SHELVED_MODES_ENABLED": JSON.stringify(shelvedModesEnabled ? "true" : "false"),
|
|
"import.meta.env.VITE_LOCAL_BALANCE_LAB_GUI": JSON.stringify(localBalanceLabGui ? "true" : "false"),
|
|
},
|
|
resolve: {
|
|
alias: {
|
|
"@dungeonAssetModules": path.resolve(
|
|
androidBuild || mode === "production" ? "src/game/dungeonAssetModules.android.ts" : "src/game/dungeonAssetModules.ts",
|
|
),
|
|
"@shelvedGameRuntime": path.resolve(
|
|
shelvedModesEnabled ? "src/app/ShelvedGameRuntime.enabled.tsx" : "src/app/ShelvedGameRuntime.disabled.tsx",
|
|
),
|
|
"@shelvedGameScene": path.resolve(
|
|
shelvedModesEnabled ? "src/scene/ShelvedGameScene.enabled.tsx" : "src/scene/ShelvedGameScene.disabled.tsx",
|
|
),
|
|
"@shelvedModeRoutes": path.resolve(
|
|
shelvedModesEnabled ? "src/app/ShelvedModeRoutes.tsx" : "src/app/ShelvedModeRoutes.disabled.tsx",
|
|
),
|
|
"@shelvedOnlineGroupRuntime": path.resolve(
|
|
shelvedModesEnabled ? "src/app/ShelvedOnlineGroupRuntime.enabled.ts" : "src/app/ShelvedOnlineGroupRuntime.disabled.ts",
|
|
),
|
|
"@shelvedDungeonSession": path.resolve(
|
|
shelvedModesEnabled ? "src/game/ShelvedDungeonSession.enabled.ts" : "src/game/ShelvedDungeonSession.disabled.ts",
|
|
),
|
|
"@shelvedCompanionPanel": path.resolve(
|
|
shelvedModesEnabled ? "src/ui/ShelvedCompanionPanel.enabled.tsx" : "src/ui/ShelvedCompanionPanel.disabled.tsx",
|
|
),
|
|
"@shelvedHud": path.resolve(
|
|
shelvedModesEnabled ? "src/ui/ShelvedHud.enabled.tsx" : "src/ui/ShelvedHud.disabled.tsx",
|
|
),
|
|
},
|
|
},
|
|
server: {
|
|
proxy: {
|
|
"/api": "http://127.0.0.1:4173",
|
|
"/content": "http://127.0.0.1:4173",
|
|
},
|
|
watch: {
|
|
// Asset-pipeline staging files are large, short-lived, and can be locked
|
|
// while iCloud or conversion tools are writing them. They are not app
|
|
// source, so watching them only risks taking the dev server down with
|
|
// EBUSY on Windows.
|
|
ignored: balanceLabRuntime
|
|
? ["**/*"]
|
|
: [
|
|
"**/dungeon-pipeline/**",
|
|
"**/playtest-artifacts/**",
|
|
...(localBalanceLabGui ? ["**/artifacts/balance-lab-gui-runtime/**"] : []),
|
|
],
|
|
},
|
|
},
|
|
build: {
|
|
target: "es2022",
|
|
sourcemap: false,
|
|
emptyOutDir: true,
|
|
outDir: androidBuild ? "dist-android" : "dist",
|
|
},
|
|
test: {
|
|
environment: "node",
|
|
include: ["src/**/*.test.ts"],
|
|
exclude: [
|
|
...configDefaults.exclude,
|
|
"**/._*",
|
|
"**/._*/**",
|
|
],
|
|
maxWorkers: 4,
|
|
},
|
|
};
|
|
});
|