Next.js 14 App Router中使用@mailchimp/marketing包遇API调用问题
@mailchimp/mailchimp_marketing包无法ping通API,原生Fetch却正常 环境信息
- Next.js 14(App Router + TypeScript)
- Node.js v20 / v22
- 依赖包:
@mailchimp/mailchimp_marketing
问题详情
安装@mailchimp/mailchimp_marketing后,在./src/app/api/newsletter/subscribe/route.ts中编写代码尝试ping Mailchimp API时,持续抛出以下错误:
Mailchimp API error: TypeError: Cannot read properties of undefined (reading '0') at isInsideNodeModules (node:internal/util:521:17) at showFlaggedDeprecation (node:buffer:178:8) at new Buffer (node:buffer:266:3) at encoder (webpack-internal:///(rsc)/./node_modules/superagent/lib/node/index.js:498:12) at RequestBase._auth (webpack-internal:///(rsc)/./node_modules/superagent/lib/request-base.js:431:44) at Request.auth (webpack-internal:///(rsc)/./node_modules/superagent/lib/node/index.js:501:15) at exports.callApi (webpack-internal:///(rsc)/./node_modules/@mailchimp/mailchimp_marketing/src/ApiClient.js:396:13) at module.exports.getWithHttpInfo (webpack-internal:///(rsc)/./node_modules/@mailchimp/mailchimp_marketing/src/api/PingApi.js:65:27) at module.exports.get (webpack-internal:///(rsc)/./node_modules/@mailchimp/mailchimp_marketing/src/api/PingApi.js:77:17) at GET (webpack-internal:///(rsc)/./src/app/api/newsletter/subscribe/route.ts:16:107)
API返回结果:
{"error":"Failed to ping Mailchimp","details":"{}"}
即使硬编码凭证字符串问题依然存在,但使用相同配置的原生Fetch API可正常调用Mailchimp接口。
原因分析
该错误源于@mailchimp/mailchimp_marketing依赖的superagent库,在Next.js的React Server Components(RSC)环境中对Node.js原生Buffer API的处理存在兼容性问题。RSC的模块打包逻辑会修改部分Node.js API的行为,导致superagent中的Buffer构造调用失败。
解决办法
方案1:改用原生Fetch API(已验证可行)
直接替换第三方包,用原生Fetch实现订阅逻辑,示例代码如下:
// ./src/app/api/newsletter/subscribe/route.ts import { NextResponse } from 'next/server'; export async function POST(request: Request) { try { const { email } = await request.json(); const MAILCHIMP_API_KEY = process.env.MAILCHIMP_API_KEY!; const MAILCHIMP_LIST_ID = process.env.MAILCHIMP_LIST_ID!; const MAILCHIMP_SERVER_PREFIX = MAILCHIMP_API_KEY.split('-')[1]; const response = await fetch( `https://${MAILCHIMP_SERVER_PREFIX}.api.mailchimp.com/3.0/lists/${MAILCHIMP_LIST_ID}/members`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Basic ${Buffer.from(`anystring:${MAILCHIMP_API_KEY}`).toString('base64')}`, }, body: JSON.stringify({ email_address: email, status: 'subscribed', }), } ); if (!response.ok) { const errorData = await response.json(); return NextResponse.json( { error: '订阅失败', details: errorData }, { status: response.status } ); } return NextResponse.json({ success: true }); } catch (error) { return NextResponse.json( { error: '服务器错误', details: (error as Error).message }, { status: 500 } ); } }
方案2:强制API路由在Node.js环境运行(绕过RSC限制)
若必须使用@mailchimp/mailchimp_marketing包,可在API路由文件顶部添加export const dynamic = 'force-dynamic';,强制Next.js将该路由作为Serverless函数在Node.js环境运行,而非RSC:
// ./src/app/api/newsletter/subscribe/route.ts export const dynamic = 'force-dynamic'; import mailchimp from '@mailchimp/mailchimp_marketing'; mailchimp.setConfig({ apiKey: process.env.MAILCHIMP_API_KEY, server: process.env.MAILCHIMP_SERVER_PREFIX, }); export async function GET() { try { const response = await mailchimp.ping.get(); return Response.json({ success: true, data: response }); } catch (error) { return Response.json( { error: 'Ping Mailchimp失败', details: JSON.stringify(error) }, { status: 500 } ); } }
注意:该方式会禁用静态优化,可能影响路由缓存性能。
总结
优先推荐使用原生Fetch API,既规避第三方库兼容性问题,又减少依赖体积。若必须使用@mailchimp/mailchimp_marketing,则通过dynamic = 'force-dynamic'强制路由在Node.js环境运行。
内容的提问来源于stack exchange,提问作者André L.

