Skip to content

构建与部署 ​

从源码到能用的服务,主干只有三步:npm run build 出 dist、Rust server 托管、打开浏览器验证。但真正会卡住人的都在支线上:worker 资产必须是 .js、mock 端点不进产物、npm 安装要 --legacy-peer-deps。这一页按流水线顺序讲,支线坑穿插在对应位置。

先看全流程 ​

流程图

日常开发不需要走完全程,npm run dev(:4230,strictPort)就够;下面各节是每个环节的细节。

构建产物长什么样 ​

  • 分包按 manualChunks 切:angular-*.js(Angular 运行时 + rxjs)、maplibre-*.js(最大的一块)、monaco-*.js(JSON 编辑器,只在打开时动态 import,不进首屏)、vendor-*.js、index-*.{js,css},sourcemap 开、target es2022。业务代码改动不会打爆三方缓存。
  • assets/maplibre-gl-worker.js 与 maplibre-gl-shared.js 显式命名落盘:vite 配置里的 maplibreWorkerAssetsPlugin 从 node_modules 逐字读取 maplibre-gl 的发行文件,改写 worker 内部相对 import 后发射。找不到预期字面量会直接抛错——这是故意的,防止上游结构漂移造成静默劣化。
  • fonts/、styles/ 从 public/ 拷贝。
  • 构建产物里没有 /mock/* 端点。mock 是 dev/preview 的 vite 插件,生产必须由 Rust server 或反代承接。

为什么 worker 必须是 .js ​

这里有个部署时最典型的坑,值得单独讲。maplibre-gl 6 是 ESM-only 发行版,它的 worker 是 module 型 Worker,浏览器对 ES module 脚本强制做 MIME 校验。.mjs 扩展名的 MIME 映射依赖静态服务器的配置——旧版 mime 表和 nginx 默认表普遍缺 .mjs,落到 octet-stream 就拒载 worker,表现是地图空白。.js 在所有服务器上都是 text/javascript,从根上绕开这个兼容面(ADR-09)。所以升级 maplibre-gl 后如果构建抛"资产改写失败",按报错同步 vite.config.ts 的 WORKER_ASSETS 配置,不要绕过插件。

生产 server 部署 ​

Rust server(axum 0.8 + tokio)是单体形态:静态托管 + mock 兼容端点 + 上传/档案 API,一个进程让编辑器完整跑起来。瓦片合成、PNG 编解码、sprite 拼装都是 crate 内实现,没有图像处理外部依赖。

推荐用仓库根的一键脚本:

bash
tools/build-server.sh              # editor 构建 → 拷 dist 到 server/static → cargo build --release
tools/build-server.sh --run        # 构建后直接启动
tools/build-server.sh --skip-web   # 前端 dist 已新鲜时跳过前端构建

或者手动指定目录托管:

bash
cd editor && npm run build
cd ../server && cargo run --release -- --static ../editor/dist
# 默认 127.0.0.1:2273;不传 --static 时工作目录存在 ./static 即自动采用

CLI 参数一览:--listen(默认 127.0.0.1:2273)、--config <yaml>、--static <dir>、--assets <dir>(默认 ./assets)、--data-dir <dir>(默认 ./server-data)。

server 提供的东西:

  • 静态托管带 SPA 历史回退,.mjs/.js 显式 text/javascript MIME(worker 兼容面的服务端半边,自带就不用操心 Nginx 配置)。
  • /mock/* 兼容端点(与 dev mock 七类逐项对齐)加规范路径 /tiles/*、/fonts/*、/sprite*。
  • 上传与数据档案 API(/api/fonts、/api/sprite、/api/tiles/{source}/schema),运行时上传数据落 server-data/(gitignored,重启不丢)。
  • 可选 martin-pg feature:内嵌 Martin 连 PG 矢量瓦片;默认反代形态零额外构建。接口全景见 server/API.md。

双入口与 MFE 联调 ​

编辑器有两个浏览器入口:standalone 的 src/main.ts(自动引导),和 ng-mfe Portal 子应用的 src/mfe.main.ts(不自动引导,注册为 defineMfeApp('mapstudio'))。后者只有做 Portal 联调才需要:起 editor dev(:4230)和 ng-mfe portal dev(:4200,#/apps/mapstudio),跑 node tools/verify-portal.mjs 验证。姊妹仓 ../gissdk_onemap 与 ../ng-mfe 不在场时,相关检查自动跳过,编辑器独立开发不受影响。npm run typecheck 末段的 mfe 专项检查同理会自动跳过。

CI/CD ​

  • ci.yml(PR + push main):quality(typecheck → vitest --coverage → build)→ e2e-smoke(verify-prod 生产冒烟)→ e2e-usecases(用例双向匹配 + 11 套)→ docs(docs-site 构建,死链即红)。门禁链的图解见测试策略。
  • nightly.yml(每日 UTC 18:00):全量 17 套 e2e + 视觉基线 11 态,diff 产物留 14 天。
  • 没有发布流水线:不发 npm 包、不推镜像、不上云,部署就是"构建 + 起进程"。

部署检查单 ​

部署后按序确认,每步都有对应的自动化工具可以先跑:

  1. GET /healthz 探活通过。
  2. 打开首页:地图渲染、图层树渲染、控制台零 pageerror(本地可先跑 npm run verify:prod 覆盖同款断言)。
  3. 底图与地形端点:/tiles/planet、/tiles/terrain 返回 TileJSON;样式里引用的绝对 URL 按对外 Host 正确拼接。
  4. 按需验证上传 API:/api/fonts、/api/sprite、/api/tiles 有响应。
  5. 反代场景:确认 .mjs/.js MIME 与 SPA 历史回退。直接用 Rust server 则跳过。

构建部署域的高频故障(worker MIME、/mock/* 404、peer 冲突、maplibre 升级构建抛错、子路径部署)集中在常见问题。