Next.js集成@uiw/react-markdown-editor报错:ResizeObserver is not defined
解决Next.js集成@uiw/react-markdown-editor时ResizeObserver未定义的错误
这个错误是因为Next.js的服务端渲染(SSR)环境中不存在浏览器专属的ResizeObserver API,而@uiw/react-markdown-editor的全屏功能直接依赖了这个API。以下是几种可行的解决方法:
方法一:动态导入组件并禁用SSR
直接用Next.js的dynamic方法导入编辑器组件,强制在客户端渲染,避开SSR环境:
import dynamic from 'next/dynamic'; // 动态导入编辑器,禁用SSR const MarkdownEditor = dynamic(() => import('@uiw/react-markdown-editor'), { ssr: false, loading: () => <div>加载编辑器中...</div>, }); // 在页面组件中使用 export default function EditorPage() { return <MarkdownEditor />; }
方法二:全局模拟ResizeObserver(适合需要SSR的场景)
如果你的页面需要保持SSR渲染,可以在全局环境中模拟一个空的ResizeObserver实现,让服务端渲染时不报错:
Pages Router 配置(pages/_document.js)
import Document, { Html, Head, Main, NextScript } from 'next/document'; class MyDocument extends Document { static async getInitialProps(ctx) { const initialProps = await Document.getInitialProps(ctx); return initialProps; } render() { return ( <Html> <Head /> <body> <Main /> <NextScript /> {/* 模拟ResizeObserver */} <script dangerouslySetInnerHTML={{ __html: ` if (typeof ResizeObserver === 'undefined') { window.ResizeObserver = class ResizeObserver { constructor(callback) { this.callback = callback; } observe() {} unobserve() {} disconnect() {} }; } ` }} /> </body> </Html> ); } } export default MyDocument;
App Router 配置(app/layout.js)
'use client'; import { useEffect } from 'react'; export default function RootLayout({ children }) { useEffect(() => { // 在客户端模拟ResizeObserver if (typeof ResizeObserver === 'undefined') { window.ResizeObserver = class ResizeObserver { constructor(callback) { this.callback = callback; } observe() {} unobserve() {} disconnect() {} }; } }, []); return ( <html lang="zh-CN"> <body>{children}</body> </html> ); }
方法三:转译依赖模块(配合动态导入)
如果动态导入仍有问题,可以用next-transpile-modules转译@uiw/react-markdown-editor:
- 安装依赖:
npm install next-transpile-modules --save-dev
- 修改next.config.js:
const withTM = require('next-transpile-modules')(['@uiw/react-markdown-editor']); const nextConfig = { // 你的其他Next.js配置 }; module.exports = withTM(nextConfig);
之后再配合方法一的动态导入使用即可。
注:你之前安装的
@react-hook/resize-observer无法解决问题,因为该编辑器内部直接调用了全局的ResizeObserver,而非使用这个Hook封装的版本。
内容的提问来源于stack exchange,提问作者Quiet Coder
相关产品推荐
相关产品推荐

