(Webpack) Почему я получаю сообщение ReferenceError: self не определено в Next.js, когда я пытаюсь импортировать клиентскую библиотеку?

Пытаясь создать компонент реакции xterm в Next.js, я застрял, поскольку я не могу справиться с сообщением об ошибке, которого у меня никогда не было.

Я пытаюсь импортировать клиентский модуль npm с именем xterm, но если я добавлю строку импорта, произойдет сбой приложения.

import { Terminal } from 'xterm'

Ошибка читается как Server Error... ReferenceError: self is not defined, а затем показывает этот фрагмент кода как Source.

module.exports = require("xterm");

Согласно некоторым исследованиям, которые я провел, это связано с Webpack, и можно было бы помочь, если бы было сделано что-то вроде этого:

output: {
  globalObject: 'this'
}

Вы знаете, как это исправить? Заранее спасибо! ????


person Lord Reptilia    schedule 08.02.2021    source источник


Ответы (1)


Ошибка возникает из-за того, что xterm пытается получить доступ к объекту window, который недоступен на стороне сервера. Чтобы исправить это, вы можете динамически импортировать xterm с ssr: false, чтобы он загружался только на стороне клиента.

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

Редактировать. В качестве альтернативы вы можете создать новый компонент, в который вы импортируете 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
})
person juliomalves    schedule 08.02.2021
comment
Благодарю за ваш ответ! Я пробовал это, но, похоже, он не импортирует конструктор { Terminal }. Вместо этого я получаю someobject = {} со свойствами $$typeof: и render:. Знаете ли вы, почему это может быть? - person Lord Reptilia; 08.02.2021
comment
Я решил это, выполнив import { Terminal } from 'xterm' в своем компоненте, а затем импортировав этот <Component /> с функцией dynamic() на родительской странице. Я мог бы отметить ваш ответ как правильный, если бы вы упомянули эту деталь. - person Lord Reptilia; 08.02.2021
comment
Ах да, я предположил, что Terminal был компонентом - Next.js dynamic должен возвращать компонент. Я обновлю свой ответ. - person juliomalves; 08.02.2021