Why am I getting ReferenceError: self is not defined when I import a client-side library?
Why am I getting ReferenceError: self is not defined when I import a client-side library?
尝试在 Next.js 中创建一个 xterm 反应组件,我被卡住了,因为我无法克服错误消息我已经从来没有过。
我正在尝试导入一个名为 xterm
的 npm 客户端模块,但如果我添加导入行,应用程序就会崩溃。
import { Terminal } from 'xterm'
错误显示为 Server Error... ReferenceError: self is not defined
然后将这段代码显示为 Source
module.exports = require("xterm");
根据我所做的一些研究,这与 Webpack 有关,如果完成类似的事情可能会有所帮助:
output: {
globalObject: 'this'
}
你知道如何解决这个问题吗?
发生错误是因为库需要 Web API 才能工作,当 Next.js pre-renders the page 在服务器端时 Web API 不可用。
在您的情况下,xterm
尝试访问服务器上不存在的 window
对象。要修复它,您必须动态导入 xterm
以便它仅在客户端加载。
在 Next.js.
中有几种方法可以实现这一点
#1 使用动态 import()
将 import
移动到组件的 useEffect
,然后动态导入库并在其中添加逻辑。
useEffect(() => {
const initTerminal = async () => {
const { Terminal } = await import('xterm')
const term = new Terminal()
// Add logic with `term`
}
initTerminal()
}, [])
#2 使用 next/dynamic
和 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
})
作为 替代方案,您可以在使用 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
}
)
尝试在 Next.js 中创建一个 xterm 反应组件,我被卡住了,因为我无法克服错误消息我已经从来没有过。
我正在尝试导入一个名为 xterm
的 npm 客户端模块,但如果我添加导入行,应用程序就会崩溃。
import { Terminal } from 'xterm'
错误显示为 Server Error... ReferenceError: self is not defined
然后将这段代码显示为 Source
module.exports = require("xterm");
根据我所做的一些研究,这与 Webpack 有关,如果完成类似的事情可能会有所帮助:
output: {
globalObject: 'this'
}
你知道如何解决这个问题吗?
发生错误是因为库需要 Web API 才能工作,当 Next.js pre-renders the page 在服务器端时 Web API 不可用。
在您的情况下,xterm
尝试访问服务器上不存在的 window
对象。要修复它,您必须动态导入 xterm
以便它仅在客户端加载。
在 Next.js.
中有几种方法可以实现这一点#1 使用动态 import()
将 import
移动到组件的 useEffect
,然后动态导入库并在其中添加逻辑。
useEffect(() => {
const initTerminal = async () => {
const { Terminal } = await import('xterm')
const term = new Terminal()
// Add logic with `term`
}
initTerminal()
}, [])
#2 使用 next/dynamic
和 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
})
作为 替代方案,您可以在使用 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
}
)