我正在用leaflet包建一个站点,但是这个包需要window对象,所以我把leaflet做的组件作为动态组件导入,ssr关闭,如下所示:
import dynamic from "next/dynamic";
const MapWithNoSSR = dynamic(() => import("../../map"), {
ssr: false
});
export default function faqOnly(props){
...
return (<> <MapWithNoSSR /></>)
}
Map组件如下所示:
import React, { useEffect, useState, useRef } from "react";
import { OpenStreetMapProvider } from 'leaflet-geosearch';
import "leaflet/dist/leaflet.css";
import 'leaflet/dist/leaflet.css'
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css'
import "leaflet-defaulticon-compatibility";
import dynamic from "next/dynamic";
const L = dynamic(() => import("leaflet"), {
ssr: false,
suspense: true,
loading: () => <p>...</p>
});
function Map(props) {
useEffect(async () => {
if(window === undefined) return
const provider = new OpenStreetMapProvider();
const results = await provider.search({ query: props.adress });
if(results.length > 0 == true){
var map = L.map('map', {
center: [results[0].y, results[0].x],
zoom: 18,
layers: [
L.tileLayer('https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png', {
attribution: ''
}),
]
})
L.marker([results[0].y, results[0].x]).addTo(map)
}else{
document.getElementById("map").style.display = "none"
}
}, [])
return <div id="map" style={{ height: "30vh"}}></div>
}
export default Map;
当我运行npm run build
时,我得到了这个错误:
ReferenceError: window is not defined
at E:\Github\Planer\rl-planer\node_modules\leaflet\dist\leaflet-src.js:230:19
at E:\Github\Planer\rl-planer\node_modules\leaflet\dist\leaflet-src.js:7:66
at Object.<anonymous> (E:\Github\Planer\rl-planer\node_modules\leaflet\dist\leaflet-src.js:10:3)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (E:\Github\Planer\rl-planer\node_modules\leaflet-geosearch\dist\geosearch.js:1:7) {
type: 'ReferenceError'
}
这在开发中工作得很好,但是当我尝试构建项目(下一个构建)时,它在传单包中抛出了一个“窗口未定义”错误,这是我在开发模式下工作时从未出现过的错误。
我看了这里的其他问题,但是似乎把动态导入移到组件之外可以解决除了我之外的所有人的问题。是我太笨了,还是这里有什么问题?
2条答案
按热度按时间v09wglhw1#
也许你根本不需要
next/dynamic
,只需要在useEffect
函数体中使用简单的js动态导入即可。(
useEffect
将仅在客户端上运行)Nextjs有一个看起来非常相似的例子:https://nextjs.org/docs/advanced-features/dynamic-import.(fuse.js页面上的第一个)
更新
好吧,也许在useEffect钩子中移动所有需要窗口的js有点麻烦。只导入整个组件客户端更容易。对我来说,你的示例代码看起来不错--除了你在map文件中再次动态导入leaflet这一事实:
page.jsx
map.jsx
mwkjh3gx2#
我所做的就是创建一个
Map
组件,它包含了leaflet
中使用window
的每个模块,然后使用动态导入的nextjs导入该组件。在我的例子中,我没有对leaflet
模块使用动态导入,而只对Map
组件使用了动态导入。