Skip to content

Decap CMS:把 Git 仓库变成静态站点的内容后台

Decap CMS(原 Netlify CMS)的定位是:把一个单页 React 应用(SPA)放进网站 /admin/ 路径。编辑者在 CMS 中填写表单,内容仍以 Markdown、JSON、YAML 或 TOML 文件保存在 Git 仓库,再由静态站点生成器构建公开站点。本文依据 2b772c7 对应的源码快照整理。[E01][E02]

选型结论:已经把内容放在 Git 中、又希望非开发人员拥有可配置编辑后台的团队,可以优先评估 Decap CMS;提交、分支和 Pull Request 审阅仍能保留。需要数据库查询、复杂权限模型、实时协作或完全托管内容平台时,应把 Decap CMS 与托管型或无头 CMS(SaaS/headless CMS,内容通过服务商 API 提供)放在一起比较。

后文的“后端”指负责读写 Git 内容的适配器,“内容集合”对应配置文件中的 collection,“编辑工作流”指用草稿分支和 Pull Request 审阅内容的方式。

先判断是否适合

  • Decap CMS 解决什么问题:给静态站点增加内容编辑界面,而不要求编辑者直接改 Markdown 或 Git 文件。[E01]
  • 内容放在哪里:后端 API 负责读写 Git 仓库;config.yml 决定文件格式、目录和媒体位置。换句话说,内容仍是普通 Git 文件,后台只是提供编辑界面。[E03][E05]
  • 扩展方式:主应用用扩展注册表登记后端、字段组件、编辑器组件和语言包。仓库内置 GitHub、GitLab、Bitbucket 等多种后端,增加新字段时只需接入对应组件。[E04]
  • 工程形态packages/* 组成一个超过 20 个包的多包单仓库(monorepo),维护者用 npm workspaces 管理依赖;批量构建和发布由仓库脚本负责。[E06][E07]

适合谁,不适合谁

适合

  • 使用 Hugo、Jekyll、Gatsby、Next.js 静态导出或其他静态生成器的网站;
  • 希望内容修改留下 Git commit、分支和 Pull Request 记录的团队;
  • 需要通过 YAML 配置内容模型,并允许逐步加入自定义字段组件、预览和媒体库的项目;
  • 能接受“Git 是事实来源,构建系统负责发布”的运维边界。

不适合或需要谨慎

  • 需要基于角色的细粒度访问控制(RBAC)、审计报表、实时协作、事务查询或大量结构化关系数据的内容平台;
  • 不希望编辑者接触 Git 权限、OAuth 授权登录、Git Gateway 或仓库分支策略的团队;
  • 依赖某个后端的商业服务,却没有准备好处理 OAuth 授权、API 速率限制、媒体存储和失败重试;
  • 需要在文章未覆盖的部署环境直接执行生产迁移,应该先在目标站点完成小范围验证。

项目快照

项目版本decap-cms@3.15.1(截至 2026 年 8 月 30 日的最新版本发布)
源码快照2b772c7main HEAD)
项目类型React 单页应用 + 可扩展 CMS 框架
主要语言JavaScript、TypeScript、HTML、CSS
许可证MIT(仓库 LICENSE 与 GitHub metadata 均标注)
社区信号约 1.93 万 Star、3.1 千个派生仓库、592 个开放 Issue;仅作活跃度背景,不等于质量评分
核对日期2026 年 8 月 30 日
验证边界源码/清单静态核对;未安装、未运行、未登录 GitHub/Netlify

社区指标和版本发布记录会变化,应以 GitHub 仓库Releases 当前页面为准。[E08][E09]

源码里的三处分工

1. CMS 嵌入站点,不另起内容服务器

根 README 将 Decap CMS 描述为放入站点 /admin 部分的单页应用。未设置 window.CMS_MANUAL_INIT 时,decap-cms 入口会自动调用 CMS.init()。入口还会把 CMS、初始化函数以及兼容用的 createClassh 暴露到 window。快速安装只需要 HTML 和配置文件;需要自定义扩展时,再通过 npm 组合所需模块。[E01][E10]

2. 扩展集中登记,再由统一入口装配

packages/decap-cms-app/src/extensions.js 集中登记后端适配器、字段组件、编辑器组件和语言包。扩展注册表把核心编辑器与后端、字段、媒体能力分开:新增后端通常实现统一接口,新增字段只需登记组件,不必改动所有编辑页面。[E04]

3. GitHub 后端同时覆盖两种 API 和编辑工作流

GitHub 后端把认证、文件读写和审核协作拆开维护。实现层读取分支、开放式贡献、use_graphql 和媒体目录等配置,再根据配置选择对应的 API 客户端。[E11][E12]

文件读写同时提供 REST 风格接口和 GraphQL 查询接口。前者处理文件、目录树、提交和 Pull Request,后者借助 Apollo 客户端库读取仓库文件和 Pull Request。fragment 是 GraphQL 查询中复用字段的片段,作用是保持返回结构一致。[E11][E13]

普通编辑、开放式贡献和编辑工作流共用同一套编辑模型,但权限、分支策略和 API 差异仍要纳入部署设计。源码把底层失败统一转换成 CMS 可识别的 API 错误,方便界面展示和后续处理。[E12][E13]

典型使用任务

把 CMS 放进 /admin/

内容分发网络(CDN)安装适合先验证流程:在站点中加入 CMS HTML 入口和 config.yml,再配置一个可用后端。项目 README 同时提供单个 HTML 文件的快速安装和 npm 包安装路径。[E01]

html
<script src="https://unpkg.com/decap-cms@3.15.1/dist/decap-cms.js"></script>

上面的版本固定方式只是示例。生产环境应根据官方安装文档和发布策略选择版本,并验证内容分发网络、内容安全策略(CSP)与浏览器兼容性。

配置第一组内容集合

以下是官方配置模型的最小示例。backend 指定内容读写方式,media_folderpublic_folder 分别指定媒体存储目录与公开 URL,collections 描述内容集合;目录、字段和发布模式需要按实际静态站点调整。[E05][E14]

yaml
backend:
  name: github
  repo: owner/site-content
  branch: main

media_folder: static/images/uploads
public_folder: /images/uploads

collections:
  - name: posts
    label: Posts
    folder: content/posts
    create: true
    fields:
      - { label: Title, name: title, widget: string }
      - { label: Date, name: date, widget: datetime }
      - { label: Body, name: body, widget: markdown }

核心包的配置规则还覆盖本地后端、多语言、媒体处理、发布模式、预览链接和内容集合视图。首版配置不必一次启用全部选项,先确认后端与内容目录能够完成最短流程。[E05]

启用草稿与 Pull Request 审核

publish_mode 设为 editorial_workflow 后,CMS 会围绕草稿分支和 Pull Request 组织编辑流程。GitHub 后端还支持 open_authoring,允许贡献者从派生仓库(fork)发起改动。权限范围(OAuth scope)决定令牌能访问什么,分支保护和合并策略也必须一起配置,不能只改 YAML 就视为完成上线。[E12][E15]

从接入到首次发布

  1. 准备一个已能正常构建的静态站点,并确认内容目录、媒体目录和部署触发方式。
  2. 选择安装方式:快速路径使用内容分发网络(CDN)HTML;需要自定义构建产物、扩展或依赖约束时使用 npm 包。[E01][E10]
  3. 创建 admin/index.htmladmin/config.yml,先只配置一个内容集合、一个文本字段和一个 Markdown 字段。
  4. 选择后端适配器。GitHub 后端需要仓库、分支和认证方式;使用 Git Gateway 时,Netlify Identity 负责身份认证,Git Gateway 负责把请求代理到 Git 内容后端,也可以换成兼容的代理服务。[E11][E16]
  5. 在隔离的测试仓库中完成登录、读取文章、保存草稿、生成提交和 PR、构建静态站点,再演练一次回滚。
  6. 再增加媒体处理、多语言、自定义字段组件、预览和开放式贡献。每增加一项后端能力,都记录权限、失败分支和恢复方式。

成功标准不是“看到 /admin/ 页面”,而是编辑者能在预期权限下完成一次可追溯的内容变更,静态站点也能产出可观察、可回滚的构建结果。

源码如何协作:沿调用链看运行过程

上节概括了模块职责,本节沿启动和保存两条调用链,说明这些模块如何在一次编辑操作中配合。

启动链路

decap-cms-core/src/bootstrap.js 创建 React 根节点,挂载 Redux 状态容器、路由和错误边界。源码中的 Provider、Router 分别负责向组件提供状态和路由上下文。启动过程先分发 loadConfig,回调中再分发 authenticateUser,所以配置加载和用户认证是进入编辑界面前的两个关键门。[E17]

模块如何分工

一次保存操作的源码路径

一次保存操作可以拆成四步:表单收集内容,入口逻辑按内容集合选择后端,序列化内容和媒体,最后提交到 Git。源码入口位于 core/src/actions/entries.ts,这里的 action 指负责协调一次状态变化的函数。[E18]

GitHub 后端的 API.ts 负责 REST 文件、目录树、提交和 Pull Request;GraphQLAPI.ts 负责查询仓库文件和 Pull Request。两条客户端路径共同支撑保存和审核,但没有覆盖所有字段组件、多语言和媒体分支。[E12][E13]

文件结构与源码阅读顺序

text
packages/
├── decap-cms-app/                 # 面向使用者的入口与默认扩展装配
├── decap-cms-core/                # 启动、Redux、路由、编辑器、配置和 actions
├── decap-cms-backend-github/      # GitHub REST/GraphQL backend
├── decap-cms-backend-git-gateway/ # Netlify Git Gateway 与 JWT/PKCE 认证
├── decap-cms-backend-*/           # GitLab、Bitbucket、Gitea、Forgejo、Azure 等
├── decap-cms-lib-auth/            # OAuth/PKCE 辅助
├── decap-cms-lib-util/            # API、媒体、文件和 workflow 公共工具
└── decap-cms-widget-*/            # 字段 widget
cypress/                           # backend、workflow、media 和 widget E2E 场景
dev-test/                          # 多 backend 本地测试页面与配置

