mcpField
N
nocobase-plugin-development

nocobase-plugin-development

github.com/nocobase开发55232 次安装8 周前更新
代码仓库

关于 nocobase-plugin-development

该技能指导 AI Agent 完成 NocoBase 插件开发,从需求分析、脚手架搭建到代码生成、启用和排错。它强调遵循 NocoBase 规范、仅在 client-v2 编写客户端代码,并要求编码前确认计划。

主要功能

  1. 01将需求映射到扩展点
  2. 02使用 `nb scaffold plugin` 创建脚手架
  3. 03生成服务端与 client-v2 代码
  4. 04创建本地化文件并验证插件
  5. 05执行实现规范与计划确认门槛

适用场景

  1. 01根据功能需求开发 NocoBase 插件
  2. 02添加服务端 API 和客户端界面元素
  3. 03排查插件设置或运行问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nocobase/skills --skill nocobase-plugin-development

安装后在 Claude Code 中输入/nocobase-plugin-development确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
build.md
getting-started.md
index.md
references/client/
action.md
block.md
component.md
ctx.md
field.md
flow.md
i18n.md
plugin.md
resource.md
router.md
references/server/
acl.md
collection.md
context.md
data-source-manager.md
database.md
i18n.md
middleware.md
migration.md
plugin.md
resource-manager.md
test.md

详细介绍

目标

指导 AI Agent 完成 NocoBase 插件开发的整个流程——从需求分析到可运行代码,产出符合 NocoBase 规范且可立即启用的插件。

范围

  • 分析用户需求,并将其映射到 NocoBase 扩展点。
  • 使用 nb scaffold plugin 搭建新插件。
  • 生成服务端代码:数据表、ACL、自定义 API、迁移、安装钩子。
  • 生成客户端代码:区块、字段、操作、设置页面、路由。
  • 生成 i18n 语言文件。
  • 启用并验证插件。
  • 使用 FAQ 清单和源代码(如有)排查常见问题。

非目标

  • 不通过 UI 构建 NocoBase 应用(请使用 nocobase-ui-builder)。
  • 不处理插件发布到外部注册表。
  • 不修改 NocoBase 核心代码。
  • 不将现有插件从客户端 v1 迁移到 v2(请使用 nocobase-client-v2-plugin-migration)。

硬性约束

以下规则适用于所有生成的插件代码。违反这些规则始终是错误的。

绝不能使用 this.app.use() 或 React Provider

this.app.use() 是内部 API。插件绝不能使用它,通过 React Provider 包装应用。这不是建议,而是一条没有例外的硬性规则。

Provider 会增加不必要的 React 渲染层、损害性能,并使插件更难维护。实现全局效果(水印、叠加层、主题、跟踪、全局监听器等)时,请改用以下方式:

  1. FlowEngine 机制(首选)——使用 registerModelLoaders、registerFlow、registerModels 实现 UI 功能。
  2. FlowEngine 上下文——this.context 包含全局数据(例如 this.context.api、this.context.dataSourceManager、this.context.logger)。直接读取这些数据,无需创建 Provider 来传递数据。注意:user、viewer、message、themeToken 等属性只有在 React 渲染后才可用——请在流程处理器或组件中使用它们,而不要在 load() 中使用。
  3. API 请求——如果插件需要数据,请使用 this.app.apiClient.request() 直接获取。允许使用 Axios 拦截器,但不应将其作为首选——尽可能优先直接请求或从上下文读取数据。
  4. 纯 DOM 操作——对于视觉效果,可在 load() 中直接操作 DOM。无需 React 组件。
  5. EventBus——使用 this.app.eventBus 响应应用生命周期事件。

如果你发现自己在想“我需要一个 Provider 来实现这个功能”,请停下来重新考虑。总有更好的替代方案。

客户端代码只能放在 client-v2

所有插件客户端代码都必须写入 src/client-v2/。src/client/ 目录属于旧版 v1 客户端——不要在其中编写或修改任何文件。从 @nocobase/client-v2 导入 Plugin,绝不能从 @nocobase/client 导入。

新版客户端运行在 /v/ URL 前缀下

client-v2/ 源目录对应 /v/ 运行时 URL 前缀。登录后,用户默认进入 /v/admin/。告知用户访问位置时,请使用 /v/ URL 格式:

注册内容访问地址
插件管理器、内置管理页面/v/admin/
插件设置页面/v/admin/settings/<menuKey>
通过 this.router.add('xxx', { path: '/foo' }) 注册的自定义路由/v/foo(不是 /v/admin/foo)

