React SDK 0.2.1 – der MapLibre-Worker liegt bei, und die stumm leere Karte ist weg

Der Worker von MapLibre GL JS v6 liegt jetzt bei und registriert sich selbst, onMapLoaded löst endlich aus, und TomTom liegt mit den übrigen auf MapLibre 6 — womit es sich auch unter dem ESM-Resolver von Node laden lässt. 19 von 21 Paketen haben sich bewegt.

Die Module des MapConductor React SDK wurden aktualisiert: 19 der 21 Pakete auf npm haben sich bewegt. Das meiste davon ist Abhängigkeitspflege, aber zwei Korrekturen rund um MapLibre betreffen Fehler, deren Ursache man im Ernstfall nur schwer findet.

Die Versionen sind bewusst nicht angeglichen. react-for-maplibre und react-for-openlayers stehen bei 0.2.2; react-icons und react-kml bleiben, wo sie waren; der Rest steht bei 0.2.1. Anders als bei 0.2.0 bekommen nicht mehr alle Pakete dieselbe Zahl: Ein Paket hochzuzählen, dessen Inhalt sich nicht geändert hat, sagt beim Aktualisieren nur „irgendetwas ist anders".

Die Karte zeigt nur die Hintergrundfarbe – und nichts wirft einen Fehler

Darum geht es bei react-for-maplibre 0.2.2.

MapLibre GL JS v6 liefert seinen Web Worker als eigene Datei aus und baut die URL dafür aus dem eigenen import.meta.url. Läuft das durch einen Bundler, wird dieser Wert zur Buildzeit eingefroren – unter Rspack ein file://-Pfad, unter Vite das Prebundle-Ziel – während die echte Worker-Datei nirgends ausgegeben wird. Die Auflösung schlägt fehl.

Unangenehm daran: der Fehlschlag wirft nichts. Es entsteht stillschweigend so etwas wie new Worker(""), und die Karte bleibt stehen, ohne eine einzige Kachel anzufordern. Zu sehen ist eine Karte aus reiner Hintergrundfarbe. Zeigt das Netzwerkpanel null .pbf-Anfragen, ist genau das der Fall.

0.2.2 legt einen in sich geschlossenen Worker bei und registriert ihn automatisch, sobald die erste Karte entsteht. Es gibt nichts zu konfigurieren. Unter Vite verhält es sich genauso wie unter webpack / Rspack, im Dev- wie im Produktionsbuild.

Eine Ausnahme gibt es: Wenn Sie den Worker von einer eigenen URL ausliefern (ein gemeinsam genutztes CDN oder ein Build, der ihn bereits erzeugt). Rufen Sie setMapLibreWorkerUrl(url) vor der ersten Karte auf, dann wird der beigelegte Worker übersprungen – und gar nicht erst heruntergeladen.

ts
import { setMapLibreWorkerUrl } from '@mapconductor/react-for-maplibre';

setMapLibreWorkerUrl('https://cdn.example.com/maplibre-worker.mjs');

Eines ist zu erwarten: Der Dev-Server von Vite schickt den beigelegten Worker durch seine Transform-Pipeline, wodurch ein Import von /@vite/client hineingerät und die Datei anschwillt (etwa 478 KB → 2,8 MB). Das sieht beunruhigend aus, ändert am Verhalten aber nichts; im Produktionsbuild wird er als gewöhnliches Asset ausgegeben.

Den Worker als Blob-URL zu übergeben funktioniert unter v6 nicht. Er startet fehlerfrei und fordert trotzdem keine einzige Kachel an. Er muss als echte Datei ausgeliefert werden.

onMapLoaded hat nie ausgelöst

Ebenfalls react-for-maplibre 0.2.2.

MapLibreProvider.initialize() wartet auf map.once('load'), bevor der Controller entsteht. Wenn es den Controller gibt, ist das Laden also längst vorbei, und das on('load'), das setupEventListeners anhängt, kann nie wieder auslösen.

Die Prüfung „bereits initialisiert?" im Konstruktor sollte diesen Fall abfangen und tat es nicht: Sowohl loaded() als auch isStyleLoaded() liefern unmittelbar nach dem Laden false. Das isStyleLoaded() von MapLibre v6 ruft Style.loaded() auf und wartet damit auf jeden tileManager.

In 0.2.2 behoben. Wer onMapLoaded verwendet hat, wurde bis dahin nie aufgerufen.

js-sdk-core 0.2.1 – der Service Worker starb bei zu vielen verschiedenen Symbolen

Die Marker-Symbole erreichen den Kachel-Service-Worker als Bitmaps. Sie wurden einzeln gesammelt und erst am Ende gemeinsam verschickt – bei mehr verschiedenen Symbolen, als der Cache fasst, waren die zuerst gesammelten zum Zeitpunkt des Versands also längst freigegeben. Ein freigegebenes ImageBitmap durch das strukturierte Klonen zu schicken wirft DataCloneError, und das reißt die gesamte Registrierung des Service Workers mit.

Ohne Registrierung kommt keine einzige Kachel an; zu sehen ist also eine Karte, die nicht erscheint. Und es tritt erst auf, wenn die Zahl der verschiedenen Symbole die Cache-Größe überschreitet – jene Sorte Fehler, die lokal läuft und in der Produktion stehen bleibt.

Die Korrektur ist kein größerer Cache. Es ist die Eigentümerschaft: Die Nutzlast trägt jetzt eigene Kopien und gibt sie frei, sobald das Verschicken zurückgekehrt ist. Was dem Cache gehört, bleibt unangetastet.

TomTom schleppt kein zweites MapLibre mehr mit