源码阅读可以按“入口装配 → 启动流程 → 保存操作 → 后端请求”的顺序进行。先看扩展注册,再看配置加载和认证,随后追踪一次内容保存,最后进入 GitHub API 客户端。对应文件依次是 extensions.jsbootstrap.jsentries.tsAPI.tsGraphQLAPI.ts。Cypress 测试用例用于核对边界场景。[E04][E17][E18][E19]

工程化与质量信号

package.json 提供代码规范检查、TypeScript 类型检查、Jest 单元测试和 Cypress 端到端测试命令。持续集成流程会把这些检查组合起来。仓库还按后端适配器、编辑工作流、媒体库和字段组件维护 Cypress 场景,兼容性测试因此成为维护成本的重要部分。[E06][E19]

这套设计也增加维护负担。这是一个规模不小的前端多包单仓库,构建、状态管理、GraphQL、测试和编辑器各自依赖不同工具。升级或自定义时,维护者需要同时处理包版本、构建流程、依赖约束、后端 API 和站点部署。Decap CMS 不是只改几行 YAML 的插件。[E06][E20]

安全、运维和限制

  • 认证与权限:GitHub 后端会使用 OAuth 授权令牌;auth_scope、仓库权限、分支和开放式贡献设置共同决定可读写范围。[E12]
  • 第三方服务边界:Git Gateway 依赖 Netlify Identity(Netlify 的身份认证服务),并使用 JWT(令牌格式)和 PKCE(授权码保护流程),还可接入大文件服务;这条链路不能直接替代 GitHub 后端。[E16]
  • 内容与媒体:媒体文件可能走 Git 大文件存储(LFS)、外部媒体库或浏览器端图片处理;存储成本、处理结果和回滚路径需要分别确认。[E05][E16]
  • 失败恢复:API 限流、OAuth 过期、分支冲突、Pull Request 合并失败和构建失败都应在测试仓库中演练。
  • 供应链:生产站点应锁定 npm/CDN 版本、配置内容安全策略(CSP)、审查自定义字段组件和媒体库,并在升级前阅读变更记录与发布说明。
  • 许可证:Decap CMS 仓库使用 MIT,但 Git 服务、媒体服务、OAuth 应用和站点内容的条款需要分别核对。

