Ghost 单仓库(Monorepo)架构导航:pnpm Workspace + Nx 驱动的全栈发布流水线
Ghost 单仓库Monorepo架构导航pnpm Workspace Nx 驱动的全栈发布流水线【免费下载链接】GhostIndependent technology for modern publishing, memberships, subscriptions and newsletters.项目地址: https://gitcode.com/GitHub_Trending/gh/GhostGhostREADME是当前采用pnpm workspace Nx组织的单仓库Monorepopnpm 负责把apps/、ghost/core/、koenig/、packages/等子项目链接成一份本地依赖图Nx 则基于这份依赖图调度 build、lint、test、dev 等任务并缓存产物。阅读本指南后你将掌握在仓库中定位任一模块前端应用 / 服务端 Core / 编辑器 / 共享库的方法workspace:与catalog:依赖声明的区别与用法以及开发期直接跑 TypeScript 源码、生产期用编译产物这套双轨构建机制是如何实现的。Monorepo 概览pnpm 提供依赖图Nx 驱动任务根 package.json 把仓库声明为名为ghost-monorepo的私有根包private: true并锁定包管理器与运行环境packageManager: pnpm12.2.1...且通过preinstall钩子执行 scripts/enforce-package-manager.js 强制使用 pnpmengines: { node: ^22.23.1 || ^24.20.0 }约束 Node 版本。pnpm-workspace.yaml 是哪些目录是工作区的唯一事实来源它通过 glob 声明了全部工作区packages: - ghost/* - apps/* - e2e - koenig/* - packages/** - !packages/_template # 新包模板本身不参与工作区 - configs/* - scripts文件里还包含一批现代 pnpm 加固配置strictDepBuilds: true、catalogMode: strict、通过allowBuilds对原生依赖构建做版本级白名单如better-sqlite312.11.1、sharp0.35.3、通过overrides统一收敛传递依赖版本典型例子是把knex-migratorknex钉回 2.4.2与 ghost/core 使用的 knex 主版本对齐。这些配置共同决定了依赖解析的安全边界。而 nx.json 定义了 Nx 的运行行为parallel: 4控制并行度、cacheDirectory: .nxcache存放缓存、namedInputs中的sharedGlobals把根级配置文件pnpm-workspace.yaml、pnpm-lock.yaml、ghost/tsconfig.json等纳入每个任务的输入指纹。修改某个应用或包之前先阅读它旁边同目录的 README这是仓库内约定俗成的守则。顶层目录总览目录内容apps/Admin 应用、面向浏览器的公开应用与前端库ghost/core/Ghost 服务端、前端渲染、数据库迁移与服务端测试koenig/Koenig 编辑器以及内容存取 / 转换 / 渲染相关的kg-*包packages/共享库、schema、翻译、测试数据与适配器adapter契约configs/共享的 ESLint、TypeScript、Vite 与 Vitest 配置包e2e/覆盖完整 Admin 与公开站点旅程的 Playwright 测试docker/本地开发与 CI 用容器及配套服务scripts/仓库初始化、校验、构建与发布工具链前端应用布局apps/下的三类工程apps/下并存着定位截然不同的前端工程改动前必须分清它们属于哪一类admin —— 新的 React Admin 应用正逐步取代旧版ember-admin —— 遗留的 Ember Admin路由正随时间推移陆续从 Ember 迁到 Reactactivitypub —— 内嵌在 Admin 中的 React 应用portal、comments-ui、signup-form、sodo-search、announcement-bar、admin-toolbar —— 发布到 npm、并通过 CDN 以script标签加载的公开应用public appsshade —— 当前 Admin 的设计系统admin-x-framework —— 提供共享 Admin API hooks、路由与工具函数。公开应用的运行模型与普通 SPA 不同它们把浏览器产物打包成 UMD例如 apps/portal/package.json 的files只包含umd/、LICENSE、README.md页面通过 script 标签加载运行时配置来自 DOM 的>pnpm nx show projects # 列出所有可识别的工作区项目 pnpm nx show project project-name # 查看单个项目的 targets 与依赖 pnpm nx graph # 浏览器中打开依赖关系图 pnpm nx run project-name:target # 运行指定项目的某个 target如 pnpm nx run tryghost/admin:build根 package.json 里的pnpm build、pnpm lint、pnpm test本质都是pnpm nx run-many -t target——即对全仓各项目执行同名 target例如pnpm buildrun-many -t build而pnpm lint除了 run-many 还会追加lint:boundaries依赖巡航边界检查与lint:packages校验内部包黄金路径。日常开发可先执行一次pnpm setup安装 初始化 submodule再按需pnpm dev基于 compose.dev.yaml 的 Docker 开发栈。源码与生产构建source导出条件的双轨机制这是本仓库最具特色的构建设计。部分 TypeScript 包在导出中把source条件放在编译产物之前见 packages/README.md 的示例 exportssource: ./src/index.ts→types→default。Ghost Core 的开发服务器与测试会启用source条件从而直接加载tryghost/kg-default-nodes这类包的原始 TypeScript——每次改动无需tsc重编译即可被正在运行的 dev server 和 core 测试命中。生产环境不启用sourceNode 走default条件加载build/里的编译产物Ghost 发布归档包含的也是这些编译文件而非包源码浏览器应用同样使用各自的常规构建输出。一个直接推论是源码改动可能在开发环境立刻生效但涉及产物内容的生产构建仍需要重新执行pnpm build——当你改动包导出、构建配置或任何进入发布产物的代码时务必补跑构建。Koenig 已发布的kg-*包作为既有对外契约保留了独立的 ESM 与 CommonJS 双输出import从build/esm/解析require从build/cjs/解析。它们的files列表包含build/但不包含src/因此source条件所用的原始 TypeScript 永远不会被发布出去而新建的内部包一律采用 ESM-only 契约。此外由于 Ghost Core 本身是 CommonJS 却跑在支持require(esm)的 Node 上仓库 engines 要求 Node ≥ 22内部 ESM 包可同时服务import与require()两类消费者——前提是整个被引用的模块图不能出现顶层awaitESLint 会强制这一限制。仓库之外的关联项目Ghost 的若干组成部分仍然维护在独立仓库中gscan负责校验 Ghost 主题Ghost-CLI用于安装与管理生产环境站点Source、Casper、Themes存放官方主题framework承载 Ghost 使用的共享 Node.js 包SDK提供围绕 Ghost API 的工具链。本文只聚焦本仓库内部结构这些外部仓库的具体用法以它们各自的文档为准。对本仓库而言最值得记住的实践结论是改包之前先看对应目录的 README改外部依赖版本先去pnpm-workspace.yaml的 catalog改包导出/构建配置后记得跑pnpm build——遵循这三条你就能在 Ghost 这个庞大的 monorepo 里安全地穿梭于编辑器、服务端与共享库之间。【免费下载链接】GhostIndependent technology for modern publishing, memberships, subscriptions and newsletters.项目地址: https://gitcode.com/GitHub_Trending/gh/Ghost创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考