Next.js中jQuery报requires a window错误,配置jsdom出现Unexpected token如何解决
Next.js中"jQuery requires a window with a document"报错解决方案
报错根因
- Next.js 默认会在服务端执行组件代码进行预渲染,而jQuery强依赖浏览器环境的
window、document对象,服务端环境不存在这两个对象,所以直接调用jQuery的选择器逻辑就会抛出该错误。 - index.js能正常运行大概率是因为该页面没有用到jQuery相关逻辑,或者刚好开启了客户端渲染模式。
此前方案的问题
你引入jsdom模拟浏览器环境的方案本身是给纯Node.js环境跑jQuery逻辑用的,但在Next.js项目里属于冗余且容易出问题:
- 你遇到的Unexpected token错误大概率是jsdom版本和你当前Node.js/Next.js的版本不兼容,或者是CommonJS导入语法和你项目的ES Module规范冲突导致的。
- 就算解决了语法错误,在服务端用jsdom模拟DOM来跑jQuery逻辑性能极低,完全没必要。
正确解决方案
方案1:把jQuery逻辑限定在客户端执行(兼容现有代码)
只需要保证jQuery相关代码只在浏览器端运行即可:
- 如果用Pages Router或者旧版本Next.js,把jQuery逻辑放到
useEffect钩子中,Next.js的useEffect只会在客户端执行:
import { useEffect } from 'react' // 组件内部代码 useEffect(() => { // 动态导入jquery,只在客户端加载 const $ = require('jquery') var cmdTxt = $('.command .text') // 其他jQuery逻辑 }, [])
- 如果用Next.js 13+ App Router,可以给组件添加客户端组件标记,保证整个组件只会在客户端渲染,再引入jQuery执行逻辑即可:
在install.js文件顶部加一行'use client'。
方案2:完全移除jQuery(最优方案)
你使用的React+Tailwind+DaisyUI技术栈完全不需要jQuery依赖,操作DOM可以用React内置的ref实现,从根本上避免环境不兼容问题:
import { useRef } from 'react' function YourComponent() { const cmdTextRef = useRef(null) // 要操作对应DOM的时候直接访问cmdTextRef.current即可 return <div className="command"> <div className="text" ref={cmdTextRef}>内容</div> </div> }
额外提示
- React技术栈下不要混合使用jQuery做DOM操作,两者的DOM更新逻辑会冲突,容易出现不可预期的渲染问题。
- DaisyUI本身是纯CSS组件库,配合Tailwind不需要任何JS依赖就能实现多选按钮等交互,完全不需要引入jQuery。
内容的提问来源于stack exchange,提问作者lana
相关产品推荐
相关产品推荐

