将HTML网站转换为Next.js应用时Cash-Dom运行报错如何解决?
问题原因
Next.js默认存在服务端渲染(SSR/SSG/ISR)环节,该环节运行在Node.js环境,不存在window、document等浏览器专属的全局DOM对象。而Cash-Dom是面向浏览器环境的DOM操作库,强依赖上述浏览器全局对象,如果你直接在组件顶层导入Cash-Dom、或者直接执行Cash相关的DOM操作代码,服务端渲染阶段就会因找不到全局对象抛出截图中的报错。
修复方案
如果你使用的是Next.js 13+ App Router
- 在所有用到Cash-Dom的组件顶部添加
'use client'指令,标记组件为客户端组件 - 把所有Cash-Dom相关的初始化、DOM操作逻辑都放到
useEffect钩子中执行,useEffect仅会在客户端环境运行
示例代码:
'use client' import { useEffect } from 'react' export default function MyComponent() { useEffect(() => { // 动态导入Cash-Dom避免服务端加载 const cash = require('cash-dom').default // 挂载到全局window供原有代码调用(如果你的旧代码依赖全局$) window.$ = cash // 此处写入你原有基于Cash-Dom的业务逻辑 }, []) return <div>你的组件内容</div> }- 在所有用到Cash-Dom的组件顶部添加
如果你使用的是Next.js Pages Router
可以使用next/dynamic导入用到Cash-Dom的组件,关闭该组件的服务端渲染:import dynamic from 'next/dynamic' // 关闭SSR,组件仅在客户端加载渲染 const CashComponent = dynamic(() => import('../components/CashComponent'), { ssr: false }) export default function Page() { return <CashComponent /> }也可以直接在页面组件的
useEffect或者componentDidMount生命周期中执行Cash-Dom相关逻辑,这两个生命周期都仅在客户端触发。额外注意事项
不要在组件顶层作用域直接执行任何Cash-Dom相关的DOM操作、全局挂载逻辑,所有相关逻辑必须包裹在客户端专属的执行上下文内。
内容的提问来源于stack exchange,提问作者Himanshu Jain
相关产品推荐
相关产品推荐

