Vite封装ShadCN库在Next.js App Router中react-hook-form导入错误
解决方案
根因分析
Next.js App Router的RSC(React Server Components)环境会优先读取第三方依赖的react-server条件导出,但react-hook-form的该导出分支仅包含服务端兼容API(如useFormState),不包含FormProvider、Controller这类客户端专属API。你的UI库在打包时未正确处理这个条件导出逻辑,导致RSC环境下导入了不完整的react-hook-form模块。
库端(Vite项目)修改方案
1. 强制打包时使用react-hook-form的通用导出
在vite.config.ts中配置Rollup,指定react-hook-form的导出条件优先级,跳过react-server:
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], build: { rollupOptions: { external: ['react-hook-form'], // 让消费项目提供依赖,不打包进库 resolve: { conditions: ['browser', 'import', 'require'], // 优先读取通用导出分支 }, }, }, });
2. 标记库中组件为客户端组件
所有依赖react-hook-form的ShadCN组件都属于客户端组件,需在组件文件顶部添加'use client'指令,确保消费项目在RSC环境下正确识别:
'use client'; import { FormProvider, Controller } from 'react-hook-form'; // 组件业务代码...
3. 配置peerDependencies
在库的package.json中将react-hook-form设为peer依赖,确保消费项目使用统一版本的依赖,避免版本冲突:
{ "peerDependencies": { "react-hook-form": "^7.45.0" } }
消费项目(Next.js App Router)修改方案
1. 给导入UI库的组件添加'use client'
在App Router的页面/组件顶部添加指令,强制组件在客户端环境运行,避免RSC触发错误的导出读取:
'use client'; import { YourFormComponent } from 'shadcn-ui-lib'; export default function Page() { return <YourFormComponent />; }
2. 配置Next.js转译UI库
在next.config.js中添加transpilePackages,让Next.js重新编译你的UI库代码,正确处理依赖导出:
/** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ['shadcn-ui-lib'], }; module.exports = nextConfig;
3. 临时覆盖react-hook-form的导出条件(不推荐长期使用)
在消费项目的package.json中添加overrides,移除react-hook-form的react-server导出条件:
{ "overrides": { "react-hook-form": { "package.json": { "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.cjs" }, "./": "./" } } } } }
内容的提问来源于stack exchange,提问作者suamikim
相关产品推荐
相关产品推荐

