主题
目录结构与职责
这页是一张可检索的地图:仓库根、editor/、editor/src/app/ 三级展开,每个目录给职责说明与关键文件,最后给一张「什么改动落在哪」的导引图。数字为 2026-10 实测(grep 与 find 口径),代码会漂移,以实际为准。分层职责的完整契约(含扩展接入点)在架构规则 §1.1(editor/docs/refactor/ARCHITECTURE-RULES.md),本页是其导航版。
仓库根
| 目录 | 职责 |
|---|---|
editor/ | Angular 应用本体,见下文 |
server/ | Rust 生产后端:静态托管、/mock/* 兼容端点、/tiles/terrain、上传与档案 API(server/README.md 为权威) |
tools/ | e2e 聚合与视觉基线工具链:Playwright 回归十七套(e2e.mjs 聚合)、pixelmatch 基线(visual-baseline.mjs)、fixtures 与基线 PNG |
docs/ | 仓内领域文档:roadmap、spec、analysis、testing(逐项见文档地图) |
docs-site/ | 本站(VitePress,入门与导航层) |
design/ | Expression Engine 落地设计两份 |
.github/workflows/ | ci.yml(PR 门禁,含本站死链检查)、nightly.yml(全量 e2e 加视觉基线) |
editor/
| 路径 | 职责 |
|---|---|
src/ | 生产代码(测试不入 src) |
tests/ | vitest 单测树(219 个测试文件),目录层级镜像 src/app;根级 architecture.test.ts(依赖方向门禁)与 app/spec-coverage.test.ts(spec 对账门禁) |
mock/ | /mock/* dev 与 preview 端点:vite 插件加瓦片、字形、sprite、地形管线,自带单测;mock/README.md 为权威 |
public/ | 静态资产:fonts/(open-sans woff2)、styles/(klokantech 本地资产与离线回退样式) |
scripts/ | link-gmap.mjs(postinstall 符号链接守卫)、typecheck-mfe.mjs(mfe 入口检查)等 |
docs/refactor/ | 架构治理活文档:RULES、CHANGELOG、DEVELOPMENT-GUIDE、CAPABILITY-MATRIX,2026-10 起新增 SIMPLIFICATION-PLAN(简化重构评估) |
vite.config.ts / vitest.config.ts / stryker.config.json / tsconfig.json | 构建、测试、类型门禁配置(要点见配置参考) |
editor/src/app/ 一览
各层职责与代表文件
app 组合根(根级三个文件)。app.component.ts 约 1700 行,是全仓唯一允许横切装配的地方:三栏骨架、模态宿主、装载链与回退、全局快捷键、window.__MAPSTUDIO__ 调试句柄。app.config.ts 提供 zoneless 与依赖注入,bootstrap.ts 与 main.ts、mfe.main.ts 构成 standalone 自举与 ng-mfe Portal 注册双入口。改全局快捷键、加新弹窗宿主、动装载顺序,都落这里。
core/(105 个文件,18 个 @Injectable 含四个 store)。领域层,按域分目录,每个目录自带纯函数:
style-store.service.ts:样式文档唯一数据源。update 单写通道、immer 补丁撤销栈、保护锁、底图与导入双通道、导出双通道。2026-10 重构从 2851 行瘦到约 2100 行,拆出去的三块见下。map/style-diff.ts:StyleDiff 类型与 diffStyles 结构 diff。单独成文件的原因是 map 子树只需要它,不必反向依赖 store 本体(此前它是 core 级模块环的根源)。config/:ms-config 文档全家(model、codec、ConfigStore、分叉检测、layer-config-codec 词表、sort-key-bands)加basemap-delivery.ts(底图 interactivity 包装、作者标记、交付档解析的纯函数,627 行)。spec-tables.ts:spec 元数据静态对照表(合成属性、登记表、量程回退、分组对照),SpecService 只留查询逻辑,数据归数据。form/、expression/、map/、interaction/、history/、persistence/、diagnostics/、spec-doc/的职责见架构总览对应小节。
features/(85 个文件,约 65 个组件)。模板加事件转发,全部 OnPush。三类角色:组件(layer-list、map-canvas、multi-merge 等根级文件)、纯函数层(同目录的 *-fns.ts,如 layer-list-fns、basemap-presets)、登记表(import-layer-registry、global-panels 这类元数据文件)。子目录按界面域切:controls 是受控控件群、expression-builder 是构建器、global 是八面板、select-data 是数据配置页。
shared/(56 个模块)。零上行依赖的复用层,三种东西:纯函数与字典(主体,如 pop-anchor、zoom-eval、layer-display、color-convert、style-conventions、json-eq)、哑组件(modal-shell、prop-details 等八个)、指令两个加管道一个加轻量服务两个(context-menu、tree-filter)。spec-zh/ 是全中文 spec 词表的唯一定义处。
什么改动落在哪
新写或修改代码前先做归属判定。决策顺序如下:
几条经验规则补充:
- 动了写样式的地方,确认走的是
StyleStore.update或其便捷方法,不是绕开 store 直接调 maplibre。 - features 里的组件要互相复用逻辑时,把逻辑下放到同目录纯函数文件或 shared,不要 features 组件互相 import(expression-builder 与 controls 之间的既有互引是历史遗留,简化计划里有账)。
- 测试与源码互不越界:测试放
tests/镜像树,src 不为测试开缝。
tests/ 树与 src 镜像
单测文件放 editor/tests/,目录层级镜像 src/app,如 tests/app/core/style-store.test.ts 对应 src/app/core/style-store.service.ts,import 一律相对路径(vitest 无 @app alias)。根级例外两件:architecture.test.ts(依赖方向门禁)与 mock-tiles.test.ts(mock 管线)。
找「某类改动该落在哪」,先查架构总览各域小节,再回本页定位文件。想了解整个代码库哪些地方还胖、后续会怎么拆,读 editor/docs/refactor/SIMPLIFICATION-PLAN.md(2026-10 的全量体检:巨型文件清单、唯一的 core 级模块环、复制粘贴守卫代码盘点,以及分优先级的瘦身方案)。