From ef5514a00862d4b5fcd6171fb6759c297cc8af6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B4=AE=E7=94=9F=EF=BC=88=E5=AD=90=E8=99=9A=EF=BC=89?= <2234839456@qq.com> Date: Sat, 13 Jun 2026 21:14:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20subsetCache=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=8C=87=E7=BA=B9=E6=94=B9=E7=94=A8=E6=9E=84=E5=BB=BA=E6=9C=9F?= =?UTF-8?q?=E6=B3=A8=E5=85=A5=EF=BC=8C=E4=BF=AE=E5=A4=8D=20LLRT=20=5F=5Ffi?= =?UTF-8?q?lename=20=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit createRequire(import.meta.url) 经 tsdown 打包为 CJS 后引入 __filename, 而 LLRT 运行时不提供 __filename,导致 ReferenceError: __filename is not defined。 改用 tsdown define 构建期把 PACKAGE_VERSION 替换为字面量字符串, 运行时无文件读取、无 __filename 依赖。 Co-Authored-By: Claude Opus 4.8 (1M context) --- backend/routes/subset.ts | 12 +++++++----- tsdown.config.ts | 6 ++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/backend/routes/subset.ts b/backend/routes/subset.ts index 5289338..e10a7c5 100644 --- a/backend/routes/subset.ts +++ b/backend/routes/subset.ts @@ -1,4 +1,3 @@ -import { createRequire } from "node:module"; import { fontSubset } from "../font_util/font"; import type { FontEditor } from "../../vendor/fonteditor-core/lib/ttf/font.js"; import { parseUrl, jsonResponse, stats, subsetCache, findFontPath, readFontBuffer } from "../shared"; @@ -7,13 +6,16 @@ import { parseUrl, jsonResponse, stats, subsetCache, findFontPath, readFontBuffe * 子集化版本指纹 * * 纳入 subsetCache 的 key,让旧缓存条目在以下两种场景自动失效,无需手动清缓存: - * - 生产:发版 bump package.json 的 version,旧缓存自然过期(语义版本失效) - * - 开发:pnpm dev 重启进程时进程启动时间戳变化,内存缓存整体重置 + * - 生产:发版 bump package.json 的 version(构建期由 tsdown define 注入),旧缓存自然过期 + * - 开发:pnpm dev 重启进程时 process.uptime() 变化,内存缓存整体重置 * * 杜绝「子集化代码已修但缓存返回旧错误结果」的陷阱。 + * + * 注意:不用 createRequire(import.meta.url) 读 package.json —— 该写法经 tsdown 打包为 CJS 后 + * 会引入 __filename,而 LLRT 运行时不提供 __filename,导致 ReferenceError。 */ -const packageVersion: string = createRequire(import.meta.url)("../../package.json").version; -const SUBSET_CACHE_KEY = `${packageVersion}:${process.uptime()}`; +declare const PACKAGE_VERSION: string; +const SUBSET_CACHE_KEY = `${PACKAGE_VERSION}:${process.uptime()}`; /** GET /api?font=...&text=... — 字体裁剪 */ export async function handleFontSubset(req: Request, res: Response) { diff --git a/tsdown.config.ts b/tsdown.config.ts index 66eea0a..d951bd8 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -1,10 +1,16 @@ import { defineConfig } from "tsdown"; +import { readFileSync } from "node:fs"; + +/** 构建期读取 package.json 版本号,注入为运行时常量(避免运行时读文件 + LLRT 无 __filename 问题) */ +const packageVersion = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8")).version; const shared = { format: ["cjs"], clean: true, sourcemap: true, outDir: "dist_backend", + /** 构建期把 PACKAGE_VERSION 替换为字面量字符串,运行时无任何文件读取 */ + define: { PACKAGE_VERSION: JSON.stringify(packageVersion) }, outputOptions: { /** 禁用代码拆分,确保单文件输出(tsdown 默认会拆分大依赖为 chunk) */ codeSplitting: false,