Strapi 开源贡献指南:从环境搭建到开发工作流、测试与提交规范
本篇技术文章基于 Strapi 官方贡献者文档(docs/docs/guides/00-contributing.md 引入的 CONTRIBUTING.md)展开,系统讲解向 Strapi 提交代码的完整流程:本地开发环境搭建、Monorepo 工作流、各类测试(unit / front / api / e2e)的运行方式、API 集成测试的底层实现,以及基于 commitlint 的 Git 提交规范。读完后你可以独立完成一次 Strapi 的 fork、本地开发、测试验证与规范化提交。
贡献文档入口与文档组织方式
Strapi 贡献者文档的入口是 docs/docs/guides/00-contributing.md。这个文件本身只是一个 MDX 包装器,通过 mdx-code-block 把仓库根目录的 CONTRIBUTING.md 作为组件引入并渲染其目录:
import Contributing, {toc as ContributingTOC} from "@site/../CONTRIBUTING.md"
<Contributing />
export const toc = ContributingTOC;
也就是说,真正的内容源是仓库根目录的 CONTRIBUTING.md,在线贡献者文档站点(contributor.strapi.io)也是基于 ./docs 目录构建的。这种“根目录 Markdown 为单一事实来源、Docusaurus 站点做引入渲染”的方式,保证了贡献流程说明与仓库始终同步。
Feature Request 与 RFC 流程
贡献文档为不同类型的贡献定义了不同的入口:
- Feature Request(功能请求):社区强烈鼓励提交功能请求或为现有请求投票,统一收集在官方反馈渠道(feedback.strapi.io)。
- RFC(Request For Comments):对 Strapi 可能影响大量用户的较大改动,在动手写 PR 之前需要经过充分的设计阶段。RFC 需要提交到独立的
strapi/rfcs仓库,由核心团队与社区共同讨论形成共识。官方特别提示:由于需要深入讨论,不要期望 RFC 能被立即合并接受。
行为准则与 CLA(贡献者许可协议)
- 本项目及其所有参与者都受 CODE_OF_CONDUCT.md 约束,参与前需要完整阅读并理解哪些行为是被容忍或不被容忍的。
- 个人贡献:接受 PR 前需要签署 CLA(Contributor License Agreement),只需签署一次。首次提交 PR 时会由 CLA bot 自动提示完成签署。
- 企业贡献:如果你代表公司向仓库提交代码,需要签署企业版 CLA(Corporate CLA),通过 contributions@strapi.io 联系官方办理。
文档贡献的两种去向
贡献文档明确了文档类 PR 的两种去向,避免提错仓库:
- 用户侧文档(Userland Documentation):针对最新稳定版文档的修复 PR 应提交到独立的
strapi/documentation仓库,并遵循该仓库自己的贡献指南。 - 贡献者文档(Contributor Documentation):即本仓库
docs/目录下的内容,也就是你现在阅读的这部分,直接从当前仓库的 develop 分支发起 PR。
Bug 上报
Strapi 使用 GitHub issues 管理 bug。在提交新 issue 前,官方要求你确认:
- 你遇到的是 Strapi 的技术问题,而非使用咨询(使用类问题应走官方文档、Discord 社区或社区论坛);
- 已搜索过相关 issues,不存在未关闭的同类问题(若找到已关闭的同类 issue,请在新帖中链接它);
- 标题简洁、切题、礼貌;提供了可复现步骤;
- 已尝试:确认启动了正确的项目、遵守 issue 模板、正文格式规范、用 CTRL+C 重启过 Strapi 服务、确保应用有干净的
node_modules(没有yarn link、没有对node_modules内文件的手工改动、没有全局依赖环)。不确定的话,最直接的验证方式是rm -rf node_modules && yarn cache clean && yarn install && yarn setup。
贡献前置条件
CONTRIBUTING.md 声明的贡献前置条件:
- Node.js 版本
>= v22 and <= v26,Yarnv1.2.0+; - 熟悉 Git。
结合仓库实际配置可以做两点补充校正:
- 从 package.json 的
engines字段看,当前仓库声明的 Node 要求为>=20.0.0 <=26.x.x(第 213-216 行),比贡献文档写的下限更宽松。实际开发时建议以贡献文档要求的 v22+ 为准,以 CI 环境对齐。 - 根 package.json 通过
packageManager: yarn@4.12.0锁定了 Yarn 4(第 212 行),仓库同时使用 Nx(nx@20.8.4)做任务编排、husky做 Git hooks(postinstall脚本为husky)。所以“Yarn v1.2.0+”是最小门槛,而当前仓库实际运行在 Yarn 4 之上。
提交 PR 前的检查清单
贡献文档要求提交 PR 前确保以下条件全部满足:
- Fork 仓库,并从
develop分支创建你的新分支; - 在仓库根目录执行
yarn install; - 在仓库根目录执行
yarn setup; - 如果你修复了 bug 或添加了应当被测试的代码,务必补充测试;
- 确保以下测试套件通过:
yarn test:unityarn test:frontyarn test:e2e --setup --concurrency=1- 可能需要先安装 Playwright 浏览器:
yarn playwright install - Enterprise(EE)e2e:需要把
STRAPI_LICENSE写入tests/e2e/.env(详见 docs/docs/guides/e2e/00-setup.md);
- 可能需要先安装 Playwright 浏览器:
- 运行
yarn lint确保代码通过 lint; - 如果贡献修复了某个已存在的 issue,请在 PR 中链接该 issue。
本地开发环境搭建
1. Fork 与克隆
用你自己的 GitHub 账号 fork strapi/strapi 仓库,然后克隆到你的机器上:
git clone git@github.com:YOUR_USERNAME/strapi.git
(YOUR_USERNAME 替换为你自己的 GitHub 用户名。)
2. 安装依赖并初始化
进入仓库根目录执行初始化:
cd strapi
yarn install
yarn setup
yarn ai:sync # link AI skills into your local tool directories (.agents/, .claude/, .cursor/)
从 package.json 的 scripts 定义(第 67-68 行)看,yarn setup 实际展开为:
yarn && yarn clean && yarn build --skip-nx-cache && tsx scripts/ai-tooling/post-setup.ts
即:安装依赖、清理各包的构建产物、跳过 Nx 缓存全量构建所有包(build 对应 nx run-many --targets build:code,build:types --nx-ignore-cycles)、最后执行 AI 工具链的后置脚本。yarn ai:sync 则把仓库内置的 AI 技能文件链接到本地的 .agents/、.claude/、.cursor/ 等目录,其入口实现在 scripts/ai-tooling/index.ts,支持 sync(支持 --force 参数)、unlink、status 三个子命令。
Git worktree 场景:如果你用 Git worktree 创建了一个独立 checkout,应改用专门的 setup 命令:
git worktree add <path> <commit-ish>
cd <path>
yarn setup:worktree
setup:worktree 对应 yarn install && yarn build && yarn ai:sync(package.json 第 68 行),比普通 setup 少了 clean 步骤、并额外同步了 AI 工具链接。
3. 启动示例应用
cd ./examples/getstarted
yarn develop
examples/getstarted 是仓库内置的完整示例应用(位于 examples/getstarted),包含预置内容模型、组件与插件,是贡献者本地验证最常用的一台“运行中的 Strapi”。贡献文档建议阅读该应用的 README 了解更多细节。
4. 以开发模式运行管理后台(admin panel)
要实时看到管理后台代码的改动效果,需要同时跑两个进程:
# 进程一:admin 包的 watch 构建
cd ./packages/core/admin
yarn watch
# 进程二:带 admin 热更的示例应用
cd ./examples/getstarted
yarn develop --watch-admin
两个命令必须同时运行:yarn watch(对应 package.json 中的 nx watch --all,见第 37 行)监听 admin 包源码变化并增量重建,而 develop --watch-admin 让示例应用加载正在 watch 构建中的 admin 产物。这样在 packages/core/admin 中修改代码后,示例应用的管理后台页面就能看到变化。
常用 Yarn 命令一览
贡献文档列出的核心命令,并附当前仓库 package.json 中的真实实现,便于理解每条命令背后在做什么:
| 命令 | 作用 | 仓库内实际实现 |
|---|---|---|
yarn watch |
对所有包启动 watch 构建 | nx watch --all -- 'nx run-many --targets build:code,build:types --projects $NX_PROJECT_NAME' |
yarn build |
构建 strapi-helper-plugin(在开发管理后台时使用) |
nx run-many --targets build:code,build:types --nx-ignore-cycles |
yarn commit |
交互式 commit CLI,辅助撰写符合 Git 规范的提交信息 | 直接调用 commit(@commitlint/prompt-cli) |
yarn setup |
安装依赖 | yarn && yarn clean && yarn build --skip-nx-cache && tsx scripts/ai-tooling/post-setup.ts |
yarn lint |
对整个代码库做 lint | nx run-many --target=lint --nx-ignore-cycles && yarn lint:other(含 prettier 检查) |
yarn test:clean |
清理覆盖率报告 | run-s -c test:api:clean test:e2e:clean test:cli:clean |
yarn test:front |
运行前端相关测试 | cross-env IS_EE=true nx run-many --target=test:front --nx-ignore-cycles -- --runInBand |
yarn test:front:watch |
前端测试的交互式 watcher | cross-env IS_EE=true run test:front --watch |
yarn test:unit |
运行后端单元测试 | nx run-many --target=test:unit --nx-ignore-cycles |
yarn test:api |
运行 API 集成测试 | node tests/scripts/run-api-tests.js |
yarn test:generate-app |
生成一个测试应用 | yarn build:ts && node tests/scripts/generate-test-app.js |
yarn test:run-app |
运行测试应用 | node tests/scripts/run-test-app.js |
yarn test:start-app |
启动测试应用 | node tests/scripts/start-app.js 一类脚本(见 tests/scripts) |
值得注意的是 test:front 默认带 IS_EE=true 环境变量,并且提供 test:front:ce / test:front:ee 变体来分别强制社区版/企业版测试;这与后文 API、e2e 测试中通过 license 控制 Edition 的机制一脉相承。
运行 API 集成测试
API 集成测试(test:api)需要一个真实的 Strapi 应用实例才能运行。官方流程:
$ yarn test:generate-app --db=sqlite
$ yarn test:generate-app --db=postgres
$ yarn test:generate-app --db=mysql
每次运行 API 集成测试前都需要一个全新的测试应用,否则测试套件会失败。yarn test:api 就是为此设计的便捷命令:它会在底层自动生成应用再跑 Jest。由于底层是 Jest,Jest 的选项可以直接透传给该命令,例如更新快照:yarn test:api -u。
切换数据库
test:api 默认生成使用 sqlite 的测试应用,也可以用 --db 切换:
$ yarn test:api --db=sqlite
$ yarn test:api --db=postgres
$ yarn test:api --db=mysql
从实现脚本 tests/scripts/run-api-tests.js 可以看到三种数据库的完整连接配置(第 14-43 行),这也是本地跑 postgres / mysql 集成测试前需要自备的数据库实例参数:
const databases = {
postgres: {
client: 'postgres',
connection: {
host: '127.0.0.1', port: 5432,
database: 'strapi_test', username: 'strapi', password: 'strapi',
schema: 'myschema',
},
},
mysql: {
client: 'mysql',
connection: {
host: '127.0.0.1', port: 3306,
database: 'strapi_test', username: 'strapi', password: 'strapi',
},
},
sqlite: {
client: 'sqlite',
connection: { filename: './tmp/data.db' },
useNullAsDefault: true,
},
};
脚本的其他关键行为(同文件):
- 测试应用生成在
test-apps/api目录(第 9 行),.env路径通过ENV_PATH传给 Jest 进程; --db参数由 yargs 解析,可选值即Object.keys(databases),默认sqlite(第 95-100 行);--generate-app默认为true,因此yarn test:api会自动先清理并重新生成应用(第 71-77 行);- 实际执行的是
jest --config jest.config.api.js --runInBand --forceExit(第 45 行),即使用仓库根目录的 jest.config.api.js 配置、单线程串行执行; - 运行环境会自动注入
STRAPI_DISABLE_EE:当未设置STRAPI_LICENSE时置为真(第 61 行),保证无 license 环境下 Strapi 以社区版启动,与贡献文档“默认跑 CE 测试”的描述一致。
运行企业版(EE)测试
测试套件默认运行社区版(CE)的测试。要运行企业版测试需要一个有效 license,通过环境变量 STRAPI_LICENSE 指定:
$ STRAPI_LICENSE=<license> yarn test:api
这与 run-api-tests.js 中 STRAPI_DISABLE_EE: !process.env.STRAPI_LICENSE 的逻辑严格对应:只要导出了 STRAPI_LICENSE,STRAPI_DISABLE_EE 即为 false,Strapi 才能以 EE 模式启动。
e2e 测试要点
e2e 测试基于 Playwright。除 PR 检查清单要求的 yarn test:e2e --setup --concurrency=1 外,完整说明见 docs/docs/guides/e2e/00-setup.md,要点:
- 首次运行需安装浏览器:
yarn playwright install; - 运行器会为每个测试 domain(如
content-manager)在test-apps下生成独立 Strapi 实例,端口从 8000 起递增,-c/--concurrency控制并行 domain 数; - 企业版 e2e 需把 license 写入
tests/e2e/.env(由tests/e2e/.env.example复制),运行器会在启动 Playwright 前用dotenv加载该文件;yarn test:e2e:ce/yarn test:e2e:ee可分别强制 CE / EE 模式。
Git 提交规范
Commit message 格式
Strapi 使用如下约定:
type: subject
body
该约定的目标是生成可以直接面向用户沟通的 changelog。
Type 的完整取值
文档正文给出了 fix / chore / docs / feat 四个示例,并指向 .commitlintrc.ts 查看完整列表。该配置文件基于 @commitlint/config-conventional,在 type-enum 规则(Error 级别、always)中定义的完整 type 集合为(第 10-22 行):
chore, ci, docs, enhancement, feat, fix, release, revert, security, test, future
各类型的语义:
fix— 修复问题;chore— 清理、工具链、重构等(通常仅用于内部工作);docs— 撰写文档;feat— 开发功能。
Subject 的写法
Subject 是对“这次提交做了什么”的概括,不是对代码行为的描述:
feat: what the feature isfix: what the problem ischore: what the PR is aboutdocs: what is documented
官方示例:
feat: introduce document servicefix: unable to publish documents due to missing permissionschore: refactor data-fetching in EditView to use react-querydocs: document service API reference
注意:对于
fix类型的提交,message 应当说明修的是什么问题,而不是描述解决方案。
用工具链保障规范落地
规范不是靠自觉,而是由提交时工具链强制的,从 package.json 的 devDependencies 可以看到完整链路:
@commitlint/cli+@commitlint/config-conventional:按.commitlintrc.ts校验提交信息,type 不在枚举内会报错;@commitlint/prompt-cli:即yarn commit调用的交互式 CLI,引导你按 type/subject/body 的格式填写提交信息;husky:在postinstall阶段安装 Git hooks,在 commit 时触发上述校验;.commitlintrc.ts中还内置了一个例外(第 26-31 行):匹配/^Merge branch '.*' into [a-zA-Z0-9\/\-_]+$/的 merge 提交信息会被忽略校验。
仓库组织:Yarn Workspaces + Nx 的 Monorepo
贡献文档指出,Strapi 采用 React 与 Babel 同款的 monorepo 设计,以保持整个生态的一致与同步。从当前仓库可以核实其组织方式:
- 根 package.json 的
workspaces字段声明了 7 类工作区:packages/*、packages/*/*、examples/*、examples/plugins/*、examples/*/src/plugins/*、.github/actions/*、scripts/*,并用顶层字段"isStrapiMonorepo": true标记(第 24-32、217 行); - 包间构建、测试、watch、lint 全部通过 Nx 的
run-many/watch编排,支持依赖图缓存与--nx-ignore-cycles(处理 monorepo 中存在的循环依赖); packages/下按域划分:核心运行时(core/strapi、core/core)、数据库层(core/database)、各插件(core/content-manager、core/admin等)、类型定义(core/types)、CLI 工具(cli/、generators/)、邮件与上传 provider(providers/)等。
贡献文档还提醒:develop 分支被尽量保持干净、测试随时通过,但其节奏可能快于发布周期。因此贡献者在关注分支策略时,应参考 npm 上 @strapi/strapi 的 release 版本来确认最新稳定版。
贡献流程速查
把全文压缩成一张可执行清单:
- 读 CONTRIBUTING.md,大改动先走 RFC,bug 先搜 issue;
- Fork 后从
develop拉分支,yarn install && yarn setup(worktree 用yarn setup:worktree),可选yarn ai:sync; - 用
examples/getstarted+yarn develop --watch-admin与packages/core/admin的yarn watch双进程做本地开发; - 补充测试后依次跑
yarn test:unit、yarn test:front、yarn test:e2e --setup --concurrency=1(必要时yarn test:api --db=sqlite验证 API 集成路径); yarn lint通过后,用yarn commit按type: subject规范提交(type 取.commitlintrc.ts枚举值);- PR 中链接所修复的 issue,签署 CLA,等待核心团队 review。
以上所有命令、路径与配置均以当前仓库的实际内容为准:test:api 的数据库参数见 tests/scripts/run-api-tests.js,e2e 的 CE/EE 机制见 docs/docs/guides/e2e/00-setup.md,monorepo 结构见根 package.json 的 workspaces 字段。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00