Проблема

В моем проекте React я использую листовки v1.7.1 и response-leaflet v3.0.5 .

Когда я пробую пример настройки на странице документации «Настройка» React Router, значок маркера становится разорванным изображением, как обведено красным ниже:

marker broken image

Из документации React Router маркер должен выглядеть так:

correct marker

После проверки атрибут src тега <img>, который содержит изображение маркера, должен быть https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png. Однако после проверки мой атрибут <img> src оказывается похожим на тарабарщину:

gibberish link

Репликация

Подозреваю, что я сделал что-то не так, когда пытался настроить Leaflet и React Leaflet через npm.

Вот моя ссылка на песочницу кода

В качестве альтернативы выполните следующие действия, чтобы воспроизвести проблему:

  1. npx create-react-app leaflet-test

  2. cd leaflet-test/

  3. npm i leaflet react-leaflet

  4. Откройте проект в редакторе кода. Перейдите на App.js и используйте следующий код:

    import React from "react";
    import "./App.css";
    import "leaflet/dist/leaflet.css";
    import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
    
    const styles = {
      mapRoot: {
        height: 400,
      },
    };
    
    export default function App() {
      return (
        <MapContainer
          style={styles.mapRoot}
          center={[51.505, -0.09]}
          zoom={13}
          scrollWheelZoom={false}
        >
          <TileLayer
            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          />
          <Marker position={[51.505, -0.09]}>
            <Popup>
              A pretty CSS3 popup. <br /> Easily customizable.
            </Popup>
          </Marker>
        </MapContainer>
      );
    }
    
  5. npm start

Я не уверен, неправильно ли я настроил Leaflet в React или это ошибка из Leaflet или React Leaflet. Заранее спасибо!

1
AnsonH 17 Янв 2021 в 11:05

2 ответа

Лучший ответ

Для справки: это связано с тем, что веб-пакет переписывает URL-адреса в CSS, тогда как Leaflet использует его для определения путей к изображениям значков.

Подробности см. В выпуске листовки № 4968.

При использовании Leaflet через CDN CSS Leaflet не обрабатывается, поэтому он работает правильно.

Вы все еще можете использовать его через веб-пакет, но вы должны либо использовать только собственные значки, либо явно указать Leaflet, где найти изображения для его значка по умолчанию:

import L from 'leaflet';
delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});

Я также сделал специально для этого случая плагин: leaflet-defaulticon-compatibility

Извлеките все параметры значков листовок по умолчанию из CSS, в частности все URL-адреса изображений значков, чтобы улучшить совместимость с компоновщиками и платформами, которые изменяют URL-адреса в CSS.

import 'leaflet/dist/leaflet.css';
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css'; // Re-uses images from ~leaflet package
import * as L from 'leaflet';
import 'leaflet-defaulticon-compatibility';
1
ghybs 17 Янв 2021 в 13:55

Благодаря комментарию FoundingBox выясняется, что это ошибка React Leaflet.

Уже существует ветка проблемы GitHub относительно этой ошибки и этот комментарий предложил следующее решение:

ХОРОШО. Оказывается, проблема была вызвана включением CSS листовки в импорт компонента.

Я только что добавил ссылку на файл leaflet.css, размещенный в CDN, и он работает нормально, но было бы хорошо, если бы его можно было исправить для работы с конфигурацией webpack create-response-app.

Другими словами, вот пошаговое руководство:

  1. Удалите import "leaflet/dist/leaflet.css"; из App.js. НЕ импортируйте CSS Leaflet из узловых модулей в какие-либо файлы JS.

  2. Перейдите на сайт public/index.html и включите размещенный в CDN leaflet.css, вставив следующий код в раздел <head> HTML-файла:

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
      integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
      crossorigin=""/>
    

    (Примечание: по этой ссылке используется Leaflet v1.7.1. Чтобы найти код, посетите документацию Leaflet. привязки последней версии Leaflet)

1
AnsonH 17 Янв 2021 в 09:15