javascript - Leaflet 在通过 CDN 使用而不是通过 npm 包使用时呈现 Windy map

标签 javascript reactjs leaflet

我正在使用 LeafletWindy通过 CDN 在 React 中运行良好:
在 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);
    });
};
但是我希望能够使用传单 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 npm package 完成这项工作的正确方法是什么?

最佳答案

“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.


  • 当你写 <script>在 HTML 页面中明确标记自己(通过 CDN 加载它们),您首先正确加载 Leaflet,然后是 Windy
  • 但是当你 import Leaflet、webpack(这是你使用 React 时的默认构建引擎)将它与你的应用程序代码捆绑在一起,默认情况下它会插入 <script><body> 中标记最后一个您的 HTML 页面,因此使其在 Windy 之后加载(然后引发错误消息)
  • 当您重新介绍您的 <script>标签以从您的 node_modules 加载传单文件夹,我猜你先把它放回去(即在 Windy 标签之前);但是,这仅在开发中有效,因为 node_modules文件夹在生产中不可用。

  • 对您来说最简单的解决方案是如果可以从本地文件(或 npm 包)而不是从其 URL(/CDN)加载 Windy 库:在这种情况下,您只需 import它在 Leaflet 之后,webpack 将按该顺序捆绑它们。
    然而,Windy 很可能会根据其位置本身执行一些魔法,例如加载 CSS:

    The Leaflet CSS is loaded automatically.


    虽然可以解决 CSS 的这种行为,但它很可能对其他东西也有一些魔力(例如,访问它的数据和层)。
    因此,如果我们假设我们必须从 CDN 加载 Windy,但是(无论出于何种原因)我们完全准备好仍然从 npm 加载 Leaflet(而不是从 CDN 加载,我们知道它工作正常且容易),我们必须找到一种方法以某种方式强制 webpack 加载顺序。
    我们现在显然已经跳出了 webpack 主要用例,因为在这种特定情况下,我们仍然希望捆绑 Leaflet,但是从 URL 和 Leaflet 之后加载 Windy,但显然是在我们的应用程序代码之前。
    我看到至少 2 种可能的(显然是 hacky)解决方案:
  • 生成<script>在我们的应用程序代码中动态标记 Windy;这确保它在 Leaflet 之后加载;但是我们必须延迟执行依赖于 Windy 的应用程序部分(例如,通过将其包装在 setTimeout 中,理想情况下检查 Windy 现在是否可用,因为它的加载延迟可能会有所不同)
  • 使用一些 webpack 插件到 import在我们的代码中有风,但 webpack 实际上仍然从 URL 加载它:例如使用 dynamic-cdn用特定的配置来指定 URL;不确定仍然有正确的加载顺序是否容易,因为它可能无法识别对 Leaflet 的依赖关系。

  • 尽管如此,在这种情况下,我们可能仍然质疑从 npm 加载 Leaflet 的需要(因为在 Windy 之前从 CDN 加载它是轻而易举的事)。
    鉴于 any 的类型转换你必须为 Windy 做,我看到你实际上使用了 TypeScript。因此,您可能希望使用传单类型,当您 import 时,这几乎是自然而然的。它(并已安装 @types/leaflet ),给您的印象是必须从 npm 加载它才能使这些类型工作。在这种情况下,我们可以利用类型和实际运行时代码是两个独立的东西这一事实。在这种情况下,您仍然可以 import代码中的传单并从其类型中受益,但指示 webpack 不应捆绑它;您将使其在外部可用,通常是因为您从 CDN 加载。请参阅 webpack 的 externals 选项。这样,您就可以两全其美:您可以自由地以自己的方式加载 Leaflet,在 Windy 之前显式加载,并且仍然具有 Leaflet 类型。

    关于javascript - Leaflet 在通过 CDN 使用而不是通过 npm 包使用时呈现 Windy map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65935523/

    相关文章:

    javascript - 如何在 jQuery 运行时更改图像

    javascript - Ant Design 范围选择器禁用日期数组

    reactjs - Material-UI 线性进度条不起作用

    html - 包含准确填写页面内容所需的 map 的 div

    reactjs - 如何在 react-leaflet 中使用 setRotationAngle

    javascript - 没有从对象中获取数组

    php - ajax - 访问 url : 中设置的变量

    javascript - Jquery 根据单选按钮和选择选项显示和隐藏 div

    javascript - 如何根据变量值动态请求 React 组件?

    r - 使用 R 中的传单库绘制跨越国际日期变更线的路线