和哪些项目比较

选择更适合的场景关键取舍
Decap CMSGit 内容源、静态生成器、需要 PR/分支工作流灵活且可自托管前端,但认证和 Git 运维由团队承担
TinaCMS希望更强的可视化编辑和 React 集成编辑体验更强,平台和数据模型取舍不同
Sanity / Contentful需要托管 API、结构化查询、团队权限降低 Git 运维,但引入 SaaS、费用和平台依赖
Directus / Strapi希望自建数据库型 headless CMS数据库与 API 能力更强,部署和运维面更大

比较时优先看内容事实来源、认证责任、预览/发布方式、媒体存储、审计和迁移成本,不要只比较编辑器截图。

上线前要验证的 5 件事

  1. 用测试仓库验证 GitHub REST 后端的登录、读取、写入、冲突和回滚。
  2. 如果需要编辑工作流,再验证分支保护、PR 状态同步和开放式贡献的派生仓库流程。
  3. 用目标静态站点验证 media_folderpublic_folder、Git 大文件存储(LFS)、外部媒体和构建缓存。
  4. 在隔离环境中运行仓库声明的 npm cinpm run test:ci 和必要的端到端测试(E2E)。
  5. 将实际验证结果补回证据记录,并明确区分源码静态核对与运行验证。

main 指向新的提交、发布新版本或后端 API 变化时,应重新审核文章,避免沿用旧结论。[E08][E21]

