feat(api-versioning): remove git-based versioning and serve via HTML script tag

- Remove `getGitHash` function from `src/utils/server.ts` as it relied on `.git` directory presence which is not available in production builds.
- Remove the `/api/app-version` endpoint from `src/index.tsx` since fetching version via API is no longer needed.
- Update `src/hooks/useAppVersion.ts` to derive the version directly from the `src` attribute of a script tag in the HTML head.
- This change improves performance by avoiding an extra API request and ensures version accuracy across all deployment environments without requiring Git metadata.
This commit is contained in:
kyuuseiryuu 2026-03-17 11:23:25 +09:00
parent eef4656f87
commit c7faeb1b65
3 changed files with 10 additions and 33 deletions

View File

@ -1,9 +1,11 @@
import { useRequest } from "ahooks";
import { useLayoutEffect, useState } from "react";
export const useAppVersion = () => {
const versionRequest = useRequest(
() => fetch('/api/app-version').then(res => res.json()).then(json => json.version),
{ debounceWait: 300 }
);
return versionRequest.data;
const [appVersion, setAppVersion] = useState('');
useLayoutEffect(() => {
const src = document.querySelector('head > script')?.getAttribute('src') ?? '';
const version = /\b(?<ver>\w*).js/.exec(src)?.groups?.ver ?? '';
setAppVersion(version.toUpperCase());
}, []);
return appVersion;
}

View File

@ -1,5 +1,5 @@
import { serve } from "bun";
import { getGitHash, getMatchInfo, verifyLogtoToken, xcxApi } from "./utils/server";
import { getMatchInfo, verifyLogtoToken, xcxApi } from "./utils/server";
import ics from 'ics';
import index from "./index.html";
import { getUidScore } from "./services/uidScoreStore";
@ -13,17 +13,12 @@ import type { IEventInfo } from "./types";
dayjs.extend(utc);
dayjs.extend(timezone);
console.debug('AppVersion: %s', await getGitHash(8));
const server = serve({
port: process.env.PORT || 3000,
routes: {
// Serve index.html for all unmatched routes.
"/*": index,
"/api/app-version": {
async GET() {
return Response.json({ version: await getGitHash(8) });
}
},
"/api/club/find": {
async GET(req) {
const searchParams = new URL(req.url).searchParams;

View File

@ -119,23 +119,3 @@ export const verifyLogtoToken = async (headers: Headers) => {
// Sub is the user ID, used for user identification
return payload
}
export async function getGitHash(length = 6): Promise<string> {
try {
// 1. 读取 HEAD 指针
const headContent = await file(".git/HEAD").text();
// 情况 A: 处于分支上 (内容格式为 "ref: refs/heads/master")
if (headContent.startsWith("ref:")) {
const refPath = headContent.replace("ref: ", "").trim();
const fullHash = await file(`.git/${refPath}`).text();
return fullHash.trim().substring(0, length);
}
// 情况 B: 处于分离头指针状态 (内容直接就是 Hash)
return headContent.trim().substring(0, length);
} catch (e) {
console.error("无法读取 Git 信息:", e);
return "unknown";
}
}