In 0.2.0 war react-for-tomtom das einzige Modul, das auf maplibre-gl 5.x zurückgehalten wurde, weil @tomtom-org/maps-sdk von maplibre-gl@^5.24.0 abhing. Der Schritt auf 6.x hätte zwei MapLibre-Kopien installiert und dem TomTom-SDK ein Kartenobjekt übergeben, mit dem es nicht rechnet.

Mit 0.51.5 ist TomTom selbst auf maplibre-gl@^6.4.0 gewechselt. react-for-tomtom 0.2.1 zieht mit ^6.6.0 nach. Es teilt sich nun ein MapLibre mit react-for-maplibre und react-for-maptiler, und die Anmerkung aus 0.2.0 entfällt.

Ein Nebeneffekt: react-for-tomtom lädt jetzt unter dem ESM-Resolver von Node. In 0.2.0 tat es das nicht; der Grund lautete damals, es „liest maplibre-gl/package.json, was Node nur mit einem Import-Attribut lädt". Gemessen, indem die veröffentlichten Pakete in einem leeren Projekt importiert wurden.

importrequire()
react-for-tomtom 0.2.0nono
react-for-tomtom 0.2.1yesno

require() scheitert weiterhin, weil maplibre-gl v6 reines ESM ist und keinen CommonJS-Einstieg deklariert – derselbe Grund wie bei react-for-maplibre und react-for-maptiler. Nutzen Sie diese drei über ESM.

Vier 0.2.1-Versionen ohne Codeänderung

Die 0.2.1-Versionen von js-sdk-react, react-geojson, react-heatmap und react-marker-clustering liefern dasselbe JavaScript wie 0.2.0. Bewegt haben sich nur Build-Angaben, die im Paket mitliegen und die ein Web-Build nie liest. Es eilt nicht, sie nachzuziehen, schaden tut es aber auch nicht.

Aktualisierte Karten-SDKs

Auf den neuesten Stand innerhalb des deklarierten Bereichs gebracht. Bewegt haben sich diese:

Abhängigkeit0.2.0Jetzt
mapbox-gl^3.15.0^3.29.0
maplibre-gl^6.0.0^6.6.0
cesium^1.131.0^1.144.0
ol^10.2.1^10.10.0
@arcgis/core^5.1.16^5.1.20
@tomtom-org/maps-sdk^0.51.0^0.51.5
azure-maps-control^3.7.0^3.7.4
@turf/turf^7.3.5^7.4.0

Drei blieben stehen – leaflet ^1.9.4, @googlemaps/js-api-loader ^2.1.1 und mappls-web-maps ^3.8.1 –, weil sich stromaufwärts nichts getan hat. Die peerDependencies von React bleiben ^18.0.0 || ^19.0.0; geändert hat sich nur die Entwicklungsversion (19.2.7 → 19.2.8).

Die Pakete und ihre Karten-SDKs

PaketVersionKarten-SDKRepository
@mapconductor/js-sdk-core0.2.1js-sdk-core
@mapconductor/js-sdk-react0.2.1js-sdk-react
@mapconductor/react-for-arcgis0.2.1@arcgis/core ^5.1.20react-for-arcgis
@mapconductor/react-for-azuremaps0.2.1azure-maps-control ^3.7.4react-for-azuremaps
@mapconductor/react-for-cesium0.2.1cesium ^1.144.0react-for-cesium
@mapconductor/react-for-googlemaps0.2.1@googlemaps/js-api-loader ^2.1.1react-for-googlemaps
@mapconductor/react-for-here0.2.1CDN (global H)react-for-here
@mapconductor/react-for-leaflet0.2.1leaflet ^1.9.4react-for-leaflet
@mapconductor/react-for-longdo0.2.1CDN (api.longdo.com/map3)react-for-longdo
@mapconductor/react-for-mapbox0.2.1mapbox-gl ^3.29.0react-for-mapbox
@mapconductor/react-for-mapkit0.2.1CDN (cdn.apple-mapkit.com)react-for-mapkit
@mapconductor/react-for-maplibre0.2.2maplibre-gl ^6.6.0react-for-maplibre
@mapconductor/react-for-mappls0.2.1mappls-web-maps ^3.8.1react-for-mappls
@mapconductor/react-for-maptiler0.2.1maplibre-gl ^6.6.0react-for-maptiler
@mapconductor/react-for-openlayers0.2.2ol ^10.10.0react-for-openlayers
@mapconductor/react-for-tomtom0.2.1@tomtom-org/maps-sdk ^0.51.5, maplibre-gl ^6.6.0react-for-tomtom
@mapconductor/react-geojson0.2.1react-geojson
@mapconductor/react-heatmap0.2.1react-heatmap
@mapconductor/react-icons0.2.0react-icons
@mapconductor/react-kml0.2.0react-kml
@mapconductor/react-marker-clustering0.2.1react-marker-clustering

HERE, Apple MapKit JS und Longdo führen kein Karten-SDK als Abhängigkeit, weil diese SDKs nicht über npm verteilt werden. Sie werden zur Laufzeit vom CDN des Anbieters geladen; die tatsächlich laufende Version ist also die, die der Anbieter ausliefert.

Aktualisieren

bash
npm install @mapconductor/js-sdk-core@latest @mapconductor/js-sdk-react@latest \
  @mapconductor/react-for-maplibre@latest

js-sdk-core steht ebenfalls bei 0.2.1. Es enthält die oben beschriebene Service-Worker-Korrektur — wer viele verschiedene Marker-Symbole verwendet, sollte es mitnehmen.

ESM, CommonJS und SSR verhalten sich wie in 0.2.0, abgesehen von react-for-tomtom oben. Die vollständige Tabelle dazu, was sich außerhalb eines Bundlers laden lässt und was nicht, steht im Beitrag zu React SDK 0.2.0. Jedes Paket liegt in einem eigenen Repository – siehe github.com/MapConductor.