如果用户说“我启用了插件,但什么都没显示”,或者遇到 404,最常见的原因是他们访问的是 /admin/... URL(调用 pm:listEnabled 的 v1 插件管理器),而不是 /v/admin/(调用 pm:listEnabledV2 的新版插件管理器)。请告知他们切换到 /v/ URL。

输入约定

输入必需默认值验证澄清问题
requirement是无非空的自然语言描述“这个插件应该做什么?”
nocobase_root否当前工作目录必须包含 NocoBase 源码树:由 CLI 管理的 Git 源码应用(包含 source/packages/core/),或 NocoBase 源码仓库(包含 packages/core/)“你的 NocoBase 源码项目在哪里?开发插件需要 Git 源码安装或克隆的源码仓库。”
plugin_name否根据需求生成@<scope>/plugin-<name> 格式“插件包应该叫什么名字?”

规则:

  • 如果未提供 nocobase_root,检查当前工作目录是否为包含源码树的 NocoBase 项目。
  • 如果这是没有源码树的 NocoBase 应用(Docker 或 npm 安装),则停止,并在 Step 0 中引导用户选择方案——源码树是必需的,无法绕过。
  • 如果未提供 plugin_name,根据需求生成一个合适的名称,并与用户确认。
  • 如果用户说“由你决定”,则使用文档中规定的默认值。

强制澄清关卡

  • 最多澄清轮数:2
  • 每轮最多提问数:3
  • 修改的前置条件:
    • nocobase_root 包含 NocoBase 源码树(由 CLI 管理的 Git 源码应用需包含 source/packages/core/,普通源码仓库需包含 packages/core/),并且前者可用 nb CLI,后者可用 yarn。
    • requirement 足够明确,可以确定需要哪些扩展点。
    • 用户已用通俗语言确认功能计划。
  • 如果两轮后仍未满足前置条件,则停止并说明缺少哪些内容。

重要:在编写任何代码或运行任何脚手架命令之前,必须始终与用户确认计划——即使需求看起来完全清楚也不例外。 用户往往有未说明的假设、尚未考虑的边缘情况,或对范围的偏好。计划确认步骤(Step 2)是必须通过的关卡,而非建议。绝不能跳过。

工作流程

Step 0:环境检查(硬性关卡——必须有源代码)

