Next.js Server Action被误判为客户端代码?求助
解决Next.js Server Action中
fs模块找不到的问题 问题原因
你遇到的Module not found: Can't resolve 'fs'错误,是因为image-size库依赖Node.js的fs模块,而客户端组件(Gallery.tsx)直接导入了Server Action文件,Webpack在打包客户端代码时会尝试解析Server Action的所有依赖,包括image-size,但客户端环境不存在fs模块,导致报错。
解决方案
1. 配置Next.js忽略客户端的fs和path模块
在项目根目录的next.config.js中添加Webpack配置,让客户端打包时跳过这些Node.js专属模块的解析:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config, { isServer }) => { // 仅在客户端打包时忽略fs和path if (!isServer) { config.resolve.fallback = { ...config.resolve.fallback, fs: false, path: false, }; } return config; }, }; export default nextConfig;
2. 修正Server Action中的数据截取逻辑
你的getImages函数当前的循环逻辑存在错误,会导致每次只返回少量数据(甚至1条),应该改为从data中直接截取对应范围的条目:
// /actions/getImages.ts 'use server' import { promises as fs } from 'fs'; import sizeOf from 'image-size'; import type { ImageProps } from "../utils/types"; export const getImages = async (offset: number, limit: number) => { try { const file = await fs.readFile('./public/data-large.json', 'utf8'); const data = JSON.parse(file); // 截取从offset开始的limit条数据,避免超出数组长度 const slicedData = data.slice(offset, Math.min(offset + limit, data.length)); // 并行处理图片尺寸获取,提升性能 const reducedResults = slicedData.map((entry, idx) => { const dim = sizeOf(`./public/kitties/kitty-${entry.public_id}.jpg`); return { id: offset + idx, height: dim.height, width: dim.width, public_id: entry.public_id, format: entry.format, }; }); return reducedResults; } catch (error: unknown) { console.error(error); throw new Error(`获取图片失败: ${(error as Error).message}`); } }
3. 验证Server Action的调用
确保在客户端组件中调用Server Action时,Next.js正确将其路由到服务端执行:
- 确认
'use server'指令在Server Action文件的最顶部(不能有任何代码或注释在它之前) - 客户端组件中导入Server Action的方式正确,无需额外处理,Next.js会自动处理服务端调用
额外提示
image-size库在服务端运行是没问题的,但不要在客户端代码中直接调用它- 如果你使用的是Next.js App Router,建议将Server Action放在
app/actions目录下,Next.js会自动识别并隔离服务端代码
内容的提问来源于stack exchange,提问作者Finer Recliner
相关产品推荐
相关产品推荐

