Ghost 动手改代码前如何判断功能处于什么迁移阶段:Active、Exploring 与 Planned 状态
【免费下载链接】GhostIndependent technology for modern publishing, memberships, subscriptions and newsletters.项目地址: https://gitcode.com/GitHub_Trending/gh/Ghost
在 Ghost 代码库里改代码之前,有一个绕不开的前置判断:你要动的那块功能,当前处于哪种迁移阶段?Ghost 正在同时推进 Ember 管理后台向 React 迁移、JavaScript 向 TypeScript 迁移、CommonJS 向 ESM 迁移等多条迁移线,仓库里最常见的写法往往是遗留模式,而不是你应该照抄的模式。判断依据只有一个事实来源:docs/codebase/direction.md。这份文档明确记录每个方向的当前状态,并且声明:Ghost 7.0 计划于 2027 年上半年发布,该文档描述的正是通向这个版本的工作方向,它不是路线图,也不是"一次迁移完所有东西"的承诺。
三个状态术语的确切含义
direction.md 用三个术语描述每个迁移方向所处的阶段,改代码前先确认自己面对的是哪一种:
- Active migration(活跃迁移):新工作走新路径,同时存量代码以连贯的单元逐步迁过来。
- Exploring(探索中):方向已经达成共识,但实现模式还在摸索,尚无定论。
- Planned(已计划):具体变更已确定要发生,但迁移尚未开始。
这个区分直接决定你的写法:Active 意味着"新功能必须走新路径";Exploring 意味着"方向定了但模式没定,先跟随邻近的成熟实现,别自己发明框架";Planned 意味着"旧契约目前仍受支持,但不要再基于它构建新功能"。
在状态表中定位你要改的区域
打开 docs/codebase/direction.md,核心内容是一张"Direction at a glance"状态表,按区域列出迁移方向和当前状态(以下为该表当前内容):
| 区域 | 迁移方向 | 状态 |
|---|---|---|
| Admin UI | Ember 到 React | Active migration |
| Application code | JavaScript 到 TypeScript | Active migration |
| Node.js modules | CommonJS 到 ESM | Active migration |
| Runtime boundaries | 用 Zod 校验未知数据 | Exploring |
| Server dependencies | 注入有状态依赖 | Exploring |
| Data access | Bookshelf 到 services、repositories、Knex | Exploring |
| Server state | 实例可互换、无状态 | Active migration |
| Repository layout | 相关项目合并进 monorepo | Active migration |
| Development patterns | 为重复性工作建立 golden path | Exploring |
| Database support | Ghost 7.0 移除 SQLite | Planned |
| Editor content | Ghost 7.0 移除 Mobiledoc | Planned |
| Self-hosting | Ghost 7.0 弃用 Ghost-CLI,改用 Docker | Active migration |
| Node.js runtime | 跟上 Node Current | Planned |
| Authentication | 基于 Better Auth 的标准化认证 | Exploring |
| Linting | ESLint 到 Oxlint | Planned |
如果你的任务落在表中某个区域,按那一行的状态行事;如果表中没有对应行,说明该方向未被列为当前迁移项,按就近的现有实现处理即可。
各状态对应的操作规则
Active migration:新功能必须走新路径
以 Admin UI 为例。apps/admin/README.md 说明新的 React 管理后台通过 Ember Bridge 渐进替换 Ember 管理后台:已迁移到 React 的路由渲染 React 组件,未迁移的路由回落到 Ember,两者共享同一 UI 空间。direction.md 对此的要求是:新 Admin 功能在apps/admin/中构建,用admin-x-framework做 API 访问、用 Shade 做 UI;不要因为功能的旧版本是 Ember 就新增 Ember 路由或继续用 Ember。迁移既有 Ember 功能时,要在连贯的产品边界上进行,并保留跨桥的导航、认证、共享状态和旧服务端行为。
服务端代码同理。ghost/core/core/server/services/README.md 规定:新的独立 service 逻辑默认用 TypeScript(除非必须扩展现有 JavaScript 模块);domain 逻辑用 TypeScript 加命名导出,只在 boot 代码或既有require()边界保留薄薄的 CommonJS 包装。
内部包层面,packages/README.md 规定新的内部包是 TypeScript-only 的 ESM 包(@tryghost/<name>、"type": "module"、私有、不发 npm release),并从packages/_template起步;每个私有包在ghostPackage.goldenPath中声明生命周期状态——compliant表示按 golden path 机械检查,migration是等待后续现代化 PR 的临时态,exempt是记录在案的长期例外,后两者必须带非空ghostPackage.reason。
Exploring:方向已定、模式未定,跟随邻近实现
Zod 是新的 runtime 边界首选校验库,从 HTTP、数据库、配置、队列、第三方服务到达的数据在校验前应视为unknown;但 direction.md 明确说明 schema 的归属与共享方式还没有统一布局,此时的正确做法是跟随一个已验证的邻近实现、保持一种形状只有一个真相来源,而不是自己拼一套手写校验。数据访问方向(Bookshelf 到 services/repositories/Knex)同样处于 Exploring:完整模式未定,不要新建 Bookshelf model、不要往 model 生命周期钩子里加新业务逻辑;在既有 Bookshelf 功能里工作时,先把行为收拢到显式的 service 或 repository 接缝后面,再替换持久化,不要为了绕开 model 而绕开既有行为。
Exploring 状态还有一个明确约束:把已同意的方向当作设计约束,而不是允许你发明局部框架;实现模式不清楚时,先把它定下来,再往代码库其他位置复制。
Planned:变更已确定但未开始,保留契约但不要围绕它建新功能
SQLite 与 Mobiledoc 都在 7.0 计划移除:Ghost 目前通过better-sqlite3支持 SQLite(旧配置名sqlite3仍兼容),但不要新增 SQLite 专属行为,也不要假设 SQLite 会长期是受支持的生产数据库。自托管方向上 Ghost-CLI 将在 7.0 被弃用、以 Docker 取代。在这些契约被移除之前,保留现有行为;在新功能里不要依赖它们。
Node.js 版本支持属于 Planned(长期跟上 Node Current),当前事实是:Ghost 支持 Node.js 22 和 24,CI 同时测试这两条线,新代码和新依赖必须两者都能跑。判断版本支持时查 docs/reference/node-compatibility.md 的兼容表,不要根据本机装的版本推断。
动手前的核对步骤
以下命令均来自仓库文档,在 monorepo 根目录或对应包目录下执行:
确认本地环境可用(新 checkout 时):
pnpm setup pnpm devpnpm dev会同时启动 MySQL、Redis 容器以及 Admin 和 Portal 的 dev watcher,主站位于http://localhost:2368,管理后台位于http://localhost:2368/ghost/(见 docs/README.md)。确认你所在包符合 golden path(改动
packages/下的内部包时):pnpm lint:packages该命令校验
ghostPackage.goldenPath状态以及所有可机械执行的规则(packages/README.md)。改动 Admin 时确认部署兼容性:Admin 与 Core 可以不同时间部署。依赖新设置、新端点或新配置值的新 Admin UI 必须检测后端支持,并在缺失时隐藏或安全禁用该功能——只有 Labs flag 不算兼容性检查,因为 flag 可能先于支持它的后端版本存在。apps/admin/README.md 要求为旧后端场景补验收测试。
交接前跑仓库统一的校验命令(见 docs/contributing/workflow.md):
pnpm checkpnpm check依次执行pnpm format:check、pnpm lint、pnpm test,但不包含浏览器 E2E 套件和 Ember Admin 测试——当你的改动落在这些区域时,需要按测试指南另行运行对应测试。
在过渡代码中工作的边界
direction.md 对"Working in transitional code"给出了硬性约束,这些约束独立于任何具体功能:
- 不要假设数量最多的模式就是被偏好的模式;
- 存在受支持的新路径时,不要扩大遗留依赖;
- 迁移要迁一个连贯的边界(连同它的测试和兼容行为),不要把大范围清理混进无关变更;
- 渐进迁移需要新旧两条路径共存时,两条都要保留;
- 当工作在不同阶段之间移动、某次迁移完成、或某个计划中的工具变成权威依据时,更新 direction.md 本身。
最后的限制要说清楚:状态表是某一时点的快照,开始一个跨天的任务前重新核对当前main上的 direction.md;当某个区域已有专门的聚焦指南(如 authentication.md、services 指南),实现细节以那份指南为准,direction.md 只提供审查方向。
【免费下载链接】GhostIndependent technology for modern publishing, memberships, subscriptions and newsletters.项目地址: https://gitcode.com/GitHub_Trending/gh/Ghost
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考