VueでLeafletを使ったときにマーカーが表示されず、404エラー


現象

npmでインストールしたleafletでマップを表示させようとすると
マップは表示されるがマーカーが表示されない。

<template>
  <div class="folium-map" id="mymap"></div>
</template>

<script>
import "leaflet/dist/leaflet.css";
import L from "leaflet";

export default {
  mounted() {
    var mymap = L.map("mymap").setView([35.65809922, 139.74135747], 10);
    L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution:
        'Map data &copy; <a href="https://openstreetmap.org">OpenStreetMap</a>',
      maxZoom: 18
    }).addTo(mymap);

    L.marker([35.710143, 139.810708], { title: "スカイツリー" }).addTo(mymap);
    L.marker([35.658772, 139.745422], { title: "東京タワー" }).addTo(mymap);
  }
};
</script>

<style>
html,
body {
  width: 600px;
  height: 600px;
  margin: 0;
  padding: 0;
}

#mymap {
  position: relative;
  width: 100%;
  height: 600px;
  left: 0%;
  top: 0%;
}
</style>

デベロッパーツール上のエラー

imageが見つけられてないらしい

対処方法

既知のLeafletのバグの模様。
Leaflet内部のiconのパスが正しく読み込めていない。
いくつか対応方法はあるが、基本的にimagesのパスを再定義してあげれば良い。
注意点としては、iconUrlなどのUrlだけ再定義してしまうと、Anchorの位置が狂ってしまい
拡大縮小したときにマーカの位置がずれてしまうので、Anchorなども含めて再定義。

import icon from "leaflet/dist/images/marker-icon.png";
import iconRetina from "leaflet/dist/images/marker-icon-2x.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";
    let DefaultIcon = L.icon({
      iconUrl: icon,
      iconRetinaUrl: iconRetina,
      shadowUrl: iconShadow,
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -34],
      tooltipAnchor: [16, -28],
      shadowSize: [41, 41]
    });
    L.Marker.prototype.options.icon = DefaultIcon;

対処後の結果

<template>
  <div class="folium-map" id="mymap"></div>
</template>

<script>
import "leaflet/dist/leaflet.css";
import L from "leaflet";
// 追加
import icon from "leaflet/dist/images/marker-icon.png";
import iconRetina from "leaflet/dist/images/marker-icon-2x.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";

export default {
  mounted() {
    var mymap = L.map("mymap").setView([35.65809922, 139.74135747], 10);
    L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
      attribution:
        'Map data &copy; <a href="https://openstreetmap.org">OpenStreetMap</a>',
      maxZoom: 18
    }).addTo(mymap);

    // 追加
    let DefaultIcon = L.icon({
      iconUrl: icon,
      iconRetinaUrl: iconRetina,
      shadowUrl: iconShadow,
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -34],
      tooltipAnchor: [16, -28],
      shadowSize: [41, 41]
    });
    L.Marker.prototype.options.icon = DefaultIcon;

    L.marker([35.710143, 139.810708], { title: "スカイツリー" }).addTo(mymap);
    L.marker([35.658772, 139.745422], { title: "東京タワー" }).addTo(mymap);
  }
};
</script>

<style>
html,
body {
  width: 600px;
  height: 600px;
  margin: 0;
  padding: 0;
}

#mymap {
  position: relative;
  width: 100%;
  height: 600px;
  left: 0%;
  top: 0%;
}
</style>

参考

javascript - Leaflet Marker not found production env - Stack Overflow
L.Icon.Default brings a wrong image url · Issue #4968 · Leaflet/Leaflet