繁体   English   中英

使用 Next.js 动态导入节点模块

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM