Leaflet 在通过 CDN 而不是通过 npm 包使用时呈现 Windy 地图
Leaflet renders Windy map when used via CDN but not via npm pakcage
我正在通过 CDN 在 React 中使用 Leaflet with Windy,效果很好:
在index.js中:
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>
<script src="https://api.windy.com/assets/map-forecast/libBoot.js"></script>
React 组件:
export const renderMap = (): void => {
const options = {
key: 'xyz',
lat: 41.3,
lon: 2.1,
zoom: 10,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).windyInit(options, (windyAPI: any) => {
const { map } = windyAPI;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).L.popup()
.setLatLng([41.3, 2.1])
.setContent(':)')
.openOn(map);
});
};
但是我希望能够使用 leaflet npm 包,而不是 CDN。当我导入包时,它已定义但 Windy 抛出错误:
libBoot.js:3 Leaflet library is missing
在index.js中:
<script src="https://api.windy.com/assets/map-forecast/libBoot.js"></script>
React 组件:
import L from 'leaflet';
export const renderMap = (): void => {
console.log('L', L); // defined - object is present
const options = {
key: 'xyz',
lat: 41.3,
lon: 2.1,
zoom: 10,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).windyInit(options, (windyAPI: any) => {
const { map } = windyAPI;
L.popup()
.setLatLng([41.3, 2.1])
.setContent(':)')
.openOn(map);
});
};
关于在线设置的信息很少,因为 Windy 服从 Leaflet,而 Leaflet 服从 Windy。 Leaflet 快速入门指南或其 github.
中没有任何信息
进行这项工作的正确方法是什么
“Leaflet library is missing”错误仅仅是由于这些JS库的加载顺序:
https://github.com/windycom/API/tree/master/hello-world#hello-world
Load the Leaflet library at the beginning of your script and after that the Windy API library from URL https://api.windy.com/assets/map-forecast/libBoot.js
.
- 当您在 HTML 页面中明确自己编写
<script>
标签(通过 CDN 加载它们)时,您正确地首先加载了 Leaflet,然后是 Windy
- 但是当你
import
Leaflet,webpack(当你使用 React 时,它是默认的构建引擎)bundles 它与你的应用程序代码,默认情况下它会插入<script>
标记最后在 HTML 页面的 <body>
中,因此使其在 Windy 之后加载(然后抛出错误消息)
- 当您重新引入
<script>
标签以从 node_modules
文件夹加载 Leaflet 时,我猜您是先将其放回去(即在 Windy 标签之前);然而,这仅适用于开发,因为该 node_modules
文件夹在生产中不可用。
最简单的解决方案是,如果可以从本地文件(或 npm 包)而不是从其 URL (/ CDN) 加载 Windy 库:在这种情况下,您只需 import
它在 Leaflet 之后,webpack 将按顺序打包它们。
然而,Windy 很可能会根据其位置自行施展魔法,例如加载 CSS:
The Leaflet CSS is loaded automatically.
虽然可以解决 CSS 的这种行为,但很可能它对其他东西也有一些魔力(例如访问其数据和层)。
因此,如果我们假设我们必须 从 CDN 加载 Windy,但是(无论出于何种原因)我们绝对准备好从 npm(而不是从CDN 也是如此,我们知道它可以很好地且轻松地工作),我们必须找到一种方法以某种方式强制 webpack 加载顺序。
我们现在显然已经脱离了 webpack 的主要用例,因为在这种特定情况下,我们仍然希望捆绑 Leaflet,但是从 URL 和 after[=63 加载 Windy =] Leaflet,但显然在我们的应用程序代码之前。
我看到至少 2 个可能的(显然是 hacky)解决方案:
- 在我们的应用程序代码中为 Windy 动态生成
<script>
标签;这确保它在 Leaflet 之后加载;但我们必须延迟执行依赖于 Windy 的应用程序部分(例如,通过将其包装在 setTimeout
中,理想情况下检查 Windy 现在是否可用,因为它的加载延迟可能会有所不同)
- 在我们的代码中使用一些 webpack 插件
import
Windy,但 webpack 实际上仍然从 URL 加载它:例如使用具有特定配置的 dynamic-cdn 来指定 URL;不确定仍然有正确的加载顺序是否容易,因为它可能无法识别对 Leaflet 的依赖性。
综上所述,在这种情况下,我们可能仍然质疑是否需要从 npm 加载 Leaflet(因为在 Windy 之前从 CDN 加载它是一件轻而易举的事)。
考虑到您必须为 Windy 执行 any
的转换,我发现您实际上使用的是 TypeScript。因此,您可能希望使用 Leaflet 打字,当您 import
它(并且已经安装 @types/leaflet
)时,这几乎自然而然地出现了,给您的印象是必须从 npm 加载它才能使这些打字工作。在这种情况下,我们可以利用类型和实际运行时代码是两个独立事物这一事实。在这种情况下,你仍然可以在你的代码中 import
Leaflet 并从它的类型中获益,但是指示 webpack 它不应该被捆绑;您将使它在外部可用,通常是因为您从 CDN 加载。参见 webpack 的 externals 选项。这样,您就可以两全其美:您可以自由地以自己的方式加载 Leaflet,在 Windy 之前明确加载 Leaflet,并且仍然有 Leaflet 类型。
我正在通过 CDN 在 React 中使用 Leaflet with Windy,效果很好:
在index.js中:
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>
<script src="https://api.windy.com/assets/map-forecast/libBoot.js"></script>
React 组件:
export const renderMap = (): void => {
const options = {
key: 'xyz',
lat: 41.3,
lon: 2.1,
zoom: 10,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).windyInit(options, (windyAPI: any) => {
const { map } = windyAPI;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).L.popup()
.setLatLng([41.3, 2.1])
.setContent(':)')
.openOn(map);
});
};
但是我希望能够使用 leaflet npm 包,而不是 CDN。当我导入包时,它已定义但 Windy 抛出错误:
libBoot.js:3 Leaflet library is missing
在index.js中:
<script src="https://api.windy.com/assets/map-forecast/libBoot.js"></script>
React 组件:
import L from 'leaflet';
export const renderMap = (): void => {
console.log('L', L); // defined - object is present
const options = {
key: 'xyz',
lat: 41.3,
lon: 2.1,
zoom: 10,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).windyInit(options, (windyAPI: any) => {
const { map } = windyAPI;
L.popup()
.setLatLng([41.3, 2.1])
.setContent(':)')
.openOn(map);
});
};
关于在线设置的信息很少,因为 Windy 服从 Leaflet,而 Leaflet 服从 Windy。 Leaflet 快速入门指南或其 github.
中没有任何信息 进行这项工作的正确方法是什么“Leaflet library is missing”错误仅仅是由于这些JS库的加载顺序:
https://github.com/windycom/API/tree/master/hello-world#hello-world
Load the Leaflet library at the beginning of your script and after that the Windy API library from URL
https://api.windy.com/assets/map-forecast/libBoot.js
.
- 当您在 HTML 页面中明确自己编写
<script>
标签(通过 CDN 加载它们)时,您正确地首先加载了 Leaflet,然后是 Windy - 但是当你
import
Leaflet,webpack(当你使用 React 时,它是默认的构建引擎)bundles 它与你的应用程序代码,默认情况下它会插入<script>
标记最后在 HTML 页面的<body>
中,因此使其在 Windy 之后加载(然后抛出错误消息) - 当您重新引入
<script>
标签以从node_modules
文件夹加载 Leaflet 时,我猜您是先将其放回去(即在 Windy 标签之前);然而,这仅适用于开发,因为该node_modules
文件夹在生产中不可用。
最简单的解决方案是,如果可以从本地文件(或 npm 包)而不是从其 URL (/ CDN) 加载 Windy 库:在这种情况下,您只需 import
它在 Leaflet 之后,webpack 将按顺序打包它们。
然而,Windy 很可能会根据其位置自行施展魔法,例如加载 CSS:
The Leaflet CSS is loaded automatically.
虽然可以解决 CSS 的这种行为,但很可能它对其他东西也有一些魔力(例如访问其数据和层)。
因此,如果我们假设我们必须 从 CDN 加载 Windy,但是(无论出于何种原因)我们绝对准备好从 npm(而不是从CDN 也是如此,我们知道它可以很好地且轻松地工作),我们必须找到一种方法以某种方式强制 webpack 加载顺序。
我们现在显然已经脱离了 webpack 的主要用例,因为在这种特定情况下,我们仍然希望捆绑 Leaflet,但是从 URL 和 after[=63 加载 Windy =] Leaflet,但显然在我们的应用程序代码之前。
我看到至少 2 个可能的(显然是 hacky)解决方案:
- 在我们的应用程序代码中为 Windy 动态生成
<script>
标签;这确保它在 Leaflet 之后加载;但我们必须延迟执行依赖于 Windy 的应用程序部分(例如,通过将其包装在setTimeout
中,理想情况下检查 Windy 现在是否可用,因为它的加载延迟可能会有所不同) - 在我们的代码中使用一些 webpack 插件
import
Windy,但 webpack 实际上仍然从 URL 加载它:例如使用具有特定配置的 dynamic-cdn 来指定 URL;不确定仍然有正确的加载顺序是否容易,因为它可能无法识别对 Leaflet 的依赖性。
综上所述,在这种情况下,我们可能仍然质疑是否需要从 npm 加载 Leaflet(因为在 Windy 之前从 CDN 加载它是一件轻而易举的事)。
考虑到您必须为 Windy 执行 any
的转换,我发现您实际上使用的是 TypeScript。因此,您可能希望使用 Leaflet 打字,当您 import
它(并且已经安装 @types/leaflet
)时,这几乎自然而然地出现了,给您的印象是必须从 npm 加载它才能使这些打字工作。在这种情况下,我们可以利用类型和实际运行时代码是两个独立事物这一事实。在这种情况下,你仍然可以在你的代码中 import
Leaflet 并从它的类型中获益,但是指示 webpack 它不应该被捆绑;您将使它在外部可用,通常是因为您从 CDN 加载。参见 webpack 的 externals 选项。这样,您就可以两全其美:您可以自由地以自己的方式加载 Leaflet,在 Windy 之前明确加载 Leaflet,并且仍然有 Leaflet 类型。