Pourquoi est-ce que j'obtiens ReferenceError: self is not Defined lorsque j'importe la bibliothèque cliente ?
P粉214089349
P粉214089349 2023-10-21 12:53:53
0
1
736

Je suis bloqué en essayant de créer un composant xterm React dans Next.js parce que je n'arrive pas à me remettre d'un message d'erreur que je n'ai jamais reçu auparavant.

J'essaie d'importer un module client npm appelé xterm mais si j'ajoute la ligne d'importation, l'application plante.

import { Terminal } from 'xterm'

Erreur de lecture 服务器错误... ReferenceError: self is not Defined Affichez ensuite ce code comme Source

module.exports = require("xterm");

D'après certaines recherches que j'ai effectuées, cela est lié à Webpack et cela pourrait être utile si quelque chose comme ceci était fait :

output: {
  globalObject: 'this'
}

Savez-vous comment résoudre ce problème ?

P粉214089349
P粉214089349

répondre à tous(1)
P粉958986070

La raison pour laquelle cette erreur se produit est que la bibliothèque nécessite l'API Web pour fonctionner et lorsque Next.js pré-rend la page côté serveur.

Dans votre cas, xterm 尝试访问服务器上不存在的window 对象。解决方案是避免在服务器上加载 xterm et importez-le dynamiquement pour qu'il ne soit chargé que côté client.

Dans Next.js, il existe plusieurs façons d'y parvenir.


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

Remplacez import 移至组件的 useEffect puis importez dynamiquement la bibliothèque et ajoutez-y une logique.

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

#2 Utilisez next/dynamicssr: false ensemble

Créez un composant et ajoutez-y une logique xterm.

// components/terminal-component
import { Terminal } from 'xterm'

function TerminalComponent() {
    const term = new Terminal()
    // Add logic around `term`
    return <></>
}

export default TerminalComponent

Ensuite, importez dynamiquement le composant lorsqu'il est utilisé.

import dynamic from 'next/dynamic'

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

Comme alternative, vous pouvez ajouter une logique directement lorsque vous utilisez des next/dynamic bibliothèques d'importation dynamique pour éviter de générer des fichiers supplémentaires.

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
    }
)
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal