MapLibre GL JS v5 から v6 へ¶
このワークショップでは、MapLibre GL JS v6 を Terra Draw v1.32.2 および terra-draw-maplibre-gl-adapter v1.4.1 と組み合わせて使います。アダプター自体は v6 対応のための変更を必要とせず、v4・v5・v6 のすべてに対応しています (terra-draw#912 参照)。ただし MapLibre v6 ではライブラリの配布形式が変わったため、コードを書き始める前に知っておく価値があります。
Note
このページは背景知識です。各演習ページのライブエディタではすべて対応済みなので、トラック A で進めている方は Terra Draw の基本 に飛んで、後から戻ってきてもかまいません。トラック B (ローカルの SvelteKit テンプレート) で進めている方は、テンプレートにここで説明する設定がそのまま入っているので、読み進めてください。
ESM のみ: UMD バンドルは廃止¶
v6 での最大の変更は配布形式です。MapLibre GL JS v6 は ES モジュールのみで配布されます。UMD バンドル (maplibre-gl.js) と個別の CSP バンドル (maplibre-gl-csp.js) は公開されなくなりました。
| v5 | v6 | |
|---|---|---|
| メインバンドル | dist/maplibre-gl.js (UMD) |
dist/maplibre-gl.mjs (ESM) |
| CSP 向けビルド | dist/maplibre-gl-csp.js |
廃止 (不要になりました) |
| ワーカー | インライン / blob | dist/maplibre-gl-worker.mjs |
package.json |
main + module |
"type": "module"、import のみ |
そのため、従来の script タグは動作しません。
<!-- v5: UMD、グローバル変数 `maplibregl` を公開する -->
<script src="https://unpkg.com/maplibre-gl@^5/dist/maplibre-gl.js"></script>
代わりに module スクリプトを使います。
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@^6.0.0/dist/maplibre-gl.css" />
<div id="map" style="height: 400px"></div>
<script type="module">
import * as maplibregl from 'https://unpkg.com/maplibre-gl@^6.0.0/dist/maplibre-gl.mjs';
const map = new maplibregl.Map({
container: 'map',
style: 'https://tiles.openfreemap.org/styles/bright',
center: [132.4553, 34.3966],
zoom: 12
});
</script>
グローバル変数 maplibregl はもう存在しません。必ず import して使います。
import の書き方¶
すでに名前付き import を使っている場合、変更は不要です。
更新が必要なのはデフォルト import だけです。ESM ビルドにはデフォルトエクスポートがありません。
// 変更前 (v5)
import maplibregl from 'maplibre-gl';
// 変更後 (v6) — 名前空間 import
import * as maplibregl from 'maplibre-gl';
// または必要なものだけを取り込む
import { Map, setWorkerUrl } from 'maplibre-gl';
ワークショップのテンプレート (template/src/routes/+page.svelte) もライブエディタも名前付き import を使っており、演習全体でこのスタイルに統一しています。
Web Worker について¶
MapLibre はタイルのパースを Web Worker で行います。v6 ではこのワーカーが実際のモジュールファイル dist/maplibre-gl-worker.mjs になり、隣接するファイル dist/maplibre-gl-shared.mjs を相対パスで import します。
CDN から読み込む場合。 ワーカーの URL は import.meta.url から自動的に導出されるため、設定は不要です。ただしワーカーが隣接ファイルを相対パスで解決するため、dist/ ディレクトリ全体が到達可能である必要があります。フルパスを指定してください。
// 良い例: 隣接ファイル (ワーカーと共有チャンク) に到達できる
import * as maplibregl from 'https://unpkg.com/[email protected]/dist/maplibre-gl.mjs';
モジュールパスを書き換えて再バンドルする CDN ではこれが壊れます。メインモジュールは読み込めるものの、ワーカーのリクエストが 404 になり、エラーも出ないまま地図が固まります。このワークショップのライブエディタが unpkg の dist/maplibre-gl.mjs の URL をそのまま固定しているのは、このためです。
Content Security Policy。 MapLibre を CDN からクロスオリジンで読み込むと、ワーカーは同一オリジンの blob URL から生成されるため、CSP に次の設定が必要です。
ワーカーを自分でホストする場合 (このテンプレートを含め、バンドラーを使う構成すべて) はワーカーの URL が同一オリジンになるため、blob: は不要です。
Vite で MapLibre v6 を使う¶
バンドラーの中では import.meta.url がワーカーファイルを確実に解決できないため、プロジェクトごとに一度だけ setWorkerUrl() を呼ぶ必要があります。Vite では ?worker&url クエリを使って、バンドル済みで自己完結したワーカーの URL を取得します。
import { Map, setWorkerUrl } from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
setWorkerUrl(workerUrl);
const map = new Map({
/* … */
});
単なる ?url ではなく ?worker&url を使ってください。dist のワーカーは隣接する maplibre-gl-shared.mjs を import しますが、?url は本番ビルドでワーカーファイルをそのまま出力し、隣接ファイルを含めません。その結果、ワーカーは最初の import で失敗し、ベクタータイルが一切読み込まれなくなります。?worker&url は Vite のワーカーパイプラインを通し、自己完結したチャンクを出力します。
さらにワークショップのテンプレートでは、Vite の依存関係の事前バンドルから MapLibre を除外しています。この処理の途中でワーカーのバンドルが失敗することがあるためです。
// template/vite.config.ts
export default defineConfig({
plugins: [sveltekit()],
optimizeDeps: {
// MapLibre v6 worker bundling can fail during dependency pre-bundling.
exclude: ['maplibre-gl']
}
});
これは上流の要求ではなく、このテンプレート独自の回避策です。設定なしで動くプロジェクトであれば不要です。
他のバンドラー
webpack 5 以降、rspack、rsbuild でも同じ setWorkerUrl() を、通常の URL を渡して呼びます: setWorkerUrl(new URL('maplibre-gl/dist/maplibre-gl-worker.mjs', import.meta.url).toString()); 変更点の全体は v5 から v6 への移行ガイド を参照してください。
次のステップ¶
MapLibre v6 での違いが分かったところで、Terra Draw の基本を学んでいきましょう。