Next.js+TS项目中Firebase-admin依赖farmhash-modern触发WebAssembly错误
问题
在Next.js+TS项目中配置Firebase-admin SDK时,调用任何SDK函数(比如服务端API中间件里的verifyIdToken方法)都会触发WebAssembly错误。
中间件代码(middleware.ts)
import { auth } from "./lib/config/firebaseConfig"; import { NextResponse } from "next/server"; import { NextRequest } from "next/server"; interface ExtendedNextRequest extends NextRequest { uid?: string; } export async function middleware(req: ExtendedNextRequest, res: NextResponse) { try { let token = req.headers.get("Authorization"); if (!token) return NextResponse.json({ message: "Access Denied" }, { status: 403 }); if (token.startsWith("Bearer ")) { token = token.split(" ")[1]; } let decodedToken = await auth.verifyIdToken(token); let uid = decodedToken.uid; req.uid = uid; return NextResponse.next(); } catch (error: any) { console.log(error.errorInfo); return NextResponse.json({ message: "Invalid Token" }, { status: 401 }); } }
报错信息
⨯ ./node_modules/farmhash-modern/bin/bundler/farmhash_modern_bg.wasm Module parse failed: Unexpected character '' (1:0) The module seem to be a WebAssembly module, but module is not flagged as WebAssembly module for webpack. BREAKING CHANGE: Since webpack 5 WebAssembly is not enabled by default and flagged as experimental feature. You need to enable one of the WebAssembly experiments via 'experiments.asyncWebAssembly: true' (based on async modules) or 'experiments.syncWebAssembly: true' (like webpack 4, deprecated). For files that transpile to WebAssembly, make sure to set the module type in the 'module.rules' section of the config (e. g. 'type: "webassembly/async"'). (Source code omitted for this binary file) Import trace for requested module: ./node_modules/farmhash-modern/bin/bundler/farmhash_modern_bg.wasm ./node_modules/farmhash-modern/bin/bundler/farmhash_modern.js ./node_modules/farmhash-modern/lib/browser.js ./node_modules/firebase-admin/lib/remote-config/condition-evaluator-internal.js ./node_modules/firebase-admin/lib/remote-config/remote-config.js ./node_modules/firebase-admin/lib/app/firebase-namespace.js ./node_modules/firebase-admin/lib/default-namespace.js ./node_modules/firebase-admin/lib/index.js ./lib/config/firebaseConfig.ts
解决方案
这个问题的核心是Firebase-admin SDK被错误打包到边缘/客户端代码中——Firebase-admin是纯服务端SDK,包含仅服务端依赖(如WebAssembly模块),不适合在边缘运行时加载。以下是可行的解决方法:
拆分验证逻辑到服务端API
不要在Middleware中直接调用Firebase-admin,改为将令牌传递给服务端API路由处理验证:- 修改Middleware代码:
import { NextResponse } from "next/server"; import { NextRequest } from "next/server"; interface ExtendedNextRequest extends NextRequest { uid?: string; } export async function middleware(req: ExtendedNextRequest) { const token = req.headers.get("Authorization")?.replace("Bearer ", ""); if (!token) { return NextResponse.json({ message: "Access Denied" }, { status: 403 }); } // 调用服务端API验证令牌 const verifyRes = await fetch(`${req.nextUrl.origin}/api/verify-token`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ token }), }); if (!verifyRes.ok) { return NextResponse.json({ message: "Invalid Token" }, { status: 401 }); } const { uid } = await verifyRes.json(); req.uid = uid; return NextResponse.next(); } - 创建服务端API路由
app/api/verify-token/route.ts:import { auth } from "@/lib/config/firebaseConfig"; import { NextResponse } from "next/server"; export async function POST(req: Request) { try { const { token } = await req.json(); const decodedToken = await auth?.verifyIdToken(token); if (!decodedToken) { return NextResponse.json({ message: "Invalid Token" }, { status: 401 }); } return NextResponse.json({ uid: decodedToken.uid }); } catch (error) { return NextResponse.json({ message: "Invalid Token" }, { status: 401 }); } }
- 修改Middleware代码:
确保Firebase-admin仅在服务端初始化
修改firebaseConfig.ts,添加环境判断,只在服务端环境初始化SDK:import admin from "firebase-admin"; let auth: admin.auth.Auth | undefined; // 仅在服务端环境初始化 if (typeof window === "undefined") { if (!admin.apps.length) { admin.initializeApp({ credential: admin.credential.cert({ projectId: process.env.FIREBASE_PROJECT_ID, clientEmail: process.env.FIREBASE_CLIENT_EMAIL, privateKey: process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/g, "\n"), }), }); } auth = admin.auth(); } export { auth };(不推荐)强制启用WebAssembly支持
如果必须在Middleware中使用Firebase-admin,可在next.config.js中配置Webpack支持WebAssembly,但存在边缘环境兼容性风险:/** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config) => { config.experiments = { asyncWebAssembly: true, layers: true, }; return config; }, }; module.exports = nextConfig;
内容的提问来源于stack exchange,提问作者Buchi
相关产品推荐
相关产品推荐

