fix: build client in Docker and serve compiled SPA from Express
Some checks are pending
Build / build (push) Waiting to run
Deploy / deploy (push) Waiting to run
Lint & Type Check / lint (push) Waiting to run
Security Scan / semgrep (push) Waiting to run
Security Scan / dependency-check (push) Waiting to run
Test / test (18.x) (push) Waiting to run
Test / test (20.x) (push) Waiting to run
Some checks are pending
Build / build (push) Waiting to run
Deploy / deploy (push) Waiting to run
Lint & Type Check / lint (push) Waiting to run
Security Scan / semgrep (push) Waiting to run
Security Scan / dependency-check (push) Waiting to run
Test / test (18.x) (push) Waiting to run
Test / test (20.x) (push) Waiting to run
Vite dev mode is incompatible with Discord Activity's iframe CSP — the HMR WebSocket is blocked which breaks the React JSX dev runtime (_jsxDEV). - Build client (vite build) during Docker image build so dist/spa/ exists - Add express.static serving dist/spa/ assets in server/index.ts - Add SPA catch-all to serve dist/spa/index.html for non-API routes The Activity now loads the production compiled bundle instead of Vite's dev-mode TypeScript modules, resolving the _jsxDEV crash. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0b1d7a9441
commit
a68a2b9f8e
2 changed files with 15 additions and 2 deletions
|
|
@ -13,8 +13,8 @@ RUN if [ -f pnpm-lock.yaml ]; then npm install -g pnpm && pnpm install --frozen-
|
||||||
# Copy source code
|
# Copy source code
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Build the app (frontend + server)
|
# Build the client so the Activity gets compiled JS (no Vite dev mode in Discord iframe)
|
||||||
# RUN npm run build
|
RUN npm run build:client
|
||||||
|
|
||||||
# Set environment
|
# Set environment
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import "dotenv/config";
|
||||||
import "dotenv/config";
|
import "dotenv/config";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import cors from "cors";
|
import cors from "cors";
|
||||||
|
import path from "path";
|
||||||
import { adminSupabase } from "./supabase";
|
import { adminSupabase } from "./supabase";
|
||||||
import { emailService } from "./email";
|
import { emailService } from "./email";
|
||||||
import { randomUUID, createHash, createVerify, randomBytes, createHmac } from "crypto";
|
import { randomUUID, createHash, createVerify, randomBytes, createHmac } from "crypto";
|
||||||
|
|
@ -8192,5 +8193,17 @@ export function createServer() {
|
||||||
return manageSubscriptionHandler(req as any, res as any);
|
return manageSubscriptionHandler(req as any, res as any);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Serve compiled SPA static assets (built by `npm run build:client`)
|
||||||
|
const spaDir = path.join(process.cwd(), "dist/spa");
|
||||||
|
app.use(express.static(spaDir, { index: false }));
|
||||||
|
|
||||||
|
// SPA catch-all — serve index.html for all non-API routes
|
||||||
|
app.get("*", (req: express.Request, res: express.Response) => {
|
||||||
|
if (req.path.startsWith("/api/")) {
|
||||||
|
return res.status(404).json({ error: "API endpoint not found" });
|
||||||
|
}
|
||||||
|
res.sendFile(path.join(spaDir, "index.html"));
|
||||||
|
});
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue