mcpField
M
maplibre-v6-migration

maplibre-v6-migration

github.com/maplibre开发155198 次安装今天更新
代码仓库

关于 maplibre-v6-migration

面向回答升级与调试问题的 MapLibre GL JS v5 到 v6 迁移技能,涵盖七项变更,补充容易沿用旧版做法的指导。

主要功能

  1. 01涵盖七项 v5 到 v6 变更
  2. 02ESM 导入与 CDN 用法
  3. 03运行时图像解析器迁移
  4. 04公共相机 API 替代方式
  5. 05事件类型更新
  6. 06打包器 Worker URL 设置

适用场景

  1. 01升级 MapLibre GL JS v5 应用
  2. 02排查 v6 中导入失败
  3. 03修复运行时精灵图标缺失
  4. 04解决 Worker 加载故障

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/maplibre/maplibre-agent-skills --skill maplibre-v6-migration

安装后在 Claude Code 中输入/maplibre-v6-migration确认已加载。

详细介绍

MapLibre GL JS v5 → v6 迁移

仅当问题或其中的代码涉及以下七项变更之一时,才使用本文。 对于其他 MapLibre 问题,例如数据源、图层、样式或地形,请使用 v6 导入方式作答,不要添加任何关于 v6 变更或从 v5 迁移的章节、表格、列表或说明。

MapLibre GL JS v6(于 2026-07-22 发布)移除了 v5 代码所依赖的若干内容:UMD/CSP 浏览器包、默认导出、CommonJS 支持、内部的 map.transform,以及 MapDataEvent 类型。大多数模型的训练数据早于 v6。因此,对于涉及以下七项变更之一的代码,听起来最自然的答案通常是 v5 版本,但它在 v6 中会出错。

主要参考资料: MapLibre GL JS v5→v6 迁移指南。本技能补充了模型容易按 v5 时代默认行为推断的遗漏内容。如果指南与本技能有出入,请以指南为准并报告问题。

何时使用本技能

  • 将现有的 MapLibre GL JS v5 应用升级到 v6,或在依赖更新后调试一个“以前能正常工作”的地图
  • 编写以下七种模式之一:CDN <script> 标签、导入语句、require() 调用、styleimagemissing 处理程序、读取 map.transform 的代码、带类型的 data/dataloading/dataabort 处理程序,或打包工具设置(Vite、webpack、esbuild、Rspack、Rollup)
  • 调试如下错误:ERR_PACKAGE_PATH_NOT_EXPORTED、CDN 更新后地图空白、精灵图标始终不显示、TypeScript 错误中提到 MapDataEvent,或阻止渲染的 worker 加载错误

1. CDN script 标签:现在仅支持 ESM

v6 移除了 UMD 包和单独的 CSP 构建版本。现在已没有可供普通 <script src="..."> 标签使用的 dist/maplibre-gl.js。仅保留 ESM 构建版本 dist/maplibre-gl.mjs,且需要设置 type="module"。


<script src="https://unpkg.com/maplibre-gl@5/dist/maplibre-gl.js"></script>


<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: '...' });
</script>

始终指定明确的主版本号(@^6.0.0,或指定某个具体版本)。绝不要使用 @latest 或不带版本号的说明符——一旦发布下一个主版本,未锁定版本的 CDN URL 就会导致页面悄无声息地出错。v5→v6 交替时已经发生过这种情况。

2. 没有默认导出——只能使用命名导入或命名空间导入

v5 的 import maplibregl from 'maplibre-gl'(默认导入)在 v6 中不再有效。

// ❌ v5 — default export removed
import maplibregl from 'maplibre-gl';

// ✅ v6 — namespace import
import * as maplibregl from 'maplibre-gl';

// ✅ v6 — or import only what you use
import { Map, NavigationControl } from 'maplibre-gl';

无论代码是新写的,还是从 Mapbox GL JS 代码片段(import mapboxgl from 'mapbox-gl')转换而来,都适用此规则。无论哪种情况,都不要沿用默认导入的写法。

3. 不支持 CommonJS——require('maplibre-gl') 会抛出错误

v6 中,maplibre-gl 的 package.json exports 字段只有 "import" 条件,没有 "require" 条件。因此,在普通 Node 环境中调用 require('maplibre-gl') 会抛出 ERR_PACKAGE_PATH_NOT_EXPORTED。这是预期行为,并非调用方设置有问题。

// ❌ throws ERR_PACKAGE_PATH_NOT_EXPORTED in v6
const maplibregl = require('maplibre-gl');

// ✅ convert the file to ESM (named/namespace import — see item 2)
import { Map } from 'maplibre-gl';

// ✅ or, if the caller must stay CommonJS, load it dynamically
const { Map } = await import('maplibre-gl');

本节仅讨论直接在 Node 中调用 require() 的情况。如果涉及打包工具(webpack、Vite 等)且 require() 仍然失败,那是另一个 ESM 互操作配置问题。

4. styleimagemissing 不再处理请求——改用 setMissingStyleImageResolver

在 v5 中,监听 styleimagemissing 并在处理程序中同步调用 map.addImage(),即可提供缺失图标。在 v6 中,styleimagemissing 仅用于通知。在处理程序中调用 addImage 不再能处理待处理的请求。

