[英]Dynamic Import Node Module With Next.js
使用 react-leaflet 节点模块时出现窗口未定义错误,因为它依赖于窗口,当然 SSR 不支持窗口。 我找到了下一个/动态,但是,我找到的所有示例都显示了如何导入组件而不是节点模块。 是否可以包含节点模块,如果可以,如何? 例如,这是我正在导入的内容,它给出了窗口未定义的错误import { Map, TileLayer, Marker } from 'react-leaflet';
问题是 next.js 动态导入在命名导出上失败
查看react-leaflet 的源代码,我可以看到可以从特定文件访问每个命名导出,例如import Map from 'react-leaflet/lib/Map'
将其与不带 SSR 的动态导入相结合
const Map = dynamic(() => import('react-leaflet/lib/Map'), {
ssr: false
});
这应该对你有用。
使用动态导入获取命名导出的更好方法是执行以下操作:
const NamedExport = dynamic(() => import('package-name').then((module) => module.NamedExport));
注意:这将分块完整'package-name'
包,然后简单地提取命名的导出。 如果您能够像接受的示例一样进入模块包,那可能会更好,因为它可能会给您一个更小的块。
当您在组件上调用该依赖项的组件(Map、TileLayer、Marker)时,就会发生该错误。
当您的应用程序在服务器端呈现时,会出现未定义的窗口,因为窗口对象属于浏览器。
为了避免服务器端window of undefined
错误,您可以在组件中使用process.browser
。
参考: https ://github.com/zeit/next.js/issues/2473?#issuecomment-362119102
我一直在用接受的答案解决类型定义问题,我不想导入整个库。 这就是我想出的:
reexport/index.ts
:
export { Marker, /* any other type you'll need */ } from 'react-leaflet';
然后,在您的组件/页面中,只需从上面的模块中导入任何内容。
const Marker = useMemo(() => dynamic<MarkerProps>(
() => import('./reexport').then(re => re.Marker),
{ ssr: false }
), []);
请注意,我已经在useMemo
钩子中包装了对dynamic
的调用,并且还为道具提供了一个类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.