From 99d15544a4de3956a80e0fbfb0392b83586fb209 Mon Sep 17 00:00:00 2001 From: shinya Date: Mon, 30 Jun 2025 10:08:54 +0800 Subject: [PATCH] fix: load dynamic config --- Dockerfile | 4 ++++ src/app/api/detail/route.ts | 2 +- src/app/api/douban/route.ts | 2 +- src/app/api/login/route.ts | 2 +- src/app/api/playrecords/route.ts | 2 +- src/app/api/search/route.ts | 2 +- src/lib/config.ts | 27 ++++++++++----------------- 7 files changed, 19 insertions(+), 22 deletions(-) diff --git a/Dockerfile b/Dockerfile index e8b0688..f16952e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,6 +22,10 @@ COPY --from=deps /app/node_modules ./node_modules # 复制全部源代码 COPY . . +# 在构建阶段也显式设置 DOCKER_ENV, +# 确保 Next.js 在编译时即选择 Node Runtime 而不是 Edge Runtime +ENV DOCKER_ENV=true + # 生成生产构建 RUN pnpm run build diff --git a/src/app/api/detail/route.ts b/src/app/api/detail/route.ts index 0668dbb..16fe971 100644 --- a/src/app/api/detail/route.ts +++ b/src/app/api/detail/route.ts @@ -185,7 +185,7 @@ async function getVideoDetail( return getDetailFromApi(apiSite, id); } -export const runtime = 'edge'; +export const runtime = process.env.DOCKER_ENV === 'true' ? 'node' : 'edge'; export async function GET(request: Request) { const { searchParams } = new URL(request.url); diff --git a/src/app/api/douban/route.ts b/src/app/api/douban/route.ts index d6871bd..b2d0844 100644 --- a/src/app/api/douban/route.ts +++ b/src/app/api/douban/route.ts @@ -43,7 +43,7 @@ async function fetchDoubanData(url: string): Promise { } } -export const runtime = 'edge'; +export const runtime = process.env.DOCKER_ENV === 'true' ? 'node' : 'edge'; export async function GET(request: Request) { const { searchParams } = new URL(request.url); diff --git a/src/app/api/login/route.ts b/src/app/api/login/route.ts index 3b5d174..269845b 100644 --- a/src/app/api/login/route.ts +++ b/src/app/api/login/route.ts @@ -1,6 +1,6 @@ import { NextRequest, NextResponse } from 'next/server'; -export const runtime = 'edge'; +export const runtime = process.env.DOCKER_ENV === 'true' ? 'node' : 'edge'; export async function POST(req: NextRequest) { try { diff --git a/src/app/api/playrecords/route.ts b/src/app/api/playrecords/route.ts index 70f1a23..c11cb4a 100644 --- a/src/app/api/playrecords/route.ts +++ b/src/app/api/playrecords/route.ts @@ -5,7 +5,7 @@ import { NextRequest, NextResponse } from 'next/server'; import { db } from '@/lib/db'; import { PlayRecord } from '@/lib/db'; -export const runtime = 'edge'; +export const runtime = process.env.DOCKER_ENV === 'true' ? 'node' : 'edge'; export async function GET() { try { diff --git a/src/app/api/search/route.ts b/src/app/api/search/route.ts index 0b95918..8a393d6 100644 --- a/src/app/api/search/route.ts +++ b/src/app/api/search/route.ts @@ -4,7 +4,7 @@ import { API_CONFIG, ApiSite, getApiSites, getCacheTime } from '@/lib/config'; import { SearchResult } from '@/lib/types'; import { cleanHtmlTags } from '@/lib/utils'; -export const runtime = 'edge'; +export const runtime = process.env.DOCKER_ENV === 'true' ? 'node' : 'edge'; // 根据环境变量决定最大搜索页数,默认 5 const MAX_SEARCH_PAGES: number = diff --git a/src/lib/config.ts b/src/lib/config.ts index ce889d9..3c0ac75 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -52,24 +52,17 @@ export const API_CONFIG = { let cachedConfig: Config; if (process.env.DOCKER_ENV === 'true') { - // 为了兼容 Edge Runtime,这里通过 eval("require") 的方式按需加载 fs 和 path, - // 避免在打包阶段将 Node 内置模块打进 Edge bundle。 - try { - // eslint-disable-next-line @typescript-eslint/no-implied-eval - const req = eval('require') as any; - const fs = req('fs') as typeof import('fs'); - const path = req('path') as typeof import('path'); + // 使用 Node.js 原生 require,避免使用 eval 触发 V8 "Code generation from strings disallowed" 限制 + // 这里在编译阶段即被 webpack 标记为 external,Edge Runtime 会被 tree-shaking 去掉 + // eslint-disable-next-line @typescript-eslint/no-var-requires + const fs = require('fs') as typeof import('fs'); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const path = require('path') as typeof import('path'); - const configPath = path.join(process.cwd(), 'config.json'); - const raw = fs.readFileSync(configPath, 'utf-8'); - cachedConfig = JSON.parse(raw) as Config; - } catch (error) { - console.error( - '[config] 读取 config.json 失败,回退至编译时配置 →', - (error as Error).message - ); - cachedConfig = runtimeConfig as unknown as Config; - } + const configPath = path.join(process.cwd(), 'config.json'); + const raw = fs.readFileSync(configPath, 'utf-8'); + cachedConfig = JSON.parse(raw) as Config; + console.log('load dynamic config success'); } else { // 默认使用编译时生成的配置 cachedConfig = runtimeConfig as unknown as Config;