关于 maplibre-v6-migration
面向回答升级与调试问题的 MapLibre GL JS v5 到 v6 迁移技能,涵盖七项变更,补充容易沿用旧版做法的指导。
主要功能
- 01涵盖七项 v5 到 v6 变更
- 02ESM 导入与 CDN 用法
- 03运行时图像解析器迁移
- 04公共相机 API 替代方式
- 05事件类型更新
- 06打包器 Worker URL 设置
适用场景
- 01升级 MapLibre GL JS v5 应用
- 02排查 v6 中导入失败
- 03修复运行时精灵图标缺失
- 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 GL JS v5→v6 迁移指南及其 CHANGELOG(v6.0.0 部分)
- CustomLayerInterface API 文档和安装指南(各打包器的
setWorkerUrl()代码片段)
本技能是一个快照。 如果主要来源与本文档相矛盾——包括上面的参考资料、MapLibre 当前文档,或运行 MapLibre 时观察到的行为——请以主要来源为准。遵循该来源,然后报告差异,并注明来源和你的 MapLibre 版本:修改已安装的副本对其他人毫无帮助,而且下次更新时会被覆盖。