Листовка отображает ветреную карту при использовании через CDN, но не через npm pakcage

#javascript #reactjs #leaflet

#javascript #reactjs #листовка

Вопрос:

Я использую листовку с Windy в React через CDN, которая работает нормально:

в 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>
 

Реагирующий компонент:

 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 листовки

в index.js:

 <script src="https://api.windy.com/assets/map-forecast/libBoot.js"></script>
 

Реагирующий компонент:

 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. В кратком руководстве по запуску листовки или в их github нет никакой информации.

Каков правильный способ заставить это работать, используя пакет Leaflet npm

Комментарии:

1. Пожалуйста, попробуйте использовать последнюю версию leaflet поверх cdn <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script> , она работает?

2. Спасибо @FalkeDesign хорошая мысль. На самом деле это не работает и выдает ошибку, в которой говорится, что требуется версия v1.4.x. Я попробовал версию v1.4.0, и возникает исходная ошибка.

Ответ №1:

Ошибка «Отсутствует библиотека листовки» просто связана с порядком загрузки этих библиотек JS:

https://github.com/windycom/API/tree/master/hello-world#hello-world

Загрузите библиотеку Leaflet в начале вашего скрипта, а затем библиотеку Windy API из URL https://api.windy.com/assets/map-forecast/libBoot.js .

  • когда вы <script> сами явно пишете теги на HTML-странице (чтобы загрузить их через CDN), вы правильно загружаете сначала Leaflet, затем Windy
  • но когда вы import листаете, webpack (который является механизмом сборки по умолчанию при использовании React) связывает его с кодом вашего приложения, и по умолчанию он вставляет <script> тег последним на <body> вашей HTML-странице, поэтому он загружается после Windy (который затем выдает сообщение об ошибке)
  • когда вы повторно вводите свой <script> тег для загрузки листовки из своей node_modules папки, я предполагаю, что вы сначала возвращаете его обратно (т. Е. Перед тегом Windy); однако это будет работать только в разработке, потому что node_modules эта папка не будет доступна в производстве.

Самым простым решением для вас было бы, если бы Windy library можно было загружать из локального файла (или пакета npm), а не из его URL (/ CDN): в этом случае вы просто import добавляете его после Leaflet, и webpack будет связывать их в таком порядке.

Однако вполне вероятно, что Windy сам выполняет какую-то магию в зависимости от своего местоположения, например, для загрузки CSS:

CSS листовки загружается автоматически.

Хотя можно было бы обойти это поведение для CSS, вероятно, оно также выполняет некоторые действия для других вещей (например, доступ к его данным и слоям).

Итак, если мы предполагаем, что мы должны загружать Windy из CDN, но (по какой-либо причине) мы абсолютно готовы к головной боли при загрузке Leaflet из npm (а не из CDN, что, как мы знаем, работает нормально и легко), нам нужно найти способ принудительно загрузить порядок загрузки webpackкаким-то образом.

Теперь мы явно выходим за рамки основного варианта использования webpack, потому что в этой конкретной ситуации мы все еще хотим, чтобы Leaflet был в комплекте, но загружал Windy с URL и после Leaflet, но, очевидно, перед нашим кодом приложения.

Я вижу как минимум 2 возможных (явно хакерских) решения:

  • генерируйте <script> тег Windy динамически в коде нашего приложения; это гарантирует, что он загружается после Leaflet; но мы должны отложить выполнение части нашего приложения, которая зависит от Windy (например, обернув его в a setTimeout , в идеале проверив, что Windy теперь доступен, поскольку его задержка загрузки может отличаться)
  • используйте некоторые плагины webpack для import Windy в нашем коде, но фактически webpack все равно загружает его с URL: например, используя dynamic-cdn с определенной конфигурацией для указания URL; не уверен, что было бы легко сохранить правильный порядок загрузки, так как он может не распознать зависимость от Leaflet.

Несмотря на все сказанное, мы все еще можем усомниться в необходимости загрузки Leaflet из npm в этом случае (поскольку загрузка его из CDN перед Windy — это легкий ветерок).

Учитывая приведения any , которые вам нужно выполнить для Windy, я вижу, что вы на самом деле используете TypeScript. Поэтому вы можете захотеть иметь доступные типы листовок, которые появляются почти естественно, когда вы import его (и установили @types/leaflet ), создавая впечатление, что он должен быть загружен из npm, чтобы эти типы работали. В этом случае мы можем использовать тот факт, что типы и фактический код времени выполнения — это две разные вещи. В этом случае вы все равно можете import использовать Leaflet в своем коде и извлекать выгоду из его типа, но указываете webpack, что он не должен быть в комплекте; что вы сделаете его доступным извне, обычно потому, что вы загружаете с CDN. Смотрите опцию externals в webpack. Таким образом, вы получаете лучшее из обоих миров: у вас есть свобода загружать листовку по-своему, здесь явно перед Windy, и у вас все еще есть типы листовок.