Next.js中getServerSideProps获取会话时出现dns模块找不到错误
问题
我在用NextAuth + MongoDB适配器,用户会自动在数据库创建。现在要做一个编辑个人资料页面,补充NextAuth默认字段(name、email、avatar)外的信息。这个页面是动态页面,需要在用户访问时从数据库取用户对象,所以在getServerSideProps里获取会话,根据会话信息拿用户;如果没会话就重定向到首页。但现在一直报错:Module not found: Can't resolve 'dns'。
我查过两年前的类似问题,说是getServerSideProps里有未使用的服务端导入/代码,但我所有导入和代码都在用,没找到解决办法。下面是编辑页面的完整代码(页面其他部分是共享的Header和Footer,没问题):
import React, { useState } from "react"; import type { GetServerSideProps } from "next"; import CustomInput from "../shared/CustomInput"; import { getServerSession } from "next-auth/next"; import { authOptions } from "../../pages/api/auth/[...nextauth]"; function EditProfile() { const [user, setUser] = useState({ name: "" }); return ( <section className="section-width py-20"> <h1 className="text-7xl font-fancy">שלום {user.name}</h1> <div className="grid grid-cols-2 mt-20"> <div className="flex flex-col space-y-5"> <h2 className="font-extrabold text-lg text-gray-400">Details</h2> <CustomInput type="text" label="Full Name" placeholder="Full Name" value={user.name} onChange={(name) => setUser({ ...user, name })} /> </div> </div> </section> ); } export const getServerSideProps: GetServerSideProps = async (context) => { const session = await getServerSession(context.req, context.res, authOptions); if (session?.user?.name) { return { props: { name: session.user.name, }, }; } else { return { redirect: { destination: "/", permanent: false, }, }; } }; export default EditProfile;
解决方案
这个错误的核心原因是:MongoDB驱动依赖的Node.js核心模块dns被打包到了客户端代码里——浏览器环境没有这个模块,所以报错。通常是因为authOptions文件里导入了MongoDB相关代码,而getServerSideProps导入了authOptions,Next.js在静态分析时不小心把服务端代码混入了客户端打包。
解决步骤
- 配置Next.js Webpack,排除客户端不需要的Node核心模块
在next.config.js里添加以下配置,告诉Webpack客户端打包时忽略这些Node专属模块:
module.exports = { webpack: (config, { isServer }) => { if (!isServer) { // 客户端打包时禁用Node.js核心模块 config.resolve.fallback = { ...config.resolve.fallback, dns: false, net: false, tls: false, fs: false, }; } return config; }, };
- 确保MongoDB相关代码只在服务端执行
检查../../pages/api/auth/[...nextauth]里的authOptions,如果里面直接导入了MongoDB客户端或做了数据库连接,要确保这些逻辑只在服务端运行。可以把数据库连接封装成单独的服务端函数,或者用条件判断限制执行环境:
// 在authOptions所在文件里 import { MongoClient } from "mongodb"; // 确保数据库连接仅在服务端初始化 let client; if (typeof window === "undefined") { client = new MongoClient(process.env.MONGODB_URI); await client.connect(); }
- 验证回调逻辑的执行环境
确保authOptions里的callbacks配置中,涉及数据库操作的逻辑都在服务端专属的回调(如session回调)里执行,不要在客户端可触发的回调中直接调用数据库。
内容的提问来源于stack exchange,提问作者Tsabary
相关产品推荐
相关产品推荐