// ❌ v5 pattern — no longer resolves the request in v6
map.on('styleimagemissing', (e) => {
  map.addImage(e.id, generateIcon(e.id));
});

// ✅ v6 — register a resolver that adds the image itself
map.setMissingStyleImageResolver(async (id) => {
  map.addImage(id, await generateIcon(id));
});

必须由解析器调用 map.addImage()。MapLibre 会忽略解析器的返回值,因此返回图像不会产生任何效果。

当样式引用的 icon-image 名称不在精灵图中,且需要在运行时生成或获取时,请使用此方法。

5. map.transform 已移除 — 请使用公开的 Camera API

v6 重构了 Map,使其组合使用 Camera,而不是继承它。现在,Map 直接继承 Evented,并转发 Camera API。作为这项更改的一部分,内部的 map.transform 属性已被移除。

// ❌ v5 — reaching into the internal transform
const { zoom, bearing, pitch } = map.transform;
const center = map.transform.center;

// ✅ v6 — public accessors
const zoom = map.getZoom();
const bearing = map.getBearing();
const pitch = map.getPitch();
const center = map.getCenter();

没有通用的公开接口可以替代原始投影/视图矩阵。 无论在 v5 还是 v6 中,它都从未通过 Map 本身公开过,只存在于 map.transform 上。现在仍可获取矩阵的唯一位置,是自定义图层的 render() 回调中,可通过回调参数获取(CustomRenderMethodInput.getProjectionData() / defaultProjectionData;参见自定义图层 API)。在自定义图层之外,请使用上面的公开 getter。对于公开 API 未提供的其他功能,请提交 issue 或 PR,而不要重新引入私有访问器。

6. MapDataEvent 已移除 — 请使用 MapSourceDataEvent / MapStyleDataEvent

v6 将所有触发的事件都改为真正的类,每个事件都会单独实例化。旧的通用类型 MapDataEvent 已移除。现在,data、dataloading 和 dataabort 的类型为 MapSourceDataEvent | MapStyleDataEvent。源数据事件会直接在自身类型中携带完整的源信息(sourceId、tile、sourceDataType 等),而不是使用通用的共享结构。

// ❌ v5 — MapDataEvent no longer exists in v6
import type { MapDataEvent } from 'maplibre-gl';
map.on('data', (e: MapDataEvent) => {
  /* ... */
});

// ✅ v6 — narrow on the union MapLibre now exports
import type { MapSourceDataEvent, MapStyleDataEvent } from 'maplibre-gl';
map.on('data', (e: MapSourceDataEvent | MapStyleDataEvent) => {
  if ('sourceId' in e) {
    // MapSourceDataEvent — e.sourceId, e.sourceDataType, e.tile
  } else {
    // MapStyleDataEvent
  }
});

凡是在类型导入或注解中使用 MapDataEvent 的地方,都需要进行相同的修复,包括 dataloading 和 dataabort 处理程序。

7. 打包构建仍需 setWorkerUrl() — CDN ESM 无需调用

v6 更改了源处理 worker 的定位方式,但仅适用于打包应用。普通的 CDN <script type="module">(条目 1)会根据 import.meta.url 自动检测 worker URL,无需额外设置。在打包器(Vite、webpack、esbuild、Rspack、Rsbuild、Rollup)中,import.meta.url 无法可靠地解析到打包器自身模块图中的 worker 文件。每种配置都需要显式调用一次 setWorkerUrl(),并且必须在创建 Map 之前调用。

// ❌ v6 with a bundler, no setWorkerUrl() call — worker fails to load, map never renders
import { Map } from 'maplibre-gl';
const map = new Map({
  /* ... */
});

// ✅ Vite — the `?worker&url` query
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({
  /* ... */
});

// ✅ webpack 5+, Rspack, Rsbuild, and Next.js 15+ (Turbopack or webpack) — call setWorkerUrl() the same way, then create the Map
import { Map, setWorkerUrl } from 'maplibre-gl';

setWorkerUrl(new URL('maplibre-gl/dist/maplibre-gl-worker.mjs', import.meta.url).toString());

在 Vite 中,请使用 ?worker&url,与安装指南中的做法一致。从 6.0.0 到 6.12.x,使用普通的 ?url 会留下 worker 所导入的 maplibre-gl-shared.mjs,导致生产环境无法加载矢量瓦片;6.13.0 则让 worker 实现了自包含。esbuild 和 Rollup 会复制 worker 文件,并将其 URL 传递给同一个一次性调用。当前各打包器的代码片段请参阅安装指南;它们随工具版本变化的速度快于本技能的其余内容。

不要将此要求套用到条目 1 的 CDN 情况。 从 CDN URL 导入的普通 <script type="module"> 始终无需调用 setWorkerUrl()。

参考资料


本技能是一个快照。 如果主要来源与本文档相矛盾——包括上面的参考资料、MapLibre 当前文档,或运行 MapLibre 时观察到的行为——请以主要来源为准。遵循该来源,然后报告差异,并注明来源和你的 MapLibre 版本:修改已安装的副本对其他人毫无帮助,而且下次更新时会被覆盖。

评论

支持 Markdown