feat: 移除仓库内 nginx 并拆分前端运行时

This commit is contained in:
Cheng Zhou
2026-03-30 21:02:51 +08:00
parent 7ccb8c20cc
commit 27ba5eabff
22 changed files with 287 additions and 160 deletions
+1
View File
@@ -1,4 +1,5 @@
# Frontend feature flags and timeline overrides
VITE_API_BASE_URL=
VITE_STARTUP_SUBMIT_ACCEPT_TIMEOUT_MONTHS=3
VITE_STARTUP_ACCEPT_TIMEOUT_MONTHS=3
VITE_STARTUP_ACCEPT_APPROVAL_TIMEOUT_MONTHS=6
+5
View File
@@ -0,0 +1,5 @@
:4173
root * /srv
try_files {path} /index.html
file_server
+7 -3
View File
@@ -2,14 +2,18 @@ FROM node:20-alpine AS build
WORKDIR /app
ARG VITE_API_BASE_URL
ENV VITE_API_BASE_URL=${VITE_API_BASE_URL}
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM alpine:3.21
FROM caddy:2-alpine
WORKDIR /opt/frontend
COPY Caddyfile /etc/caddy/Caddyfile
COPY --from=build /app/dist /srv
COPY --from=build /app/dist ./dist
EXPOSE 4173
+4 -1
View File
@@ -7,9 +7,12 @@ import { useStudyStore } from "../store/study";
import { TEXT } from "../locales";
import { extendAccessToken, forceLogout, lockSession, markNetworkActive } from "../session/sessionManager";
import { useSessionStore } from "../store/session";
import { resolveApiBaseUrl } from "./baseUrl";
const apiBaseUrl = resolveApiBaseUrl(import.meta.env.VITE_API_BASE_URL);
const instance: AxiosInstance = axios.create({
baseURL: "/",
baseURL: apiBaseUrl,
timeout: 15000,
});
+19
View File
@@ -0,0 +1,19 @@
import { describe, expect, it } from "vitest";
import { resolveApiBaseUrl } from "./baseUrl";
describe("resolveApiBaseUrl", () => {
it("defaults to same-origin root when no env override is set", () => {
expect(resolveApiBaseUrl(undefined)).toBe("/");
expect(resolveApiBaseUrl("")).toBe("/");
expect(resolveApiBaseUrl(" ")).toBe("/");
});
it("preserves explicit root", () => {
expect(resolveApiBaseUrl("/")).toBe("/");
});
it("trims whitespace and trailing slashes from absolute base urls", () => {
expect(resolveApiBaseUrl(" http://localhost:8000/ ")).toBe("http://localhost:8000");
expect(resolveApiBaseUrl("https://api.example.com///")).toBe("https://api.example.com");
});
});
+12
View File
@@ -0,0 +1,12 @@
const trimTrailingSlashes = (value: string): string => value.replace(/\/+$/, "");
export const resolveApiBaseUrl = (rawValue: string | undefined): string => {
const normalized = rawValue?.trim() ?? "";
if (!normalized) {
return "/";
}
if (normalized === "/") {
return "/";
}
return trimTrailingSlashes(normalized);
};