证据索引

  • E01:仓库 README,项目定位、SPA /admin/、安装方式和 MIT 声明。
  • E02:仓库 main HEAD commit,文章采用的源码快照。
  • E03:GitHub backend README,Implementation/API/GraphQLAPI/AuthenticationPage 分工。
  • E04decap-cms-app/src/extensions.js,后端、widget、编辑器组件和 locale 注册。
  • E05decap-cms-core/src/constants/configSchema.js,backend、media、i18n、publish mode 和 collection 配置 schema。
  • E06:根 package.json,Nx/Lerna monorepo、build/test/lint/type-check 命令和 workspaces。
  • E07packages/decap-cms-core/README.md,超过 20 个包的 monorepo 说明。
  • E08:GitHub REST repository metadata,默认分支、语言、topics、许可证和动态指标。
  • E09:GitHub latest release API,decap-cms@3.15.1
  • E10packages/decap-cms-app/src/index.js 与 package README,自动/手动初始化及 npm/CDN 使用方式。
  • E11packages/decap-cms-backend-github/package.json 和 README,REST/GraphQL 依赖与模块结构。
  • E12packages/decap-cms-backend-github/src/implementation.tsx,branch、open authoring、API root、media 和 GraphQL 配置。
  • E13packages/decap-cms-backend-github/src/GraphQLAPI.ts,Apollo、repository/blob/Pull Request 查询和错误处理。
  • E14:Decap CMS 官方 configuration options 文档,配置入口和选项说明。
  • E15:仓库 Cypress editorial workflow specs,REST/GraphQL/open authoring 测试覆盖。
  • E16packages/decap-cms-backend-git-gateway/README.md 与 implementation,Netlify Identity、Git Gateway、JWT/PKCE 和 Large Media。
  • E17packages/decap-cms-core/src/bootstrap.js,React root、Redux、Router、loadConfig 和 authenticateUser 启动链。
  • E18packages/decap-cms-core/src/actions/entries.ts,entry provider 选择和持久化 action。
  • E19:仓库 Cypress 目录和根测试脚本,backend/workflow/media/widget E2E 与 unit test。
  • E20packages/decap-cms-core/package.json,React/Redux/Immutable/webpack 等核心依赖。
  • E21:文章采用 GitHub Guides refresh policy,commit 变化进入 review-due,不自动判定 stale。

文章结论绑定 source commit;动态信息以核对日期为准。