Next.js 未找到中间件模块:无法解析 'fs'
Next.js middleware Module not found: Can't resolve 'fs'
当我尝试初始化 Firebase admin V9 时,在 Next.js _middleware
文件中出现此错误。有人知道如何解决这个问题吗?
./node_modules/@google-cloud/storage/build/src/bucket.js:22:0
Module not found: Can't resolve 'fs'
../../firebase/auth-admin
import * as admin from "firebase-admin";
if (!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert({
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_ADMIN_PRIVATE_KEY,
}),
});
}
const firestore = admin.firestore();
const auth = admin.auth();
export { firestore, auth };
在我的 _middleware
中调用它
import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
import { auth } from "../../firebase/auth-admin";
export default async function authenticate(
req: NextRequest,
ev: NextFetchEvent
) {
const token = req.headers.get("token");
console.log("auth = ", auth);
// const decodeToken = await auth.verifyIdToken(token);
return NextResponse.next();
}
我通过自定义 webpack 看到了一个解决方案 here,但这并不能解决问题。
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
webpack: (config, { isServer, node }) => {
node = {
...node,
fs: "empty",
child_process: "empty",
net: "empty",
tls: "empty",
};
return config;
},
};
module.exports = nextConfig;
Next.js 中间件使用的边缘运行时不支持 Node.js 本机 API。
来自 Edge Runtime 文档:
The Edge Runtime has some restrictions including:
- Native Node.js APIs are not supported. For example, you can't read or write to the filesystem
- Node Modules can be used, as long as they implement ES Modules and do not use any native Node.js APIs
您不能使用在 Next.js 中间件中使用 fs
的 Node.js 库。尝试使用 client-side 库。
我浪费了很多时间来解决这个问题。奇怪的是,这将在 api 本身中起作用。
所以不要在 _middleware
文件中调用 firebase-admin 操作。在 api 本身中调用它,例如:
import type { NextApiRequest, NextApiResponse } from 'next'
import { auth } from "../../firebase/auth-admin";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const authorization = req.headers.authorization
console.log(`Handler auth header: ${authorization}`)
if (!authorization) {
return res.status(401).json({ message: 'Authorisation header not found.' })
}
const token = authorization.split(' ')[1]
if (!token) {
return res.status(401).json({ message: 'Bearer token not found.' })
}
console.log(`Token: ${token}`)
try {
const {uid} = await auth.verifyIdToken("sd" + token)
console.log(`User uid: ${uid}`)
res.status(200).json({ userId: uid })
} catch (error) {
console.log(`verifyIdToken error: ${error}`)
res.status(401).json({ message: `Error while verifying token. Error: ${error}` })
}
}
使这个可重用的解决方法是创建一个包装函数。
如果有人知道如何在 _middleware
文件中进行这项工作,我将不胜感激。
编辑:包装中间件函数的要点:
https://gist.github.com/jvgrootveld/ed1863f0beddc1cc2bf2d3593dedb6da
确保您没有在客户端中调用 firebase-admin
import * as admin from "firebase-admin";
当我尝试初始化 Firebase admin V9 时,在 Next.js _middleware
文件中出现此错误。有人知道如何解决这个问题吗?
./node_modules/@google-cloud/storage/build/src/bucket.js:22:0
Module not found: Can't resolve 'fs'
../../firebase/auth-admin
import * as admin from "firebase-admin";
if (!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert({
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_ADMIN_PRIVATE_KEY,
}),
});
}
const firestore = admin.firestore();
const auth = admin.auth();
export { firestore, auth };
在我的 _middleware
import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
import { auth } from "../../firebase/auth-admin";
export default async function authenticate(
req: NextRequest,
ev: NextFetchEvent
) {
const token = req.headers.get("token");
console.log("auth = ", auth);
// const decodeToken = await auth.verifyIdToken(token);
return NextResponse.next();
}
我通过自定义 webpack 看到了一个解决方案 here,但这并不能解决问题。
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
webpack: (config, { isServer, node }) => {
node = {
...node,
fs: "empty",
child_process: "empty",
net: "empty",
tls: "empty",
};
return config;
},
};
module.exports = nextConfig;
Next.js 中间件使用的边缘运行时不支持 Node.js 本机 API。
来自 Edge Runtime 文档:
The Edge Runtime has some restrictions including:
- Native Node.js APIs are not supported. For example, you can't read or write to the filesystem
- Node Modules can be used, as long as they implement ES Modules and do not use any native Node.js APIs
您不能使用在 Next.js 中间件中使用 fs
的 Node.js 库。尝试使用 client-side 库。
我浪费了很多时间来解决这个问题。奇怪的是,这将在 api 本身中起作用。
所以不要在 _middleware
文件中调用 firebase-admin 操作。在 api 本身中调用它,例如:
import type { NextApiRequest, NextApiResponse } from 'next'
import { auth } from "../../firebase/auth-admin";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const authorization = req.headers.authorization
console.log(`Handler auth header: ${authorization}`)
if (!authorization) {
return res.status(401).json({ message: 'Authorisation header not found.' })
}
const token = authorization.split(' ')[1]
if (!token) {
return res.status(401).json({ message: 'Bearer token not found.' })
}
console.log(`Token: ${token}`)
try {
const {uid} = await auth.verifyIdToken("sd" + token)
console.log(`User uid: ${uid}`)
res.status(200).json({ userId: uid })
} catch (error) {
console.log(`verifyIdToken error: ${error}`)
res.status(401).json({ message: `Error while verifying token. Error: ${error}` })
}
}
使这个可重用的解决方法是创建一个包装函数。
如果有人知道如何在 _middleware
文件中进行这项工作,我将不胜感激。
编辑:包装中间件函数的要点: https://gist.github.com/jvgrootveld/ed1863f0beddc1cc2bf2d3593dedb6da
确保您没有在客户端中调用 firebase-admin
import * as admin from "firebase-admin";