如何创建兼容Next.js App Router的混编React UI组件库?
解决Next.js App Router兼容库中服务端/客户端组件共存的tsup构建问题
你的核心问题是全局给所有文件添加了"use client"指令,导致原本的服务端组件被强制标记为客户端组件,从而失效。解决思路是只给真正的客户端组件添加该指令,服务端组件保持无指令状态,具体方案如下:
方案1:手动给客户端组件添加"use client"
直接在每个客户端组件的文件最顶部添加:
"use client"; export default function ClientComponent() { // 客户端组件逻辑 }
这种方式最直接,也不容易出错,Next.js会自动识别该文件为客户端组件,服务端组件则保持无指令的状态。
方案2:通过tsup条件配置自动添加banner
如果组件数量多,不想手动逐个添加,可以在tsup.config.ts中配置基于文件路径的条件banner,只给客户端组件目录下的文件添加指令。
假设你的项目结构是:
src/ ├── client-components/ # 所有客户端组件 │ └── ClientComponent.tsx └── server-components/ # 所有服务端组件 └── ServerComponent.tsx
对应的tsup配置如下:
import { defineConfig } from "tsup"; export default defineConfig({ entry: ["src/**/*.tsx"], format: ["esm"], splitting: true, clean: true, banner: { js: (filePath) => { // 仅当文件属于客户端组件目录时,添加"use client" return filePath.includes("client-components") ? `"use client";` : ""; }, }, });
关键注意事项
- 服务端组件绝对不能导入客户端特有的API(如
window对象、useState/useEffect等React客户端钩子),否则即使没有"use client"指令,Next.js也会将其视为客户端组件。 - 确保库的
package.json中设置"type": "module",保证和Next.js App Router的ES模块机制兼容。 - 导出组件时,建议在入口文件(如
index.ts)中明确区分服务端和客户端组件的导出,方便使用者识别。
内容的提问来源于stack exchange,提问作者Explorer
相关产品推荐
相关产品推荐

