Next.js14报错:Module not found: Can't resolve 'fs' 求助
解决Next.js中
Module not found: Can't resolve 'fs'报错问题 问题根源
你用的argon2是Node.js端的加密库,它依赖的@mapbox/node-pre-gyp会调用Node.js的fs模块,但你的代码在客户端组件中执行(DashboardUI.jsx被page.js引用,App Router默认是客户端组件),浏览器环境不存在fs模块,所以触发报错。
具体解决方案
方案一:将验证逻辑移到Server Component
App Router中page.js默认是Server Component,允许使用Node.js模块,直接在这里调用密码验证逻辑:
- 修改
firebase.js,确保argon2仅在服务器端加载:
import { doc, getDoc } from 'firebase/firestore'; import { db } from "./firebase-config"; // 动态导入argon2,限制仅在服务器端执行 const argon2 = (await import('argon2')).default; export const checkPasswordMatch = async ({ pw }) => { const docRef = doc(db, "password", "password"); const docSnap = await getDoc(docRef); if (docSnap.exists()) { // 注意:这里要取文档中存储哈希的具体字段,比如你存的是hash就写hash const hash = docSnap.data().hash; try { return await argon2.verify(hash, pw); } catch (err) { console.error(err); return false; } } else { console.log("No such document!"); return false; } }
- 在
dashboard/page.js中调用该方法(page是Server Component,可安全执行Node.js代码):
import { checkPasswordMatch } from '@/db/firebase'; export default async function DashboardPage() { // 示例:这里可以根据业务逻辑获取用户输入的密码,比如从表单提交中获取 const isPasswordValid = await checkPasswordMatch({ pw: 'user-input-password' }); return ( <div> {isPasswordValid ? '密码验证通过' : '密码错误'} </div> ); }
方案二:创建API Route处理验证逻辑
把密码验证逻辑放到API接口中,客户端通过fetch调用接口:
- 创建
app/api/check-password/route.js:
import { NextResponse } from 'next/server'; import { checkPasswordMatch } from '@/db/firebase'; export async function POST(request) { const { pw } = await request.json(); const isMatch = await checkPasswordMatch({ pw }); return NextResponse.json({ isValid: isMatch }); }
- 在客户端组件
DashboardUI.jsx中调用接口:
const handlePasswordCheck = async (userInputPw) => { const res = await fetch('/api/check-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pw: userInputPw }) }); const data = await res.json(); console.log('验证结果:', data.isValid); }
额外注意事项
- 你原代码中
const hash = docSnap.data()是错误的,docSnap.data()返回的是整个文档对象,必须提取存储哈希的具体字段(比如docSnap.data().passwordHash),否则argon2.verify会因为传入对象而非字符串哈希报错。 - 密码验证逻辑绝对不要放在客户端执行,避免哈希值泄露或被篡改,所有敏感逻辑必须放在服务器端。
内容的提问来源于stack exchange,提问作者André Gomes
相关产品推荐
相关产品推荐

