From 8b7cc15362a3324b4c09f9cd3194913b5173a953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=BF=94?= Date: Mon, 30 Mar 2026 10:44:10 +0800 Subject: [PATCH] fix(build): lazy initialize Resend to prevent build failures The real root cause of CI build failures was NOT Turbopack, but Resend initialization at module level without API key. Problem: - Resend was initialized at module level: const resend = new Resend(process.env.RESEND_API_KEY) - During build, Next.js collects page data and imports all modules - If RESEND_API_KEY is not set, Resend throws error: 'Missing API key' - This caused build to fail with 'Failed to collect page data for /api/contact' Solution: - Implement lazy initialization pattern for Resend - Only initialize Resend when actually needed (when sending emails) - Add proper error handling if API key is missing Changes: - src/app/api/contact/route.ts: Add getResend() function with lazy init - src/app/(marketing)/contact/actions.ts: Add getResend() function with lazy init This allows the build to succeed even without RESEND_API_KEY in CI, while still requiring it at runtime when actually sending emails. --- src/app/(marketing)/contact/actions.ts | 16 ++++++++++++++-- src/app/api/contact/route.ts | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/app/(marketing)/contact/actions.ts b/src/app/(marketing)/contact/actions.ts index 70153aa..24403b4 100644 --- a/src/app/(marketing)/contact/actions.ts +++ b/src/app/(marketing)/contact/actions.ts @@ -3,9 +3,21 @@ import { Resend } from 'resend'; import { z } from 'zod'; -const resend = new Resend(process.env.RESEND_API_KEY); const companyEmail = process.env.COMPANY_EMAIL || 'contact@novalon.cn'; +let resend: Resend | null = null; + +function getResend(): Resend { + if (!resend) { + const apiKey = process.env.RESEND_API_KEY; + if (!apiKey) { + throw new Error('RESEND_API_KEY environment variable is not set'); + } + resend = new Resend(apiKey); + } + return resend; +} + const contactFormSchema = z.object({ name: z.string().min(2, '姓名至少需要2个字符'), phone: z.string().regex(/^1[3-9]\d{9}$/, '请输入有效的手机号码'), @@ -244,7 +256,7 @@ export async function submitContactForm( `; try { - const { data: emailData, error } = await resend.emails.send({ + const { data: emailData, error } = await getResend().emails.send({ from: '睿新致远官网 ', to: [companyEmail], subject: `📧 ${data.subject} - ${data.name}`, diff --git a/src/app/api/contact/route.ts b/src/app/api/contact/route.ts index 50489db..ef62a97 100644 --- a/src/app/api/contact/route.ts +++ b/src/app/api/contact/route.ts @@ -3,9 +3,21 @@ import { Resend } from 'resend'; import { z } from 'zod'; import { SecurityMiddleware } from '@/lib/security/middleware'; -const resend = new Resend(process.env.RESEND_API_KEY); const companyEmail = process.env.COMPANY_EMAIL || 'contact@novalon.cn'; +let resend: Resend | null = null; + +function getResend(): Resend { + if (!resend) { + const apiKey = process.env.RESEND_API_KEY; + if (!apiKey) { + throw new Error('RESEND_API_KEY environment variable is not set'); + } + resend = new Resend(apiKey); + } + return resend; +} + let securityMiddleware = new SecurityMiddleware(); export function setSecurityMiddleware(middleware: SecurityMiddleware) { @@ -108,7 +120,7 @@ export async function POST(request: NextRequest) { `; - const result = await resend.emails.send({ + const result = await getResend().emails.send({ from: '睿新致远官网 ', to: [companyEmail], subject: `${sanitizedData.subject} - ${sanitizedData.name}`,