NextJS中使用nodemailer、NextAuth与useState时出现模块未找到错误
问题:NextAuth + Nodemailer 在客户端组件中出现模块找不到错误
问题描述
我正在开发一个需要用户认证才能发布推文的简单网页,使用NextAuth结合nodemailer作为邮箱认证提供商。之前用getServerSession(options)获取会话状态一切正常,但在首页引入包含useState的NewTweet组件(已添加"use client"指令)后,出现一系列"Module not found: Can't resolve ___"错误(比如fs、net等包)。
我知道nodemailer只能在服务端组件中使用,但不理解为什么客户端会调用它,而且已经在NextAuth的route.js里加了"use server"指令还是没解决问题。
相关文件代码
1. route.js(NextAuth处理文件)
"use server"; import NextAuth from 'next-auth' import options from './options' const handler = NextAuth(options) export {handler as GET, handler as POST}
2. page.js(首页)
"use client"; import Link from 'next/link.js' import options from './/api/auth/[...nextauth]/options.js' import { getServerSession } from 'next-auth' import NewTweet from 'components/NewTweet.js' export default async function Home(){ const session = await getServerSession(options) console.log(session) return( <div> <Link href='/api/auth/signin'>Log In!</Link> <div> {session ? <NewTweet /> : <p>You are not logged in!</p>} </div> </div> ) }
3. NewTweet.js(客户端组件)
"use client"; import { getServerSession } from 'next-auth' import { useState } from 'react' import options from '../src/app/api/auth/[...nextauth]/options.js' export default function NewTweet(){ const [content, setContent] = useState('') return( <div> <form onSubmit={async (e) => { e.preventDefault() if (!content) { alert('No content') return } alert(content) }} > <div className='flex'> <div className='flex-1 px-1 pt-2 mt-2 mr-1 ml-1'> <textarea className='border p-4 w-full text-lg font-medium bg-transparent outline-none color-primary ' rows={2} cols={50} placeholder="What's happening?" name='content' onChange={(e) => setContent(e.target.value)} /> </div> </div> <div className='flex'> <div className='flex-1 mb-5'> <button className = 'border float-right px-8 py-2 mt-0 mr-2 font-bold rounded-full'> Send Tweet! </button> </div> </div> </form> </div> ) }
错误信息
./node_modules/nodemailer/lib/dkim/index.js:10:0 Module not found: Can't resolve 'fs' 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 ./src/app/api/auth/[...nextauth]/options.js ./components/NewTweet.js
解决方案
问题根源在于客户端组件(NewTweet.js和page.js)直接导入了包含nodemailer的NextAuth options文件——nodemailer依赖Node.js的服务端核心模块(如fs、net),这些模块在浏览器环境中不存在,所以打包时会报错。
1. 清理客户端组件的无效导入
NewTweet.js里完全没用到getServerSession和options,直接删除这两行代码:
import { getServerSession } from 'next-auth' import options from '../src/app/api/auth/[...nextauth]/options.js'
2. 替换客户端组件的会话获取方式
page.js是客户端组件,不能直接调用服务端方法getServerSession,改用NextAuth提供的客户端钩子useSession:
"use client"; import Link from 'next/link.js' import { useSession } from 'next-auth/react' // 改用客户端钩子 import NewTweet from 'components/NewTweet.js' export default function Home(){ const { data: session } = useSession() // 替换getServerSession调用 console.log(session) return( <div> <Link href='/api/auth/signin'>Log In!</Link> <div> {session ? <NewTweet /> : <p>You are not logged in!</p>} </div> </div> ) }
3. 确保options文件仅在服务端使用
你的options.js因为导入了next-auth/providers/email(依赖nodemailer),所以这个文件只能在服务端组件或API路由中引用,绝对不能在客户端组件里导入。
关键原理
getServerSession是服务端专属方法,只能在服务端组件或API路由中调用,无法在客户端组件直接运行。- nodemailer是服务端库,任何依赖它的模块都只能在Node.js环境运行,一旦被客户端组件引用,就会触发浏览器不支持的Node.js模块错误。
内容的提问来源于stack exchange,提问作者willten1
相关产品推荐
相关产品推荐

