NextJS 14.1.0构建遇TypeError: r is not a function错误求解决方案
解决NextJS 14.1.0和Pubnub兼容的坑
问题根源
NextJS 14的App Router默认会对页面做服务器端预渲染,而Pubnub的React Provider依赖浏览器环境的API,在服务器端执行时就会触发不兼容错误——你看到的hexoid is not a function警告,是Formidable依赖的工具在服务端跑不起来,本质还是Pubnub在服务端初始化时调用了只有浏览器能用的代码。
具体解决办法
1. 让PubNubProvider只在客户端加载
在App Router里,要么用'use client'指令把Pubnub相关代码限制在客户端执行,要么动态导入时禁用SSR:
方式一:单独写个客户端专用的Provider组件
// app/pubnub-provider-client.js 'use client'; import { PubNubProvider } from 'pubnub-react'; import PubNub from 'pubnub'; // 在这里初始化Pubnub实例,确保只在客户端跑 const pubnubInstance = new PubNub({ publishKey: '你的发布密钥', subscribeKey: '你的订阅密钥', // 其他配置按需添加 }); export default function ClientPubNubProvider({ children }) { return <PubNubProvider client={pubnubInstance}>{children}</PubNubProvider>; }
然后在根布局里引入这个组件:
// app/layout.js import ClientPubNubProvider from './pubnub-provider-client'; export default function RootLayout({ children }) { return ( <html lang="zh-CN"> <body> <ClientPubNubProvider>{children}</ClientPubNubProvider> </body> </html> ); }
方式二:动态导入并禁用SSR
// app/layout.js import dynamic from 'next/dynamic'; import PubNub from 'pubnub'; // 动态导入Provider,指定只在客户端渲染 const PubNubProvider = dynamic(() => import('pubnub-react').then(mod => mod.PubNubProvider), { ssr: false, loading: () => <div>加载中...</div> // 可选加载占位,不需要可删除 }); export default function RootLayout({ children }) { return ( <html lang="zh-CN"> <body> <PubNubProvider client={new PubNub({ publishKey: '你的发布密钥', subscribeKey: '你的订阅密钥', })}>{children}</PubNubProvider> </body> </html> ); }
2. 升级Pubnub版本试试
说不定官方已经修复了NextJS 14的兼容问题,直接更新到最新稳定版:
npm install pubnub@latest pubnub-react@latest
3. 给Formidable做服务端排除(针对hexoid警告)
如果升级后还能看到hexoid is not a function警告,就在next.config.js里配置下,让Formidable只在客户端打包:
// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config) => { config.externals.push('formidable'); return config; }, }; module.exports = nextConfig;
4. 页面用Pubnub hooks要加客户端指令
如果你的页面里用了usePubNub这类hooks,必须在页面组件顶部加'use client',确保这些hooks只在客户端执行:
// app/page.js 'use client'; import { usePubNub } from 'pubnub-react'; export default function Home() { const pubnub = usePubNub(); // 你的页面逻辑 return <div>首页</div>; }
内容的提问来源于stack exchange,提问作者Adhi
相关产品推荐
相关产品推荐

