科技背景
💻 NOCOBASE DEVELOPER GUIDE

开发者指南 插件开发与深度定制

快速掌握NocoBase插件开发和深度定制能力

核心架构:深入了解NocoBase架构设计

插件开发:完整的插件开发流程

深度定制:系统级定制与扩展

🏗️ 核心架构 🔌 插件开发 🛠️ 深度定制 📝 最佳实践

🏗️ 核心架构

深入了解NocoBase的架构设计,为插件开发和定制打下基础

架构概览

NocoBase采用模块化架构设计,主要由以下几个核心部分组成:

  • 核心模块(Core):提供基础框架和核心功能,如用户认证、权限管理等
  • 插件系统(Plugin System):支持通过插件扩展功能,是NocoBase的核心特性
  • 数据库抽象层(Database Abstraction):支持多种数据库,提供统一的操作接口
  • 前端框架(Frontend):基于React的前端实现,提供可视化配置界面
  • API层(API Layer):提供RESTful API,支持前后端分离和第三方集成

插件系统

NocoBase的插件系统是其可扩展性的核心,主要特点包括:

  • 模块化设计:每个插件都是一个独立的模块,可以单独安装和卸载
  • 依赖管理:插件之间可以声明依赖关系,系统会自动处理加载顺序
  • 钩子系统:提供丰富的钩子(hooks),允许插件在特定时机执行代码
  • 配置管理:插件可以定义自己的配置项,通过系统界面进行管理
  • 前端集成:插件可以同时包含后端逻辑和前端组件,实现完整功能

架构层次

层次结构

前端应用层 React + Ant Design
API层 RESTful API
业务逻辑层 核心模块 + 插件
数据访问层 数据库抽象层
存储层 PostgreSQL / MySQL

🔌 插件开发教程

完整的插件开发流程,从创建到发布

插件开发流程

1

创建插件

使用NocoBase提供的插件脚手架创建新插件

# 在NocoBase项目根目录执行 npm run create-plugin my-plugin
2

插件结构

了解插件的基本结构和配置文件

my-plugin/ ├── package.json # 插件配置 ├── src/ │ ├── server/ # 后端代码 │ ├── client/ # 前端代码 │ └── index.ts # 插件入口 └── README.md # 插件说明
3

实现后端功能

在server目录中实现后端逻辑

// src/server/index.ts import { Plugin } from '@nocobase/server'; export class MyPlugin extends Plugin { async load() { // 注册API路由 this.app.router.get('/api/my-plugin/hello', async (ctx) => { ctx.body = { message: 'Hello from my plugin!' }; }); // 注册钩子 this.app.on('beforeLoad', async () => { // 插件加载前的逻辑 }); } } export default MyPlugin;
4

实现前端功能

在client目录中实现前端组件

// src/client/index.tsx import React from 'react'; import { Plugin } from '@nocobase/client'; export class MyPluginClient extends Plugin { async load() { // 注册前端路由 this.app.router.add('my-plugin', { path: '/my-plugin', component: () =>
My Plugin Page
}); // 注册菜单 this.app.menu.add('my-plugin', { name: 'My Plugin', icon: 'Settings', path: '/my-plugin' }); } } export default MyPluginClient;
5

配置插件

在package.json中配置插件信息

// package.json { "name": "my-plugin", "version": "1.0.0", "description": "My NocoBase plugin", "main": "lib/index.js", "nocobase": { "type": "plugin", "name": "my-plugin", "title": "My Plugin", "description": "This is my plugin", "icon": "Settings" }, "dependencies": { "@nocobase/server": "^1.0.0", "@nocobase/client": "^1.0.0" } }
6

构建和安装

构建插件并安装到NocoBase中

# 构建插件 cd my-plugin npm install npm run build # 安装到NocoBase cd .. npm install ./packages/plugins/my-plugin # 启动NocoBase npm run dev

🛠️ 深度定制

系统级定制与扩展,满足复杂业务需求

核心模块定制

修改核心功能

通过重写或扩展核心模块的方法,实现功能定制

钩子系统

使用系统提供的钩子,在特定时机执行自定义逻辑

数据库定制

扩展数据库模型,添加自定义字段和关系

前端定制

自定义组件

开发自定义前端组件,替换或扩展默认组件

主题定制

自定义系统主题,包括颜色、字体、布局等

路由定制

自定义前端路由,添加新页面和导航

定制示例

示例1:添加自定义API

// 在插件的server/index.ts中 import { Plugin } from '@nocobase/server'; export class MyPlugin extends Plugin { async load() { // 添加自定义API路由 this.app.router.get('/api/custom/hello', async (ctx) => { // 实现自定义逻辑 const { name } = ctx.query; ctx.body = { message: `Hello, ${name || 'world'}!`, timestamp: new Date().toISOString() }; }); // 添加需要认证的API this.app.router.post('/api/custom/protected', this.app.authMiddleware(), async (ctx) => { // 只有认证用户才能访问 const user = ctx.state.currentUser; ctx.body = { message: 'This is a protected API', user: { id: user.id, username: user.username } }; }); } } export default MyPlugin;

示例2:自定义前端组件

// 在插件的client/components/MyComponent.tsx中 import React from 'react'; import { Button, Card, Typography } from 'antd'; const { Title, Paragraph } = Typography; export const MyComponent: React.FC = () => { const [count, setCount] = React.useState(0); return ( Counter Current count: {count} ); }; // 在插件的client/index.tsx中注册 import { Plugin } from '@nocobase/client'; import { MyComponent } from './components/MyComponent'; export class MyPluginClient extends Plugin { async load() { // 注册组件 this.app.components.register('MyComponent', MyComponent); // 添加路由 this.app.router.add('my-plugin', { path: '/my-plugin', component: MyComponent }); } } export default MyPluginClient;

📝 最佳实践

插件开发和定制的最佳实践,确保代码质量和可维护性

开发规范

代码规范

  • 遵循ESLint和Prettier规范
  • 使用TypeScript确保类型安全
  • 编写清晰的注释和文档

插件设计

  • 单一职责原则,每个插件只做一件事
  • 提供合理的默认配置
  • 考虑插件的可测试性

性能优化

前端优化

  • 使用React.memo和useMemo优化渲染
  • 合理使用useCallback缓存函数
  • 优化组件结构,避免不必要的重渲染

后端优化

  • 使用数据库索引优化查询
  • 合理使用缓存减少数据库查询
  • 优化API响应,避免返回过多数据

常见问题

Q: 插件开发时如何调试?

A: 使用NocoBase的开发模式,运行npm run dev启动开发服务器,支持热重载。前端可以使用Chrome DevTools调试,后端可以在VS Code中设置断点调试。

Q: 如何处理插件之间的依赖关系?

A: 在插件的package.json中通过dependencies声明依赖关系,NocoBase会自动处理插件的加载顺序。也可以在插件的load方法中检查其他插件是否已加载。

Q: 插件如何访问数据库?

A: 通过this.app.db访问数据库实例,可以使用Sequelize ORM进行数据库操作。例如:const User = this.app.db.getModel('users');

Q: 如何发布插件到插件市场?

A: 首先确保插件符合发布规范,然后在NocoBase插件市场注册账号,按照指引提交插件。需要提供插件的名称、描述、版本信息和构建产物。