Maison  >  Questions et réponses  >  le corps du texte

Pourquoi est-ce que j'obtiens ReferenceError: self is not Defined lorsque j'importe la bibliothèque cliente ?

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粉214089349P粉214089349384 Il y a quelques jours709

répondre à tous(1)je répondrai

  • P粉958986070

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

    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
        }
    )
    

    répondre
    0
  • Annulerrépondre