如何构建兼容NextJS 15的客户端与服务端分离类库?
解决Next.js 15类库客户端/服务端代码分离问题
1. 重构类库目录结构
先按环境拆分代码目录,明确各模块的运行环境:
devso-nextjs-library/ ├── src/ │ ├── client/ # 客户端专属组件/代码(需加'use client') │ │ ├── index.ts │ │ ├── TextField.tsx │ │ ├── PrimaryButton.tsx │ │ └── FormButtonContainer.tsx │ ├── server/ # 服务端专属代码(Server Actions、服务端组件) │ │ ├── index.ts │ │ ├── FormServer.tsx │ │ └── FormServerState.ts │ └── shared/ # 共享工具/类型(无环境依赖) │ ├── index.ts │ ├── InputType.ts │ └── ZodValidationError.ts ├── package.json └── tsconfig.json
目录职责说明
- client目录:存放所有带交互逻辑、依赖React客户端Hooks(如useEffect、useState)的组件,所有文件顶部必须添加
'use client'指令,包括该目录的index.ts入口文件。 - server目录:存放Server Actions、服务端组件(无需
'use client'),确保这类代码仅在服务端执行。 - shared目录:存放通用类型、无副作用的工具函数,比如枚举、验证工具类,可在客户端和服务端安全复用。
每个目录的index.ts负责导出内部内容,示例:
// src/client/index.ts 'use client'; export { TextField } from './TextField'; export { PrimaryButton } from './PrimaryButton'; export { FormButtonContainer } from './FormButtonContainer';
// src/server/index.ts export { FormServer } from './FormServer'; export { FormServerState } from './FormServerState';
// src/shared/index.ts export { InputType } from './InputType'; export { ZodValidationError } from './ZodValidationError';
2. 修改package.json配置
2.1 更新exports字段
添加子路径导出,让主应用可以按需导入不同环境的代码:
{ "name": "devso-nextjs-library", "version": "1.0.0", "main": "dist/index.js", "module": "dist/index.mjs", "types": "dist/types/index.d.ts", "exports": { ".": "./dist/index.js", "./client": "./dist/client/index.js", "./server": "./dist/server/index.js", "./shared": "./dist/shared/index.js", "./package.json": "./package.json" }, "typesVersions": { "*": { "client": ["dist/types/client/index.d.ts"], "server": ["dist/types/server/index.d.ts"], "shared": ["dist/types/shared/index.d.ts"] } }, // 其他原有字段保持不变 }
2.2 调整build脚本
修改tsup命令,同时编译三个入口文件,生成对应目录的产物:
{ "scripts": { "build": "tsup src/client/index.ts src/server/index.ts src/shared/index.ts --format esm,cjs --dts --out-dir dist" } }
3. 主应用按需导入
现在主应用可以根据场景导入对应路径的代码,彻底避免环境冲突:
// 导入客户端组件 import { TextField, PrimaryButton, FormButtonContainer } from 'devso-nextjs-library/client'; // 导入服务端相关代码 import { FormServer, FormServerState } from 'devso-nextjs-library/server'; // 导入共享类型/工具 import { InputType, ZodValidationError } from 'devso-nextjs-library/shared';
关键注意事项
- 客户端组件必须全局标记
'use client':client目录的入口文件也要加该指令,确保整个模块被Next.js识别为客户端代码。 - Server Actions严格隔离:所有Server Actions必须放在server目录,禁止在客户端代码中直接导入或调用。
- 共享代码无环境依赖:shared目录下的代码不能包含客户端专属API(如
window)或服务端私有变量,保证跨环境兼容性。
内容的提问来源于stack exchange,提问作者Boardy
相关产品推荐
相关产品推荐

