Appearance
cesium-example 单案例迁移规范
将旧
cesium-example中一个可识别案例重构为@nexa/gis-cesium的公共 API、自动发现案例、测试和文档。一次只处理一个案例,方案审批和人工验收是强制闸门。
适用范围
默认源仓库:
text
/Users/ysuhan/Elon/Project/opensource/Cesium 资源/cesium-example目标范围:
text
packages/gis-cesium/src/lib/ # 公共 API 与实现
packages/gis-cesium/src/examples/templates/ # 可运行案例
docs/api/gis-cesium/guide/ # 使用指南
docs/config/sidebar.ts # 文档导航本规范不授权一次迁移多个案例,不授权新增依赖、修改构建配置、破坏公共 API,也不授权把旧 React 页面整体移入 SDK。
源库基线与迁移难点
源库使用 React 17 和 Cesium 1.72,主要代码分散在:
text
src/router/category.js # 案例目录入口
src/views/<Category>/<Case>/ # React/Vue 页面和交互
src/js/SampleItems/<Category>/<Case>/ # Viewer 初始化和旧版编排
src/components/** # 实际能力实现
src/utils/** # 算法与工具
src/static/** # 纹理、模型、数据和截图2026-08-07 盘点得到 159 个 view 入口、113 个 SampleItems 入口、217 个 component JavaScript 文件和 634 个静态资产。文件数量不等于可迁移能力数量:其中包含重复实现、多版本实现、纯 UI 页面、未完成案例以及已经迁移到 gis-cesium 的能力。
因此,禁止只读取 views/<Case>/index.jsx 就开始实现。每次必须先追踪完整源码闭包。
核心原则
一次一个案例
每个案例独立经历:
text
选择案例
→ 源码闭包分析
→ 重叠检查与处置判定
→ API/测试/案例/文档方案
→ 人工批准
→ 单案例实现
→ 本地完整验收
→ 人工体验验收
→ 明确指令后进入下一个任何 AI 完成一个案例后必须停止。不得自动选择、规划或迁移下一个案例。
迁移的是能力,不是旧代码形状
- 保留可验证的用户行为和核心算法。
- 删除 React 生命周期、旧 Viewer 初始化、全局变量和页面壳。
- 剥离业务数据、固定服务地址、Token 和场景专用规则。
- 修复源实现中的泄漏、重复注册、帧率相关动画和无效清理。
- 不保留 Cesium 1.72 私有 API 用法。
- 不因为旧代码“能跑”而复制无类型 JavaScript。
保持 Cesium 可组合性
gis-cesium 是扩展 SDK,不是 Cesium 全量防腐层。
- 允许公共 API 使用
Viewer、Entity、Cartesian3、Color、JulianDate等稳定 Cesium 公共类型。 - 只有在跨产品复用、组合多个 Cesium 对象、管理生命周期、隔离版本风险或提供统一性能策略时才新增 SDK API。
- 简单的一次
viewer.entities.add()不应为了“封装”而新增薄包装。 - 禁止普通模块新增 Cesium
_前缀字段或未公开模块访问。
单案例迁移流程
Phase 0:确定案例
用户可以指定一个案例名称或精确源入口,例如:
text
SpecialEffects/CircleSpreadScan
src/views/Analysis/SightLine/index.jsx如果用户没有指定案例,AI 必须自行对比旧仓库与当前 gis-cesium,选择下一个最值得补齐的安全缺口,但仍不能直接实现:
- 从
src/router/category.js、src/views/**和src/js/SampleItems/**建立源案例浅层索引,合并重复 React/Vue 和 SampleItems 变体; - 从公共导出、
core/**/index.ts、测试、src/examples/templates/和docs/api/gis-cesium/guide/建立目标能力索引; - 按行为、Cesium 对象、输入、生命周期、视觉结果、测试和文档判断
new/enhance/example-only/duplicate/defer,禁止只按名称匹配; - 对领先的至少三个候选追踪完整源码闭包,识别隐藏依赖、私有 API、资产、网络服务和真实重叠;
- 按复用价值、基础价值、缺口确定性、可验证性、独立交付性、测试性和变更规模评分,并对新增依赖、私有 API、资产授权、外部服务和跨模块复杂度扣分;
- 展示 Top 5 差距表,只选择一个最高价值且没有架构硬阻塞的案例进入 Gate 1 提案。
如果没有安全候选,AI 必须报告差距清单并停止,不能为了推进而强行迁移。
为案例确定稳定的 caseId,后续分析、提案、验收都使用同一标识。
一个案例验收完成后,再次自动选择时必须基于更新后的目标仓库重跑对比;新 API 可能使后续候选变成 example-only 或 duplicate,不得沿用旧排名。
Phase 1:分析源码闭包
必须检查:
text
[ ] 路由或 category 中的案例入口
[ ] view 页面及其交互、初始化和卸载逻辑
[ ] 对应 js/SampleItems 实现
[ ] 所有 components、materials、shader、utils 依赖
[ ] 图片、纹理、模型、视频、GeoJSON、3D Tiles 等资产
[ ] window.Cesium 和其他运行时全局对象
[ ] React/jQuery/Turf/OpenLayers/mapv/heatmap.js 等第三方依赖
[ ] 网络 URL、Token、跨域要求和外部服务稳定性分析时把代码分成六类:
| 分类 | 处理方式 |
|---|---|
| 可复用 GIS 能力 | 进入 API 设计候选 |
| Demo 编排 | 进入新案例,不进入 SDK 核心 |
| React/旧 Viewer 启动 | 删除,使用现有案例框架 |
| 业务耦合 | 删除或抽象为通用输入 |
| 静态资产 | 核实必要性、体积和来源后处理 |
| 源实现缺陷 | 修复,不保持错误兼容 |
输出必须包括可观察行为、核心 Cesium 对象、资源所有权、清理现状、性能特征和无法确认的行为。
如果源案例可运行,应记录浏览器控制台和视觉基线;无法运行时必须说明仅依据源码或历史截图,降低结论置信度。
Phase 2:检查目标仓库重叠
至少搜索:
text
packages/gis-cesium/src/lib/core/
packages/gis-cesium/src/lib/NexaCesium.ts
packages/gis-cesium/src/examples/templates/
packages/gis-cesium/src/lib/core/**/__tests__/
docs/api/gis-cesium/guide/按行为而不是文件名分类:
| 处置 | 条件 | 动作 |
|---|---|---|
new | 没有等价能力 | 提议新增最小 API |
enhance | 已有能力缺少明确行为 | 提议向后兼容增强 |
example-only | API 已有,仅案例或文档缺失 | 禁止改核心实现 |
duplicate | API、测试、案例和文档均已满足 | 报告证据并停止 |
defer | 架构、依赖、授权或私有 API 风险未解决 | 报告阻塞并停止 |
名称相同不等于行为相同,名称不同也不代表新能力。必须比较输入、输出、视觉效果、生命周期、清理行为和限制。
Phase 3:选择模块与设计 API
优先扩展已有子系统:
| 责任 | 目标目录/模式 |
|---|---|
| 有运行期资源的动态效果 | effects/,实现 on/off/destroy(viewer) |
| Viewer 能力注入 | plugins/,通过 CesiumViewer.extend/extendViewer,必要时返回 uninstall hook |
| GLSL/Fabric/MaterialProperty | materials/,注册必须幂等 |
| Entity 工厂或渲染能力 | entities/ |
| 持久图层 CRUD | layers/ |
| 已有绘制、弹窗、Provider、热力等领域 | 扩展对应现有子系统 |
| 不拥有 Viewer 的公共纯函数 | tools/ |
| 内部渲染辅助 | utils/,默认不导出为公共 API |
API 设计必须先给出完整用户调用示例,包括清理:
typescript
import { XxxEffect } from '@nexa/gis-cesium'
import { Cartesian3 } from 'cesium'
const effect = new XxxEffect({
position: Cartesian3.fromDegrees(116.3, 39.9),
})
effect.on(viewer)
// 页面或场景退出时由创建方负责清理
effect.destroy(viewer)设计检查:
text
[ ] 为什么值得进入 SDK,而不是直接使用 Cesium 公共 API?
[ ] 输入是否使用正确的稳定公共类型?
[ ] 三个以上配置是否使用 Options?
[ ] 默认值是否通用、可预测且有文档?
[ ] 必填值、范围、NaN/Infinity、空集合是否校验?
[ ] 谁创建和销毁 Entity/Primitive/Event/DOM/GPU/Timer?
[ ] on/off/destroy 或 install/uninstall 是否幂等?
[ ] 是否保持现有公共 API 向后兼容?Gate 1:方案审批
编码前必须向人工提交单案例提案,至少包含:
- 源码闭包及行为分析;
- 重叠检查和
new/enhance/example-only/duplicate/defer结论; - API 调用示例和模块归属;
- 生命周期、资产、依赖和版本风险;
- API、测试、案例、文档交付文件;
allowedFiles、forbiddenFiles、contextFiles和maxChangedFiles;- 验证命令和非目标。
人工未明确批准前,禁止修改实现代码。
以下事项不能作为普通迁移直接委派:
- 新增依赖或修改
package.json、pnpm-lock.yaml; - Breaking Change;
- 新增 Cesium 私有 API;
- 修改构建、ESLint、TypeScript、Vite 或 CI;
- 未定位的 WebGL、Shader、Framebuffer 或资源泄漏问题;
- 来源或使用权不明确的资产。
Phase 4:实现公共 API
实现必须遵守当前 packages/gis-cesium/AGENTS.md:
- TypeScript strict,不使用
any、@ts-ignore或@ts-nocheck; - 公共类型进入对应模块
types.ts; - 公共 class/function/interface 有中文 JSDoc 和
@example; - 所有公共函数有显式返回类型;
- 类型导入使用
import type; - 资源只删除自己创建的对象;
destroy()可重复调用;- 模块
index.ts和NexaCesium.ts同时命名导出。
如果 Cesium 类型确有缺失,不得在普通实现中临时增加 any 或私有访问。先检查现有 core/cesium-compat/ 和类型 shim;仍无法解决时停止,转为架构审查。
Phase 5:编写测试
测试必须表达业务和生命周期语义,而不是只验证字段值。
最低覆盖:
text
[ ] Options 必填值与非法范围
[ ] 默认值和自定义值
[ ] 核心正常行为
[ ] 重复 on/off/install/uninstall 不创建重复资源
[ ] destroy 后只释放自己拥有的资源
[ ] destroy 重复调用安全
[ ] 源案例的重要边界行为
[ ] 修复过的源实现缺陷有回归测试测试优先使用现有共享 mock 和契约模式,不得复制旧的 mockViewer: any 或假设原生 Viewer 存在 viewer.extend()。
以下能力应增加浏览器/WebGL 验证:
- GLSL、材质注册、后处理和离屏渲染;
- 3D Tiles、Primitive 或 GPU 资源释放;
- DOM overlay、事件输入和跨 Viewer 生命周期;
- Cesium 版本敏感或仅真实 Scene 才能验证的路径。
Phase 6:创建可运行案例
目录必须符合自动发现格式:
text
packages/gis-cesium/src/examples/templates/<Name>/
├── index.ts
├── index.vue
├── index.code.ts
└── cover.png案例要求:
- 只使用
@nexa/gis-cesium公共 API 和 Cesium 公共 API; - 不 import
src/lib/core/**内部文件; - 不复制 API 内部实现;
- 包含一个基础用法和一个进阶用法或可配置变体;
- 关键步骤使用中文注释;
- 明确清理 effect、plugin、event、timer 和临时场景对象;
- 不包含 Token、不可控外部服务或开发机绝对路径;
- 资产放在目标包允许的位置,记录来源并控制体积;
import.meta.glob自动发现,不手工注册案例。
视觉验收至少检查:案例可打开、核心效果可识别、交互可执行、控制台无新增错误、离开后重新进入不产生重复资源。
Phase 7:编写 API 文档
每个新增或增强的公共能力必须同时提供:
- 源码 JSDoc:职责、所有权、参数、返回值、限制和
@example; - VitePress 指南:
docs/api/gis-cesium/guide/<slug>.md; - 导航:必要时更新
docs/config/sidebar.ts。
指南至少包含:
text
[ ] 能力定位与适用场景
[ ] 安装/import 和完整基础示例
[ ] Options/API 表格
[ ] 进阶示例
[ ] 生命周期与清理责任
[ ] 性能和 Cesium 版本限制
[ ] 与原生 Cesium API 的组合方式当前仓库没有可执行的 api:build-docs package script。不得虚报该命令通过,也不得为了单案例迁移擅自修改构建配置。现阶段使用 build:lib、check:governance 和 docs:build 验证类型声明、公共导出和指南构建。
Phase 8:本地验收
先运行聚焦命令,再运行根 AGENTS.md 要求的全仓门禁:
bash
pnpm --filter @nexa/gis-cesium run typecheck
pnpm --filter @nexa/gis-cesium run test
pnpm --filter @nexa/gis-cesium run build:lib
pnpm --filter @nexa/gis-cesium run check:governance
pnpm lint
pnpm typecheck
pnpm build
pnpm test:all
pnpm docs:build按变更类型追加:
bash
pnpm --filter @nexa/gis-cesium run test:e2e # 浏览器/WebGL/DOM/版本敏感
pnpm --filter @nexa/gis-cesium run test:bench # 数量级或性能策略
pnpm --filter @nexa/gis-cesium run check:bundle # 新公共实现或资产影响包体所有结果必须来自本地实际输出。AI 声称的“应该通过”不算证据。
Gate 2:人工体验验收
完成报告必须列出:
- API、测试、案例、文档的实际文件;
- 源行为到目标实现的映射和差异;
- 所有命令的实际结果;
- 浏览器控制台和视觉验证;
- 剩余限制与人工操作步骤。
报告结尾必须明确:
text
本案例到此停止。请人工验收;未收到“验收通过,继续下一个”前不迁移下一案例。单案例 Definition of Done
text
## 范围
- [ ] 只处理一个已批准案例
- [ ] 源码闭包和目标重叠检查完整
- [ ] 无未批准依赖、构建或 Breaking Change
## API
- [ ] 模块归属正确且有进入 SDK 的充分理由
- [ ] 类型、实现、index.ts、NexaCesium.ts 完整
- [ ] 公共 JSDoc 含 @example
- [ ] 生命周期和资源所有权明确、幂等
- [ ] 未新增 Cesium 私有 API 或类型逃逸
## 测试
- [ ] 正常、默认、非法输入和边界行为已覆盖
- [ ] 重复启停和销毁清理已覆盖
- [ ] 需要时有真实浏览器/WebGL 测试
## 案例
- [ ] 自动发现目录完整
- [ ] 只调用公共 API
- [ ] 基础 + 进阶行为可识别
- [ ] 控制台无新增错误,重复进入无泄漏
## 文档
- [ ] JSDoc、指南和 sidebar 同步
- [ ] 文档包含清理、限制和组合方式
## 验收
- [ ] 聚焦命令通过
- [ ] lint/typecheck/build/test:all/docs:build 全部通过
- [ ] 完成报告包含真实证据
- [ ] 已停止并等待人工验收相关执行材料
- Codex Skill:
.codex/skills/cesium-example-migration/SKILL.md - Claude Skill:
.claude/skills/cesium-example-migration.md - CodeBuddy Skill:
.codebuddy/skills/cesium-example-migration.md - Claude/CodeBuddy 快捷命令:
/migrate-cesium-example <案例名称或精确源入口> - 自动选型评分:
.codex/skills/cesium-example-migration/references/selection-policy.md - AI 启动模板:迁移 AI Prompt
- Cesium 升级风险:Cesium 升级清单
- SDK 架构基线:gis-cesium 扩展 SDK 演进基线