node.js - 在 getServerSideProps 内使用 EmailProvider 获取 NextAuth 会话时抛出 fs “模块未找到”
我正在尝试在 getServerSideProps 中从服务器端调用获取 NextAuth 会话,并且我正在使用带有 NextAuth 的 EmailProvider。我正在按照 NextAuth 文档中的示例,从 getServerSideProps 获取会话。
在 [...nextauth].ts] 配置文件中,我使用了 EmailProvider。
// pages/api/auth/[...nextauth].ts
import NextAuth from 'next-auth';
import EmailProvider from 'next-auth/providers/email';
export const authOptions = {
adapter: PrismaAdapter(prisma),
providers: [
EmailProvider({ ... }),
],
};
export default NextAuth(authOptions);
在一个前端组件中,我尝试这样获取会话:
// components/MyComponent.tsx
import { authOptions } from '@auth/[...nextauth]';
export const getServerSideProps = async ({ req, res }) => {
const serverSession = await getServerSession(req, res, authOptions);
return {
props: { serverSession },
};
};
我甚至在 next.config.js 中添加了 webpack 配置,以在客户端时忽略仅服务器使用的代码:
// next.config.js
module.exports = {
webpack: (config, { isServer, webpack }) => {
if (!isServer) {
config.plugins.push(
new webpack.IgnorePlugin({ resourceRegExp: /^\/pages\/api\/auth\/$/ })
);
}
}
}
问题是当我在前端组件文件中添加 import { authOptions } from '@auth/[...nextauth]'; 时,它会抛出编译错误:
// compilation error
error - ./node_modules/nodemailer/lib/dkim/index.js:10:0
Module not found: Can't resolve 'fs'
https://nextjs.org/docs/messages/module-not-found
Import trace for requested module:
./node_modules/nodemailer/lib/mailer/index.js
./node_modules/nodemailer/lib/nodemailer.js
./node_modules/next-auth/providers/email.js
./pages/api/auth/[...nextauth].ts
./components/MyComponent.tsx
./pages/index.tsx
我猜当我在 MyComponent 中导入 [...nextauth] 时,这是预期的行为,它会导入 EmailProvider,而 EmailProvider 又导入 nodemailer,nodemailer 又导入 fs。由于 MyComponent 在客户端运行,它会抛出错误,因为 fs 模块在客户端不可用。
所以我尝试了几件事情:
- 在我的
package.json中添加"fs": false(源代码在这里)。这作为临时解决方案是可行的,但随后更多的模块需要被添加到package.json中,我就会陷入一个泥潭,最终导致无法使用prisma。 - 在
getServerSideProps内导入authOptions(示例)。这并没有影响错误。
还有其他想法吗?谢谢!
答案#1
啊,所以组件不能进行服务器端渲染(SSR),只有页面可以。这里有更多的文档。
所以为了解决这个问题,我将 getServerSideProps 移到了一个页面(例如 pages/index.tsx 或 pages/ 根目录下的任何其他页面)。代码看起来一样,下面复制了一份,但代码所在的文件不同。
// components/MyComponent.tsx <-- this is wrong
// ^^ IT SHOULD NOT BE A COMPONENT
// pages/index.tsx <-- or whatever page you're using
// ^^ IT SHOULD BE A PAGE INSTEAD OF A COMPONENT
import { authOptions } from '@auth/[...nextauth]';
export const getServerSideProps = async ({ req, res }) => {
const serverSession = await getServerSession(req, res, authOptions);
return {
props: { serverSession },
};
};