开发插件需要 NocoBase 源码树。 脚手架搭建、构建和调试都在源码仓库内的 packages/plugins/ 中进行。没有源代码的环境无法使用;必须停止并告知用户如何获取源码,不得尝试继续搭建脚手架。

  1. 检测环境类型:
    • 由 CLI 管理的源码应用:存在 source/ 目录(由 nb init 创建)。源码树位于 <app-path>/source/。通过检查 source/packages/core/ 是否存在,确认这是 Git 源码安装。
    • 普通源码仓库:存在 packages/core/,但没有 source/——这是用户自行克隆的仓库(git clone https://github.com/nocobase/nocobase.git)。源码树位于仓库根目录。
    • 两者都不符合 → 停止。请参阅下文“没有可用的源码树”。
  2. 验证工具链:由 CLI 管理的应用需使用 nb CLI,普通源码仓库需使用 yarn。
  3. 确认源码树完整——其中必须存在 packages/core/。这样才能读取核心源码以排查问题,也是构建所依赖的条件。
没有可用的源代码树 — 停止并告知用户

如果工作目录是由 CLI 管理的应用,且其 source/ 来自 Docker 或 npm(没有 source/packages/core/),或者根本不是 NocoBase 项目,不要进行脚手架搭建。请说明情况,并提供以下两个选项:

  • 使用 Git 源重新创建项目 — 运行 nb init --ui,并在源代码提示中选择 Git source install。这是推荐用于插件开发的选项:它会将完整的 NocoBase 源代码放在 <app-path>/source/ 下,以便构建插件,并在调试时阅读核心源代码。另外两个选项(Docker install、create-nocobase-app install)都不会提供适合插件开发的源代码树。

  • 指向现有的源代码仓库 — 如果用户已经在其他位置克隆了 NocoBase 源代码仓库,请询问其路径,并改为在该仓库中开发插件。如果用户还没有,可以克隆一个:

    git clone https://github.com/nocobase/nocobase.git -b main --depth=1 my-nocobase
    cd my-nocobase && yarn install
    

询问用户倾向于哪个选项;不要替用户做决定,并且在有可用的源代码树之前不要继续。

CLI 管理的源代码应用的命令执行目录:

除环境级命令外,以下每条命令都针对源代码树运行,因此请在 <app-path>/source/ 下执行。

命令执行目录
nb scaffold plugin<app-path>/source/
nb source dev<app-path>/source/
nb source build<app-path>/source/
nb scaffold migration<app-path>/source/
nb plugin enable/disable任意目录(环境级命令)
nb app upgrade/restart任意目录(环境级命令)

步骤 1:需求分析

分析用户的需求,并确定需要哪些扩展点:

  • 服务端:集合、自定义 REST API、ACL、定时任务、迁移、事件监听器
  • 客户端:区块(BlockModel/TableBlockModel)、字段(FieldModel)、操作(ActionModel)、设置页面、路由
  • 两者:包含服务端数据和客户端 UI 的全栈插件

不要向用户询问技术细节(例如:“你需要 BlockModel 还是 TableBlockModel?”)。请在内部将需求映射到扩展点。

步骤 2:计划确认(硬性门槛)

此步骤为必需步骤,不得跳过,无论需求看起来多么明确。 即使是看似简单直接的需求,也可能存在未说明的边缘情况、范围偏好或假设。始终先展示计划,并等待用户明确确认,再进入步骤 3。

用用户能理解的通俗语言展示功能计划。主动指出用户可能尚未考虑的决策(例如:“禁用插件后是否应保留数据?”、“是否需要设置页面来配置?”)。例如:

“这是我的计划:

  1. 创建一个设置页面,用于配置 API 密钥
  2. 添加一个每 5 分钟同步一次数据的定时任务
  3. 创建一个数据表来存储同步的记录
  4. 该表将在 UI 中作为一个区块提供

需要确认几点:

  • 禁用插件时是否应清除同步的数据?
  • 是否需要控制谁有权访问设置?

这样安排可以吗?”

在用户明确确认之前,不要运行 nb scaffold plugin,也不要编写任何代码。

步骤 3:搭建插件骨架

这两种环境都会在源代码树的 packages/plugins/ 中搭建骨架,唯一的区别是使用哪个命令来封装执行。

对于由 CLI 管理的源代码应用,请在 <app-path>/source/ 中运行:

cd <app-path>/source
nb scaffold plugin <plugin_name>
# Example: nb scaffold plugin @nocobase-sample/plugin-hello
# Creates:  <app-path>/source/packages/plugins/@nocobase-sample/plugin-hello/

nb scaffold plugin 会转发到 pm create,后者始终相对于当前工作目录生成到 packages/plugins/ 中,因此从错误的目录运行会把插件放到错误的位置。它唯一的标志是 --force-recreate。

AI Agent 提示: nb scaffold plugin 会在内部调用位于 source/node_modules/.bin/ 中的 nocobase-v1。在沙盒或非交互环境中,如果全局 nb 无法自动定位 nocobase-v1,你可能需要在运行 nb 命令前,将 source/node_modules/.bin/ 添加到 PATH:

PATH="<app-path>/source/node_modules/.bin:$PATH" nb scaffold plugin <plugin_name>

对于纯源代码仓库,请在仓库根目录运行:

yarn pm create <plugin_name>
# Creates:  packages/plugins/@nocobase-sample/plugin-hello/

请勿使用 create-plugin、generate 或任何其他变体。

搭建骨架后,启动开发模式,让代码更改自动热重载:对于由 CLI 管理的应用,在 <app-path>/source/ 中运行 nb source dev;对于纯源代码仓库,在仓库根目录运行 yarn dev。

请阅读 references/getting-started.md,了解预期的项目结构。

步骤 4:生成代码(必须先阅读参考文档)

编写任何代码之前,必须先阅读相关参考文件。 请勿通过搜索源代码、阅读示例或依赖已有知识来跳过这一步。参考文档包含项目特定的约定,这些约定优先于一般知识。

请阅读 references/index.md,找到相关参考文件,然后阅读此插件所需的文件。

强制参考文档规则

这些是必须遵守的要求,而非建议。编辑对应代码前,必须先阅读相关文件:

编辑内容必须先阅读
src/client-v2/plugin.tsxreferences/client/plugin.md
src/server/plugin.tsreferences/server/plugin.md
src/client-v2/models/ 中的任何文件references/client/block.md、references/client/field.md 或 references/client/action.md(根据适用情况选择)
src/server/collections/ 中的任何文件references/server/collection.md
关键词触发的参考文档

如果实现涉及以下任何概念,还必须阅读相应的参考文档:

代码中的关键词必须阅读
route、router、navigate、location、pathnamereferences/client/router.md 和 references/client/ctx.md
ctx.api、ctx.viewer、ctx.message、ctx.modelreferences/client/ctx.md
registerFlow、uiSchema、on: 事件处理器references/client/flow.md
resource、MultiRecordResource、SingleRecordResourcereferences/client/resource.md
为标准前端显示或编辑而持久化的筛选条件加载带有 filter 主题的 nocobase-utils,然后阅读 筛选条件格式,以及相关的客户端或服务端参考文档
tExpr、useT、this.treferences/client/i18n.md
acl.allow、权限references/server/acl.md
defineCollection、字段、关系references/server/collection.md
生成顺序

顺序灵活,可根据插件需求调整:

  • 当插件包含数据表和 API 时,优先从服务端开始。
  • 当插件纯属前端时,优先从客户端开始。
  • 当客户端和服务端紧密耦合时,交替进行。

编写客户端代码前的检查点: 查看“硬性约束”一节。切勿使用 this.app.use() 或 Providers。请改用 FlowEngine、上下文、纯 DOM 或 EventBus。

Step 5:国际化

默认行为(请勿询问):

  • 始终生成 src/locale/zh-CN.json 和 src/locale/en-US.json。
  • 创建 src/client-v2/locale.ts(脚手架不会生成此文件),并从中导入 tExpr / useT。文件内容请参阅 references/client/i18n.md。

仅在以下情况下询问是否需要添加其他语言:

  • 用户明确提到其他语言;或
  • 用户使用中文或英语以外的语言交流。

Step 6:启用并验证

对于由 CLI 管理的源代码应用:

nb plugin enable <plugin_name>

对于普通源代码仓库:

yarn pm enable <plugin_name>

启用后,说明用户应在 UI 中看到什么,以及如何测试插件。向用户引用 URL 时,始终使用 /v/ 前缀(例如 /v/admin/、/v/admin/settings/<menuKey>、/v/<custom-path>)——请参阅“硬性约束”中的“现代客户端运行于 /v/ URL 前缀下”规则。

默认行为

除非用户明确提出其他要求,否则均采用以下默认设置。请勿询问。

决策默认设置何时询问
客户端版本仅使用 client-v2。所有客户端代码均放在 src/client-v2/ 中。绝不使用 src/client/,也不从 @nocobase/client 导入从不
模型注册registerModelLoaders(延迟加载)从不
路由注册componentLoader(延迟加载)从不
设置页面注册使用 componentLoader 调用 pluginSettingsManager.addMenuItem() + addPageTabItem()从不
ACLacl.allow('*', '*', 'loggedIn')用户提到细粒度权限时
语言文件zh-CN.json + en-US.json用户提到其他语言时
addCollection(客户端)不要添加——建议改用 UI“数据源管理”仅用于演示;如有需要,使用 eventBus 模式(不要在 load() 中直接调用)
install() 种子数据不要添加用户提到预设数据或演示数据时
tExpr 导入从插件的 locale.ts 导入,不要直接从 @nocobase/flow-engine 导入从不
this.app.use()(Provider)不要使用——改用 FlowEngine 机制或纯 DOM。请参阅 client/plugin.md从不

故障排查

插件未按预期工作时:

常见问题检查清单

  1. 插件未显示在插件管理器中 → 按顺序检查:(a) 浏览器 URL 必须是 /v/admin/,不能是 /admin/...——只有现代插件管理器会通过 pm:listEnabledV2 获取并显示 v2 插件;(b) 插件已通过 nb plugin enable <name>(由 CLI 管理的应用)或 yarn pm enable <name>(普通源代码仓库)启用;(c) package.json 中包含正确的 NocoBase 元数据。
  2. 数据表未显示在区块选择器中 → 建议用户通过 NocoBase UI“数据源管理”添加数据表。如果需要在代码层注册(仅用于演示),请使用 filterTargetKey: 'id' 的 addCollection 和 eventBus 模式。请参阅 client/plugin.md。
  3. 设置页面显示空白 → 对于 client-v2,确认使用的是 componentLoader(而非 Component)。
  4. 模型未显示在菜单中 → 检查插件 load() 中的 define({ label: tExpr('...') }) 和 registerModelLoaders。
  5. load() 数据库查询失败 → load() 在数据库同步之前运行。将数据库操作移至 install() 或请求处理程序中。
  6. i18n 无法正常工作 → 首次添加语言文件后,需要重启应用。检查 tExpr 是否从 locale.ts 导入,而非从 @nocobase/flow-engine 导入。
  7. registerFlow 处理程序未触发 → 检查 on 事件名称。按钮使用 'click',初始化使用 'beforeRender'。

源代码调试

步骤 0 会确保存在源代码树,因此始终可以获取核心源代码进行调试——应阅读源代码,而不是猜测 API 的行为。

对于由 CLI 管理的 Git 源代码应用:

source/packages/core/server/src/          — Server core
source/packages/core/client-v2/src/       — Client core (v2, recommended)
source/packages/core/database/src/        — Database layer
source/packages/core/flow-engine/src/     — FlowEngine

对于普通源代码仓库:

packages/core/server/src/                 — Server core
packages/core/client-v2/src/              — Client core (v2, recommended)
packages/core/database/src/               — Database layer
packages/core/flow-engine/src/            — FlowEngine

完整示例插件

需要完整的可运行示例时,请从本地源代码树中读取示例插件:

参考资料加载表

参考资料使用时机备注
references/index.md始终在步骤 1 之后全局索引——阅读此文件以查找相关模块参考资料
references/getting-started.md步骤 3(脚手架)插件脚手架 + 项目结构
references/server/*.md插件需要服务端代码时每个服务端模块对应一个文件
references/client/*.md插件需要客户端代码时每个客户端模块对应一个文件
references/build.md用户询问构建/打包时构建与分发

安全检查

高影响操作:

  • 运行 nb scaffold plugin / yarn pm create(会在用户的项目中创建文件)
  • 运行 nb plugin enable / yarn pm enable(会修改数据库状态)
  • 修改现有插件文件(插件已存在时)

二次确认模板:

  • “我即将在 {{directory}} 中运行 {{command}}。这将{{impact}}。是否继续?”

回滚指引:

  • 如果 nb scaffold plugin 生成的脚手架有误 → 删除生成的目录并重新运行。
  • 如果启用后插件代码出现错误 → 修复代码;可以使用 nb plugin disable <name> 禁用插件。
  • 未经用户明确确认,绝不运行 nb app upgrade --force 或 yarn nocobase install -f——这些命令可能会重置或修改数据库。

验证清单

  • NocoBase 源代码树可用(source/packages/core/ 或 packages/core/),且相应的 CLI(nb 或 yarn)可用。若两者都不可用,则运行在步骤 0 停止,并向用户提供这两个选项。
  • 已检测环境类型(CLI 管理的 Git 源码应用或普通源码仓库),且脚手架/构建命令是在源代码树中运行的。
  • 已分析用户需求并确定扩展点。
  • 代码生成前,已与用户确认功能计划。
  • 插件脚手架已成功创建。
  • 所有生成的文件均遵循 NocoBase 约定(client-v2、延迟加载、locale.ts)。
  • 生成的代码中没有 this.app.use() 或 React Provider 模式(硬性约束)。
  • 已生成 zh-CN.json 和 en-US.json,其中包含所有可翻译字符串。
  • 使用 nb plugin enable(普通源码仓库则使用 yarn pm enable)启用插件时没有错误。
  • 生成的代码符合参考模板中的模式。
  • 出现问题时,已查阅常见问题清单。

最小测试场景

  1. 用户请求简单的设置页插件 → 脚手架 + 服务端 API + 客户端设置页。
  2. 用户请求自定义区块插件 → 脚手架 + BlockModel + registerFlow + i18n。
  3. 用户请求全栈 CRUD 插件 → 脚手架 + defineCollection + ACL + TableBlockModel + 自定义字段 + 自定义操作。
  4. 用户提供的需求模糊 → 触发澄清检查,并在编写代码前确认计划。
  5. 插件启用失败 → 查阅常见问题清单;如果源代码可用,则阅读源代码。
  6. 用户在 Docker 或通过 npm 安装的应用中运行此技能(没有源代码树)→ 步骤 0 在脚手架创建前停止,并提供以下选项:使用 nb init --ui + Git source install 重新创建项目,或指向现有源码仓库。

输出约定

最终回复必须包含:

  • 用户请求的内容(用户的原始需求)。
  • 创建的内容(生成的文件列表)。
  • 如何启用和测试(命令 + 预期的 UI 行为)。
  • 使用的假设/默认值。
  • 已知限制或后续步骤(如有)。

参考资料

评论

支持 Markdown