React项目转Next.js时signalr报jQuery未找到的解决方法咨询
解决方案
首先确认两个核心问题:
- 原代码执行顺序错误:
require('signalr')执行在window.jQuery = $之前,signalr加载时无法找到挂载在window上的jQuery,本身就存在逻辑缺陷 - Next.js SSR阶段无window对象,依赖window的代码在服务端执行会报错
方案1:改造data-pulse-provider.js适配SSR
仅在客户端环境执行依赖window的逻辑,同时修正执行顺序:
import { logMessage } from './helpers'; import $ from 'jquery'; let DataPulseProvider; // 只有浏览器环境才执行后续逻辑 if (typeof window !== 'undefined') { // 先挂载jQuery到window,再加载signalr window.jQuery = $; require('signalr'); DataPulseProvider = /** @class */ (function () { // ... 原有逻辑保持不变 }()); } export { DataPulseProvider };
注意:使用时需要确保只在客户端侧调用
DataPulseProvider,比如在React组件的useEffect回调中初始化使用,避免服务端渲染时调用到undefined变量。
方案2:无侵入式调用(无需修改原provider文件)
如果不想改动原有data-pulse-provider.js的代码,可以在使用该模块的地方,仅在客户端侧动态导入:
import { useEffect } from 'react'; function YourComponent() { useEffect(() => { // useEffect仅在客户端执行,此时window已存在 const { DataPulseProvider } = require('./data-pulse-provider'); // 初始化使用 const pulseProvider = new DataPulseProvider(); // ... 后续业务逻辑 }, []); return <div>...</div>; }
如果需要全局使用该provider,可以结合Next.js关闭SSR的动态导入:
// 单独封装一个客户端初始化组件 import { useEffect } from 'react'; export default function DataPulseInit() { useEffect(() => { const { DataPulseProvider } = require('./data-pulse-provider'); // 挂载到全局或者状态管理库中供全局调用 window.dataPulse = new DataPulseProvider(); }, []); return null; }
在_app.js中引入该组件时关闭SSR:
import dynamic from 'next/dynamic'; const DataPulseInit = dynamic(() => import('../components/DataPulseInit'), { ssr: false }); export default function App({ Component, pageProps }) { return ( <> <DataPulseInit /> <Component {...pageProps} /> </> ) }
内容的提问来源于stack exchange,提问作者margherita pizza
相关产品推荐
相关产品推荐

