Heim  >  Fragen und Antworten  >  Hauptteil

Warum erhalte ich „ReferenceError: self is not Defined“, wenn ich die Client-Bibliothek importiere?

Ich stecke beim Versuch, eine xterm React-Komponente in Next.js zu erstellen, fest, weil ich über eine Fehlermeldung, die ich noch nie zuvor erhalten habe, nicht hinwegkomme.

Ich versuche, ein NPM-Clientmodul namens xterm zu importieren, aber wenn ich die Importzeile hinzufüge, stürzt die App ab.

import { Terminal } from 'xterm'

Fehler beim Lesen 服务器错误... ReferenceError: self is not Defined Zeigen Sie diesen Code dann als Source

an
module.exports = require("xterm");

Aus einigen meiner Recherchen geht hervor, dass dies mit Webpack zusammenhängt und es hilfreich sein könnte, wenn so etwas gemacht wird:

output: {
  globalObject: 'this'
}

Wissen Sie, wie Sie dieses Problem lösen können?

P粉214089349P粉214089349364 Tage vor687

Antworte allen(1)Ich werde antworten

  • P粉958986070

    P粉9589860702023-10-22 10:48:55

    出现此错误的原因是该库需要 Web API 才能工作,而当 Next.js 在服务器端预渲染页面

    在您的情况下,xterm 尝试访问服务器上不存在的window 对象。解决方案是避免在服务器上加载 xterm 并动态导入它,以便仅在客户端加载它。

    在 Next.js 中,有多种方法可以实现此目的。


    #1 在 useEffect 内使用动态 import()

    import 移至组件的 useEffect,然后动态导入库并在其中添加逻辑。

    useEffect(() => {
        const initTerminal = async () => {
            const { Terminal } = await import('xterm')
            const term = new Terminal()
            // Add logic with `term`
        }
        initTerminal()
    }, [])
    

    #2 将 next/dynamicssr: false 一起使用

    创建一个组件,在其中添加 xterm 逻辑。

    // components/terminal-component
    import { Terminal } from 'xterm'
    
    function TerminalComponent() {
        const term = new Terminal()
        // Add logic around `term`
        return <></>
    }
    
    export default TerminalComponent
    

    然后在使用时动态导入该组件。

    import dynamic from 'next/dynamic'
    
    const TerminalComponent = dynamic(() => import('<path-to>/components/terminal-component'), {
        ssr: false
    })
    

    作为替代方案,您可以在使用 next/dynamic 动态导入库时直接添加逻辑,以避免产生额外的文件。

    import dynamic from 'next/dynamic'
    
    const Terminal = dynamic(
        {
            loader: () => import('xterm').then((mod) => mod.Terminal),
            render: (props, Terminal) => {
                const term = new Terminal()
                // Add logic with `term`
                return <></>
            }
        },
        {
            ssr: false
        }
    )
    

    Antwort
    0
  • StornierenAntwort