Skip to content

amis 开源项目解读

项目信息

  • 项目名称:amis

  • 项目描述:amis 是百度开源的前端低代码框架,通过 JSON 配置自动生成后台管理页面,拥有 237+ 组件、自研表达式引擎和完整的可视化编辑器。

  • 项目地址:https://github.com/baidu/amis

  • 官方文档:https://baidu.github.io/amis/zh-CN/docs/index

  • 核心特点

    • 670,000 行源代码
    • 237+ 个前端组件(142 UI + 95 业务)
    • 9 个 Monorepo 子包(5 层架构)
    • 86+ 个编辑器插件
    • Apache-2.0 开源许可
  • 核心模块

    • L5: amis-editor,可视化编辑器,拖拽构建页面
    • L4: amis,业务渲染,JSON → 页面
    • L3: amis-ui,基础组件,按钮/表单/表格
    • L2: amis-core,基础设施,工厂/Store/动作
    • L1: amis-formula,表达式引擎,公式/变量/过滤器

1. 项目概览

1.1 项目定位与核心价值

  • 一句话定位:amis 是一个面向前端开发者和后端开发者的低代码前端框架,通过 JSON 配置就能自动生成各种后台管理页面(CRUD、表单、图表、仪表盘等),极大减少前端开发成本,甚至可以完全不需要了解前端技术。

  • 解决的核心痛点

    1. 后台页面重复开发:企业后台管理系统存在大量重复性工作(表单、表格、列表页),传统方式需要手写大量 HTML/CSS/JS,开发效率低。amis 将页面结构抽象为 JSON 配置,实现"配置即页面"。
    2. 前端人力资源瓶颈:大量后端开发者需要做后台管理系统但不熟悉前端技术。amis 允许后端开发者通过编写 JSON 配置来生成页面,降低前端门槛。
    3. UI 一致性难以保证:企业级后台系统需要统一的 UI 风格和交互规范。amis 内置了一套完整的 UI 组件库和主题系统,保证了所有页面风格统一。
  • 目标用户群

    • 前端开发者:需要快速搭建后台管理系统的前端工程师
    • 后端开发者:不熟悉前端但需要做后台页面的后端开发者
    • 平台搭建者:需要集成低代码能力的 SaaS 平台开发者

1.2 目标场景与典型 Case

  • 场景一 — 企业后台管理系统快速搭建:HR、财务、客户管理等内部系统,只需在 JSON 中描述页面结构,框架自动渲染。

  • 场景二 — 低代码平台的核心渲染引擎:爱速搭(百度的低代码平台)使用 amis 作为底层渲染机制。

  • 场景三 — 动态表单与配置化后台:SaaS 平台需要根据客户需求动态调整页面,改 JSON 配置即可改变页面,无需重新发布。

  • 典型使用 Case(伪代码)

typescript
// 1. 定义 JSON Schema
const schema = {
  type: "page",
  title: "用户管理",
  body: {
    type: "crud",
    api: "/api/users",
    columns: [
      { name: "id", label: "ID" },
      { name: "name", label: "姓名" },
      { name: "email", label: "邮箱" }
    ]
  }
};

// 2. 调用 render 函数
amis.render(schema, {}, { fetcher: myFetcher });
// 3. amis 自动将 JSON 渲染为完整的 React 交互页面

1.3 核心技术亮点

  1. Schema 驱动渲染:页面完全由 JSON 配置描述,天然支持动态下发和实时修改
  2. 自研表达式引擎:安全沙箱执行,支持 80+ 内置公式函数,禁止 eval/Function
  3. MST 状态管理:基于 MobX State Tree 的树形状态管理系统,数据与 UI 一一对应
  4. 渲染器工厂模式:通过 @Renderer 装饰器注册自定义渲染器,支持异步加载
  5. 完整的低代码编辑器:WYSIWYG 可视化编辑,86+ 组件插件,拖拽构建页面
  6. Office 文档预览:自研 OpenXML 解析引擎,支持 xlsx/docx 在线预览

1.4 技术栈与选型对比

技术选择替代方案选择原因
前端框架React 18Vue, Angular生态最成熟,社区最大
状态管理MST (MobX State Tree)Redux, Zustand树形结构天然匹配组件树,内置 action 追踪
构建工具Vite 4 + RollupWebpack, FIS3开发体验快,从 FIS3 逐步迁移
编译器SWCBabel基于 Rust,编译速度快 20 倍
表达式引擎自研eval/Function, Formula.js安全性(沙箱),可控性(自定义函数)
样式方案SCSS + CSS HelperTailwind, CSS-in-JS兼容历史代码,工具类类似 Tailwind
MonorepoLerna + npm workspacesTurborepo, pnpm团队熟悉度,稳定可靠

1.5 项目规模

维度数据
总有效源文件~3,820
源代码总行数~670,000
TypeScript/TSX 文件1,892 (953 .ts + 939 .tsx)
SCSS 样式文件321
SVG 图标文件390
前端组件总数237+ (142 UI + 95 业务)
编辑器插件数86+
Monorepo 子包数9 (7 npm workspaces)
当前版本6.13.0
开源许可Apache-2.0

2. 整体架构设计 (Overall Architecture)

2.1 架构概述

amis 采用分层 Monorepo 架构,核心设计模式为 Schema 驱动的渲染引擎 + 渲染器工厂模式 + MST(MobX State Tree)状态管理

系统从下到上分为 5 层:

  • L1 - 表达式引擎层 (amis-formula):独立的词法分析、语法解析和表达式求值引擎,提供沙箱安全的公式计算能力
  • L2 - 核心基础设施层 (amis-core):渲染器工厂、MST Store 系统、JSON Schema 解析、动作系统、主题/国际化基础设施
  • L3 - UI 组件层 (amis-ui):142+ 基础 UI 组件(Button、Form、Table 等)、SCSS 样式系统、图标库
  • L4 - 业务渲染层 (amis):95+ 业务渲染器(CRUD、Form Renderer、Table Renderer 等),将 JSON Schema 映射到 UI 组件
  • L5 - 编辑器层 (amis-editor-core + amis-editor):可视化低代码编辑器,包括拖拽系统、属性面板、插件系统和实时预览

2.2 整体架构图

text
+===========================================================================+
|                         L5: 可视化编辑器层                                   |
|  +-------------------------+    +------------------------------+           |
|  |     amis-editor         |    |  amis-theme-editor-helper    |           |
|  |  [86+ Plugin]           |    |  [主题编辑辅助]                |           |
|  |  [Builder] [Renderer]   |    +------------------------------+           |
|  +------------+------------+                                               |
|               | (依赖)                                                     |
|  +------------v------------+                                               |
|  |   amis-editor-core       |                                              |
|  |  [DnD System]            |                                              |
|  |  [Plugin Manager 68KB]   |                                              |
|  |  [Inline Editor]         |                                              |
|  |  [Store Manager]         |                                              |
|  +-------------------------+                                               |
+=============================+=============================================+
                              | (依赖)
+=============================v=============================================+
|                    L4: 业务渲染层 (amis)                                     |
|  +-----------------------------------------------------------------------+ |
|  |  Schema.ts (Type System)   |   Renderers (95+ 业务渲染器)              | |
|  |  - SchemaFull.ts (27KB)    |   - Form/ (95+ 表单项渲染器)              | |
|  |  - SchemaMinimal.ts (25KB) |   - Table/  (旧版表格渲染器)              | |
|  |  - Schema.ts               |   - Table2/ (新版表格渲染器)              | |
|  |  - compat.ts (15KB)        |   - Action, CRUD, CRUD2, Dialog...      | |
|  +-----------------------------------------------------------------------+ |
+=============================+=============================================+
                              | (依赖)
+=============================v=============================================+
|                    L3: UI 组件层 (amis-ui)                                   |
|  +------------------+ +------------------+ +----------------------------+  |
|  | Components (142+) | | SCSS System      | | Icons (105+)              |  |
|  | - Button          | | - base/          | | Themes                    |  |
|  | - Form/Input...   | | - components/    | | Hooks                     |  |
|  | - Table           | | - helper/ (Tail- | | Utils                     |  |
|  | - Menu/Tabs/...   | |   wind-like CSS) | |                           |  |
|  +------------------+ +------------------+ +----------------------------+  |
+=============================+=============================================+
                              | (依赖)
+=============================v=============================================+
|                  L2: 核心基础设施层 (amis-core)                                |
|  +---------------------+  +---------------------+  +--------------------+  |
|  | Factory System      |  | Store System (MST)   |  | Action System      |  |
|  | - registerRenderer  |  | - RendererStore      |  | - handleAction()   |  |
|  | - resolveRenderer   |  | - ServiceStore       |  | - dispatchEvent()  |  |
|  | - @Renderer decorator| | - FormStore          |  | - ListenerAction   |  |
|  | - filterSchema      |  | - CRUDStore          |  | - ajax/dialog/...  |  |
|  +---------------------+  | - TableStore/2       |  +--------------------+  |
|                            | - ListStore          |                         |
|  +---------------------+  | - FormItemStore      |  +--------------------+  |
|  | SchemaRenderer      |  | - ModalStore         |  | Theme & Locale     |  |
|  | - 递归解析引擎       |  | - PaginationStore    |  | - themeable HOC    |  |
|  | - 可见性控制         |  | - AppStore           |  | - makeTranslator   |  |
|  | - 变量解析与过滤     |  | - ComboStore         |  | - localeable HOC    |  |
|  | - 全局事件绑定       |  | - RootStore          |  +--------------------+  |
|  +---------------------+  +---------------------+                         |
|                                                                           |
|  +---------------------+  +---------------------+  +--------------------+  |
|  | Utils (75+ files)   |  | Global Variables     |  | Scoped Context      | |
|  | - api.ts             |  | - globalVar.ts       |  | - Scoped.tsx         | |
|  | - dataMapping.ts     |  | - globalVarClient... |  | - filterTarget()    | |
|  | - tpl.ts (模板引擎)  |  |                      |  | - IScopedContext    | |
|  | - helper.ts          |  |                      |  | - StatusScoped      | |
|  +---------------------+  +---------------------+  +--------------------+  |
+=============================+=============================================+
                              | (依赖)
+=============================v=============================================+
|                  L1: 表达式引擎层 (amis-formula)                              |
|  +------------------+  +------------------+  +----------------------------+ |
|  | Lexer (词法分析) |  | Parser (语法解析)|  | Evaluator (求值器)         | |
|  | - 词法 token 化   |  | - AST 构建       |  | - Evaluator (同步)         | |
|  | - 运算符/变量识别 |  | - 运算符优先级   |  | - AsyncEvaluator (异步)    | |
|  |                    |  | - 公式/函数语法  |  | - 沙箱安全执行             | |
|  +------------------+  +------------------+  | - 上下文注入               | |
|                                               +----------------------------+ |
|  +------------------+  +------------------+  +----------------------------+ |
|  | Filter System    |  | Function System  |  | Doc System                 | |
|  | - registerFilter |  | - registerFunc   |  | - doc.ts (58KB 函数文档)   | |
|  | - extendsFilters |  | - functionDocs   |  | - doc.md (30KB 文档)       | |
|  +------------------+  +------------------+  +----------------------------+ |
+=============================================================================+

2.3 目录结构

标签数量主要分布
【核心基建】主导amis-core, amis-formula, amis-editor-core, factory, store, SchemaRenderer 等
【业务模块】大量amis 渲染器, amis-editor 插件, office-viewer
【UI 视图】大量amis-ui 组件/样式/图标, scss 系统
【工具集】较多utils/, scripts/, mock/, types/
【配置】较多根配置文件, docs/, examples/, locale/
【质量保证】适量各包的 tests/
【废弃】1fis-conf.js (FIS3, 已迁移到 Vite)
shell
amis/
├── packages/                          # 【核心基建】Monorepo 包目录(npm workspaces)

   ├── amis-formula/                  # 【核心基建】L1: 表达式引擎(词法→语法→求值)
   └── src/
       ├── lexer.ts              # 【核心基建】词法分析器:字符串 → Token 流
       ├── parser.ts             # 【核心基建】语法解析器:Token 流 → AST
       ├── evalutor.ts           # 【核心基建】同步表达式求值器(79KB,核心引擎)
       ├── evalutorForAsync.ts   # 【核心基建】异步表达式求值器
       ├── filter.ts             # 【核心基建】过滤器注册系统
       ├── function.ts           # 【核心基建】公式函数注册系统
       ├── doc.ts                # 【核心基建】公式函数文档词典(58KB)
       ├── doc.md                # 【配置】公式文档(30KB)
       ├── index.ts              # 【核心基建】包入口(导出 evaluate/parse/lexer)
       └── types.ts              # 【核心基建】引擎类型定义

   ├── amis-core/                     # 【核心基建】L2: 核心基础设施层
   └── src/
       ├── index.tsx             # 【核心基建】包入口(导出所有核心 API + render 函数)
       ├── factory.tsx           # 【核心基建】渲染器工厂(register/resolve/filter)
       ├── SchemaRenderer.tsx    # 【核心基建】递归 Schema 解析渲染引擎
       ├── Root.tsx              # 【核心基建】根组件(ScopedRootRenderer)
       ├── RootRenderer.tsx      # 【核心基建】根渲染器(数据初始化 + 动作处理中枢)
       ├── Scoped.tsx            # 【核心基建】数据作用域组件
       ├── WithStore.tsx         # 【核心基建】MST Store 注入 HOC
       ├── schema.ts             # 【核心基建】JSON Schema 类型定义(33KB)
       ├── types.ts              # 【核心基建】核心 TypeScript 类型
       ├── theme.tsx             # 【核心基建】主题系统(themeable HOC)
       ├── locale.tsx            # 【核心基建】国际化系统
       ├── env.tsx               # 【核心基建】RendererEnv 环境定义
       ├── globalVar.ts          # 【核心基建】全局变量系统
       ├── store/                # 【核心基建】MST Store 状态管理系统
   ├── index.ts          # 【核心基建】Store 导出入口
   ├── root.ts           # 【核心基建】RootStore(页面根 Store)
   ├── service.ts        # 【核心基建】ServiceStore(API 数据加载)
   ├── form.ts           # 【核心基建】FormStore(表单状态管理)
   ├── formItem.ts       # 【核心基建】FormItemStore(表单项状态)
   ├── crud.ts           # 【核心基建】CRUDStore(列表增删改查)
   ├── table.ts          # 【核心基建】TableStore(旧版表格)
   ├── table2.ts         # 【核心基建】TableStore2(新版表格)
   ├── list.ts           # 【核心基建】ListStore(简单列表)
   ├── combo.ts          # 【核心基建】ComboStore(组合表单)
   ├── modal.ts          # 【核心基建】ModalStore(弹窗状态)
   ├── pagination.ts     # 【核心基建】PaginationStore(分页)
   ├── app.ts            # 【核心基建】AppStore(应用级状态)
   └── manager.ts        # 【核心基建】Store 管理器(全局注册表)
       ├── utils/                # 【工具集】核心工具函数库(75+ 文件)
   ├── api.ts            # 【工具集】API 请求封装 + 适配器
   ├── tpl.ts            # 【工具集】模板引擎(filter/表达式解析)
   ├── helper.ts         # 【工具集】通用辅助函数
   ├── dataMapping.ts    # 【工具集】数据映射转换
   ├── formula.ts        # 【工具集】表达式工具(桥接 amis-formula)
   ├── renderer-event.ts # 【工具集】渲染器事件系统
   ├── animation.ts      # 【工具集】动画工具
   └── ...               # 70+ 文件
       ├── actions/              # 【核心基建】动作系统(事件行为定义)
       ├── renderers/            # 【核心基建】基础渲染器(Form/Item/Options/Placeholder)
       ├── components/           # 【核心基建】核心基础组件(LazyComponent/Overlay/ErrorBoundary)
       └── hooks/                # 【核心基建】React Hooks(useEnvContext 等)

   ├── amis-ui/                       # 【UI 视图】L3: 基础 UI 组件库
   ├── src/
   ├── components/           # 【UI 视图】142+ 基础 UI 组件
   ├── calendar/         # 【UI 视图】日历组件
   ├── condition-builder/# 【UI 视图】条件构建器
   ├── formula/          # 【UI 视图】公式编辑器组件
   ├── json-schema/      # 【UI 视图】JSON Schema 编辑器
   ├── menu/             # 【UI 视图】菜单组件
   ├── schema-editor/    # 【UI 视图】Schema 编辑器
   ├── table/            # 【UI 视图】表格视图组件
   └── virtual-list/     # 【UI 视图】虚拟列表
   ├── hooks/                # 【UI 视图】React Hooks
   ├── icons/                # 【UI 视图】图标组件库(105+)
   ├── themes/               # 【UI 视图】主题组件(antd/cxd/default)
   ├── locale/               # 【配置】国际化语言包
   └── utils/                # 【工具集】UI 工具函数
   └── scss/                     # 【UI 视图】SCSS 样式系统
       ├── base/                 # 【UI 视图】基础样式
       ├── components/           # 【UI 视图】组件样式
       ├── helper/               # 【UI 视图】辅助工具类(类似 Tailwind CSS)
   ├── background/       # 【UI 视图】背景工具类
   ├── border/           # 【UI 视图】边框工具类
   ├── flex/             # 【UI 视图】Flexbox 工具类
   ├── grid/             # 【UI 视图】Grid 工具类
   ├── spacing/          # 【UI 视图】间距工具类
   └── typography/       # 【UI 视图】排版工具类
       ├── layout/               # 【UI 视图】布局样式
       └── themes/               # 【UI 视图】主题样式

   ├── amis/                          # 【核心基建】L4: 业务渲染层(JSON → 页面)
   ├── src/
   ├── index.tsx             # 【核心基建】包入口(导出所有业务渲染器 + Schema)
   ├── Schema.ts             # 【核心基建】主 Schema 类型
   ├── SchemaFull.ts         # 【核心基建】完整 Schema(27KB,全量类型定义)
   ├── SchemaMinimal.ts      # 【核心基建】最小 Schema(25KB,精简版)
   ├── minimal.ts            # 【核心基建】最小化入口注册(23KB)
   ├── compat.ts             # 【核心基建】向后兼容层(15KB)
   ├── schemaExtend.ts       # 【核心基建】Schema 扩展工具
   ├── preset.tsx            # 【核心基建】预设配置
   ├── types.ts              # 【核心基建】类型导出
   └── renderers/            # 【业务模块】业务渲染器
       ├── Form/             # 【业务模块】表单渲染器(95+ 表单项)
       ├── Table/            # 【业务模块】旧版表格渲染器
       ├── Table2/           # 【业务模块】新版表格渲染器
       └── icons/            # 【UI 视图】渲染器专用图标
   └── __tests__/                # 【质量保证】主包测试用例(大量快照测试)

   ├── amis-editor-core/             # 【核心基建】L5: 可视化编辑器核心基础设施
   └── src/
       ├── index.ts              # 【核心基建】包入口
       ├── manager.ts            # 【核心基建】插件管理器(68KB,核心)
       ├── plugin.ts             # 【核心基建】插件类型定义(40KB)
       ├── inlineEdit.ts         # 【核心基建】内联编辑组件(8KB)
       ├── deepSplice.ts         # 【核心基建】深层数组操作工具
       ├── util.ts               # 【工具集】编辑器工具函数(53KB)
       ├── variable.ts           # 【核心基建】变量系统
       ├── component/            # 【核心基建】编辑器基础组件(Panel/base)
       ├── dnd/                  # 【核心基建】拖拽系统(Drag & Drop)
       ├── icons/                # 【UI 视图】编辑器图标
       ├── layout/               # 【核心基建】编辑器布局组件
       ├── locale/               # 【配置】编辑器国际化
       ├── plugin/               # 【核心基建】编辑器插件基础框架
       └── store/                # 【核心基建】编辑器 Store 管理

   ├── amis-editor/                  # 【业务模块】L5: 可视化编辑器 UI
   └── src/
       ├── index.tsx             # 【核心基建】包入口
       ├── builder/              # 【核心基建】页面构建器
       ├── component/            # 【核心基建】编辑器主组件
       ├── icons/                # 【UI 视图】编辑器功能图标
   ├── btn/              # 【UI 视图】按钮分类图标
   ├── form/             # 【UI 视图】表单分类图标
   ├── layout/           # 【UI 视图】布局分类图标
   ├── display/          # 【UI 视图】展示分类图标
   └── ...               # 更多分类
       ├── locale/               # 【配置】编辑器语言包
       ├── plugin/               # 【业务模块】86+ 组件编辑插件
   ├── CRUD2/            # 【业务模块】CRUD2 组件插件
   ├── Form/             # 【业务模块】表单组件插件
   ├── Layout/           # 【业务模块】布局组件插件
   └── Others/           # 【业务模块】其他组件插件
       ├── renderer/             # 【核心基建】编辑器渲染器控件(45+)
   ├── FormulaControl.tsx       # 【核心基建】公式编辑器控件
   ├── DataBindingControl.tsx   # 【核心基建】数据绑定控件
   ├── APIControl.tsx           # 【核心基建】API 配置控件
   ├── ColumnControl.tsx        # 【核心基建】列配置控件
   └── ...                      # 40+ 控件
       ├── tpl/                  # 【核心基建】编辑器模板系统
       ├── util.ts               # 【工具集】编辑器工具函数
       └── validator.tsx         # 【核心基建】编辑器校验系统

   ├── amis-theme-editor-helper/     # 【工具集】主题编辑器辅助工具
   └── src/
       ├── helper/               # 【工具集】辅助函数
       ├── systemTheme/          # 【工具集】系统主题定义(component.ts 6158行)
       ├── renderers/            # 【工具集】渲染器
       ├── style/                # 【UI 视图】样式
       └── locale/               # 【配置】国际化

   ├── office-viewer/                # 【业务模块】Office 文档在线预览
   └── src/
       ├── common/               # 【工具集】通用工具
       ├── excel/                # 【业务模块】Excel 预览引擎
   ├── data/             # 【业务模块】数据处理
   ├── edit/             # 【业务模块】编辑功能
   ├── formula/          # 【业务模块】公式计算
   ├── io/excel/         # 【业务模块】Excel 文件读取与渲染
   ├── render/           # 【业务模块】渲染引擎
   ├── sheet/            # 【业务模块】工作表管理
   └── types/            # 【业务模块】Excel 类型定义
       ├── openxml/              # 【核心基建】OpenXML 解析引擎
   ├── drawing/          # 【核心基建】图形/绘图解析(presetShape.ts 38,785行)
   ├── math/             # 【核心基建】数学公式解析
   └── word/             # 【核心基建】Word 文档解析
       ├── word/                 # 【业务模块】Word 预览引擎
   ├── parse/            # 【业务模块】Word 解析
   └── render/           # 【业务模块】Word 渲染
       ├── package/              # 【业务模块】Office 文件解包/打包
       ├── util/                 # 【工具集】工具函数
       └── tools/                # 【工具集】辅助工具(XSD 解析等)

   └── vite-plugin-amisr/            # 【工具集】Vite 插件
       └── src/                      # 【工具集】JSON → React 组件热重载插件

├── docs/                             # 【配置】项目文档(中文)
├── examples/                         # 【配置】示例代码和演示页面
├── mock/                             # 【工具集】Mock 数据(开发调试用)
├── scripts/                          # 【工具集】构建、发布与自动化脚本
├── types/                            # 【工具集】TypeScript 类型声明补丁
├── reports/                          # 【配置】项目分析报告
├── package.json                      # 【配置】Monorepo 根配置
├── fis-conf.js                       # 【废弃】FIS3 构建配置(29KB,已被 Vite 替代)
├── vite.config.ts                    # 【配置】Vite 构建配置
└── README.md                         # 【配置】项目说明(中文)

3. 模块依赖与调用关系

3.1 全局入口与核心路由

  • 逻辑说明:用户调用 amis.render(schema, props, options) 启动整个渲染流程。入口函数创建 MST Store 实例,初始化环境上下文(env),然后通过 ScopedRootRenderer → RootRenderer 开始递归渲染。在渲染过程中,SchemaRenderer 根据 Schema 中每个节点的 type 字段,通过渲染器工厂(factory)查找对应的渲染器组件,并递归处理每个节点的 bodychildrencolumns 等嵌套属性。

调用拓扑 (plainText)

text
amis.render(schema, props, options)  [packages/amis-core/src/index.tsx]
 |
 +-- AMISSchema (入口组件)
      |
      +-- RendererStore.create({}, options)  [MST Store 初始化]
      |    |
      |    +-- getEnv(store)  [环境变量注入]
      |    |    +-- fetcher (API 请求)
      |    |    +-- notify (消息通知)
      |    |    +-- jumpTo (页面跳转)
      |    |    +-- isCancel (请求取消)
      |    |
      |    +-- envOverwrite(schema, locale, platform)  [环境覆盖]
      |
      +-- ScopedRootRenderer  [packages/amis-core/src/Root.tsx]
           |
           +-- RootRenderer  [packages/amis-core/src/RootRenderer.tsx]
                |
                +-- store.addStore(RootStore)  [创建根 Store 节点]
                |
                +-- render(pathPrefix, schema, props)  [核心渲染入口]
                     |
                     +-- SchemaRenderer  [packages/amis-core/src/SchemaRenderer.tsx]
                          |
                          +-- resolveRenderer(path, schema)  [渲染器查找]
                          |    |
                          |    +-- renderersTypeMap[type]  [按 type 直接匹配]
                          |    +-- renderers[].test(path)  [按路径正则匹配]
                          |
                          +-- renderer.component (实际组件)
                               |
                               +-- [递归处理 body/children/columns 等嵌套属性]
                               |
                               +-- 叶子节点 -> amis-ui 基础组件

3.2 核心业务实体与关联

  • 实体定义
实体描述对应 Store
Schema (JSON 配置)页面的完整 JSON 描述,包含类型、数据、样式、事件等无(纯数据)
RendererStore全局渲染器 Store,管理所有子 StoreRendererStore
RootStore页面根 Store,管理页面级数据、路由、弹窗RootStore
ServiceStore服务 Store,管理 API 数据获取与缓存ServiceStore
FormStore表单 Store,管理表单数据、校验、提交FormStore
CRUDStore列表 Store,管理分页列表数据增删改查CRUDStore
TableStore/TableStore2表格 Store,管理表格数据、列、行操作TableStore/TableStore2
FormItemStore表单项 Store,管理单个表单项的值、校验FormItemStore
ListStore列表 Store,管理简单列表数据ListStore
ModalStore弹窗 Store,管理全局弹窗状态ModalStore
ComboStore组合 Store,管理多层级嵌套表单组合ComboStore
PaginationStore分页 Store,管理分页状态PaginationStore
AppStore应用 Store,管理应用级设置AppStore
ActionObject动作对象,描述一个操作(ajax、dialog、link、reload 等)无(运行时创建)
  • 实体引用拓扑 (plainText)
text
[RendererStore] 1 ----> N [StoreNode (MST)]
     |
     +---- 1 ----> 0..1 [RootStore]  (页面根节点)
     |                    |
     |                    +---- 1 ----> N [ServiceStore]  (API 服务)
     |                    +---- 1 ----> N [CRUDStore]     (列表 CRUD)
     |                    +---- 1 ----> N [FormStore]     (表单)
     |                    |               |
     |                    |               +---- 1 ----> N [FormItemStore] (表单项)
     |                    |               +---- 1 ----> N [ComboStore]    (组合)
     |                    |
     |                    +---- 1 ----> N [TableStore / TableStore2]  (表格)
     |                    +---- 1 ----> N [ListStore]                (列表)
     |                    +---- 1 ----> 1 [ModalStore]               (弹窗)
     |                    +---- 1 ----> 1 [PaginationStore]          (分页)

[Schema] (JSON) -----> [SchemaRenderer] (递归解析引擎)
     |                       |
     |                       +----> [Factory] (渲染器注册与查找)
     |                       |          |
     |                       |          +----> [Renderers] (渲染器注册表)
     |                       |                    |
     |                       |                    +---- [amis 业务渲染器]
     |                       |                    +---- [amis-ui 基础组件]
     |                       |                    +---- [自定义渲染器]
     |                       |
     |                       +----> [Store System] (数据管理)
     |                       +----> [Action System] (事件处理)
     |                       +----> [Expression Engine] (amis-formula)

4. 核心模块详解

模块一:渲染器工厂系统 (Factory System)

  • 模块名称:Renderer Factory — 渲染器注册、查找、异步加载、Schema 过滤的完整管线

  • 设计说明:工厂系统是 amis 的心脏,实现了一个策略模式 + 装饰器模式的组件注册与分发机制。开发者通过 @Renderer(config) 装饰器注册渲染器,工厂按权重(weight)排序存储。在渲染时,通过 resolveRenderer(path, schema) 按 type 或路径正则匹配查找对应渲染器。系统支持同步/异步渲染器加载、Schema 过滤器链、渲染器别名、MST Store 注入和 Scope 隔离。

  • 内部结构图 (plainText)

text
+-----------------------------+
|     registerRenderer()      |  <-- @Renderer 装饰器调用
|  - 校验 type/test           |
|  - 权重排序插入              |
|  - 别名注册                  |
|  - 组件 HOC 包装             |
|     +--> HocStoreFactory     |  <-- 自动注入 MST Store
|     +--> Scoped(component)   |  <-- 隔离数据作用域
+-------------+---------------+
              |
              v
+-----------------------------+
|    renderers[] (注册表)      |
|  +------------------------+ |
|  | weight: 0  (最高优先级) | |
|  | weight: 10              | |
|  | weight: 100 (最低优先级)| |
|  +------------------------+ |
|  renderersTypeMap: {        |
|    "page": RendererConfig,  |
|    "form": RendererConfig,  |
|    "crud": RendererConfig,  |
|    ...                      |
|  }                          |
+-------------+---------------+
              |
              v
+-----------------------------+
|     resolveRenderer()       |  <-- SchemaRenderer 调用
|  1. renderersTypeMap[type]  |  <-- 优先按 type 精确匹配
|  2. cache[path]             |  <-- 路径匹配缓存
|  3. renderers[].test(path)  |  <-- 正则/函数匹配
|  4. 返回 RendererConfig     |
+-------------+---------------+
              |
              v
+-----------------------------+
|    renderer.component        |  <-- 已包装好 Store/Scope 的组件
|  +------------------------+ |
|  | React Component        | |
|  | + store prop (MST)     | |
|  | + data prop            | |
|  | + dispatchEvent()      | |
|  | + render() recursion   | |
|  +------------------------+ |
+-----------------------------+

模块二:MST Store 状态管理系统

  • 模块名称:MST Store System — 基于 MobX State Tree 的分层状态管理

  • 设计说明:amis 使用 MST 构建了一个树形 Store 系统。每个页面组件对应一个 Store 节点,形成与 UI 组件树一一对应的 Store 树。数据从上往下流动(parentStore → childStore),事件从下往上冒泡(子组件 → 父组件)。Store 系统管理数据加载(ServiceStore)、表单状态(FormStore)、列表操作(CRUDStore)、表格渲染(TableStore)等场景。

  • 内部结构图 (plainText)

text
+-----------------------------+
|     RendererStore (全局)     |  1 个 per session
|  - fetcher                  |
|  - notify                   |
|  - isCancel                 |
|  - addStore()               |
|  - removeStore()            |
+-------------+---------------+
              |
              v  addStore(RootStore)
+-----------------------------+
|       RootStore (根)         |  1 个 per page
|  - data (页面数据)           |
|  - context (上下文)          |
|  - location/params (路由)    |
|  - globalVars (全局变量)     |
|  - dialogSchema (弹窗)      |
|  - drawerSchema (抽屉)      |
+-----+--------+------+------+
      |        |      |
      v        v      v
+--------+ +-------+ +--------+
|Service | |Form   | |CRUD    |
|Store   | |Store  | |Store   |
|(API)   | |(表单)  | |(列表)  |
+--------+ +---+---+ +--------+
              |   |
              v   v
         +--------+  +--------+
         |FormItem|  |Combo   |
         |Store   |  |Store   |
         +--------+  +--------+

数据流动规则:
  - parentStore.data 自动传递给 childStore (downStream)
  - 子组件通过 scope 向上查找数据
  - ServiceStore 加载的数据自动合并到父级 Store
  - FormStore 的数据变更通过 MST action 保证可追踪

模块三:动作与事件系统 (Action System)

  • 模块名称:Action System — 统一的事件处理与动作分派系统

  • 设计说明:amis 定义了一套完整的动作语义(actionType),包括 reloadajaxdialogdrawerurllinkemailcopytoastsaveAs 等。所有用户交互(按钮点击、表单提交、行操作)都通过 dispatchEvent 转换为标准化的 RendererEvent,事件携带数据和上下文在组件树中传递。RootRenderer 的 handleAction 方法是所有动作的中央处理枢纽。

  • 内部结构图 (plainText)

text
用户交互 (点击/提交/选择)
        |
        v
+----------------------------+
|   dispatchEvent(e, data)   |  <-- 每个组件可调用
|   创建 RendererEvent        |
+-------------+--------------+
              |
              v
+----------------------------+
|   RootRenderer.handleAction |  <-- 中央处理枢纽
|                             |
|  switch(action.actionType) { |
|    case 'reload':           |
|      scoped.reload(target)  |
|    case 'ajax':             |
|      store.saveRemote(api)  |
|    case 'dialog':           |
|      store.openDialog(...)  |
|    case 'drawer':           |
|      store.openDrawer(...)  |
|    case 'url'/'link':       |
|      env.jumpTo(url)        |
|    case 'toast':            |
|      env.notify(level, msg) |
|    case 'copy':             |
|      env.copy(content)      |
|    case 'email':            |
|      window.open(mailto)    |
|    case 'saveAs':           |
|      saveAs(api.url)        |
|  }                          |
+-----------------------------+

模块四:表达式引擎 (amis-formula)

  • 模块名称:Formula Engine — 自研表达式/公式解析与求值引擎

  • 设计说明:amis-formula 实现了一个完整的表达式引擎,包含词法分析器(Lexer)、语法解析器(Parser)、同步求值器(Evaluator)和异步求值器(AsyncEvaluator)。引擎按流程 token 化输入字符串 → 构建 AST → 在沙箱环境中求值,支持 80+ 内置公式函数(数学、字符串、日期、数组等)。核心设计是安全沙箱:禁用 Function constructor 和 eval,通过 AST 解释执行。

  • 内部结构图 (plainText)

text
输入: "${name} 今年 ${age} 岁,成绩 ${IF(score>60, '及格', '不及格')}"
        |
        v
+----------------------------+
|  Lexer (词法分析器)          |
|  - 扫描字符流               |
|  - 识别 Token:              |
|    ${ ... }  (模板变量)     |
|    IF(...)   (函数调用)     |
|    >  (运算符)              |
|    name, age, score (变量)  |
|    '及格' (字符串字面量)    |
|  - 输出 Token 流            |
+-------------+--------------+
              |
              v
+----------------------------+
|  Parser (语法解析器)         |
|  - 递归下降解析             |
|  - 运算符优先级处理         |
|  - 构建 AST:                |
|    TemplateLiteral          |
|    +-- Identifier(name)    |
|    +-- Identifier(age)     |
|    +-- CallExpression(IF)  |
|        +-- BinaryOp(>)     |
|        |   +-- score       |
|        |   +-- 60          |
|        +-- '及格'           |
|        +-- '不及格'         |
+-------------+--------------+
              |
              v
+----------------------------+
|  Evaluator (求值器)          |
|  - 遍历 AST 节点            |
|  - 从 data 上下文取变量     |
|  - 执行函数调用 (沙箱)      |
|  - 返回求值结果:            |
|    "张三 今年 18 岁,成绩 及格" |
+----------------------------+

模块五:可视化编辑器系统 (Editor System)

  • 模块名称:amis-editor — WYSIWYG 低代码编辑器

  • 设计说明:编辑器分为两层:amis-editor-core 提供编辑器基础设施(插件管理器 PluginManager 68KB、拖拽系统 DnD、内联编辑 InlineEdit、Store),amis-editor 提供可视化编辑功能(86+ 组件插件、属性面板渲染器、页面构建器)。编辑器的工作原理是"操作 Schema → 预览渲染",用户拖拽组件到画布,编辑器修改 JSON Schema,amis 渲染引擎实时呈现结果。

  • 内部结构图 (plainText)

text
+===========================================================+
|                    amis-editor (编辑器 UI)                    |
|  +---------------------+  +-----------------------------+  |
|  | Component Plugins   |  | Renderer Controls (45+)     |  |
|  | (86+ 组件编辑插件)   |  | - FormulaControl            |  |
|  | - Form/ (表单插件)   |  | - DataBindingControl       |  |
|  | - CRUD2/ (CRUD2)    |  | - APIControl               |  |
|  | - Layout/ (布局)     |  | - ColumnControl            |  |
|  | - Others/ (其他)     |  | - StatusControl            |  |
|  +---------------------+  +-----------------------------+  |
|  |       Builder        |  |    Validator System        |  |
|  +---------------------+  +-----------------------------+  |
+==========================+=================================+
                           | (依赖)
+==========================v=================================+
|               amis-editor-core (编辑器核心)                   |
|  +-----------------------+  +----------------------------+  |
|  | PluginManager (68KB)  |  | DnD System                 |  |
|  | - registerPlugin()    |  | - Drag & Drop 引擎          |  |
|  | - resolvePlugin()     |  | - 排序/移动                 |  |
|  | - plugin lifecycle    |  +----------------------------+  |
|  +-----------------------+  +----------------------------+  |
|  | InlineEdit (8KB)      |  | Editor Store               |  |
|  | - 内联编辑组件          |  | - editor state management  |  |
|  +-----------------------+  +----------------------------+  |
+============================================================+
                           | (依赖)
+==========================v=================================+
|                  amis (渲染引擎 - 实时预览)                   |
+============================================================+

5. 关键数据流程

场景说明

  • 场景一:用户请求渲染一个页面 — 从 amis.render(schema) 调用开始,经过环境初始化、Store 创建、Schema 覆盖、递归渲染,最终返回 React 组件树的完整流程。

  • 流转时序图 (Mermaid)

场景说明

  • 场景二:用户交互触发动作 — 从按钮点击、表单提交等用户操作,触发动作(如 reload、ajax、dialog),到最终 UI 更新的完整流程。

  • 流转时序图 (Mermaid)

6. 接口与契约规范

6.1 渲染器注册契约 (TypeScript)

typescript
/**
 * 渲染器基础配置契约
 * 通过 @Renderer(config) 装饰器注册渲染器时的配置接口
 */
export interface RendererBasicConfig {
  /** 路径匹配正则表达式(用于识别 Schema type 或路径模式) */
  test?: RegExp | TestFunc;
  /** 渲染器类型标识(如 'page', 'form', 'crud') */
  type?: string;
  /** 别名列表,可绑定多个 type */
  alias?: Array<string>;
  /** 注册名称(用于 debug 和查找) */
  name?: string;
  /** 关联的 MST Store 类型,如 'FormStore', 'CRUDStore' */
  storeType?: string;
  /** 是否需要继承上层数据域 */
  storeExtendsData?: boolean | ((props: any) => boolean);
  /** 权重,值越低越优先命中(默认 0) */
  weight?: number;
  /** 是否隔离数据作用域 */
  isolateScope?: boolean;
  /** 是否为表单项 */
  isFormItem?: boolean;
  /** 是否覆盖已注册的渲染器 */
  override?: boolean;
  /** 全局变量变化时的回调 */
  onGlobalVarChanged?: (instance: React.Component, schema: any, data: any) => void | boolean;
}

/**
 * 完整的渲染器配置(含组件引用)
 */
export interface RendererConfig extends RendererBasicConfig {
  /** 已包装 Store/Scope 的 React 组件 */
  component?: React.ComponentType<RendererProps>;
  /** 原始(未包装)的 React 组件 */
  Renderer?: React.ComponentType<RendererProps>;
  /** 异步加载渲染器的工厂函数 */
  getComponent?: () => Promise<{default: React.ComponentType<RendererProps>} | any>;
}

/**
 * 渲染器组件接收的 Props 契约
 */
export interface RendererProps extends ThemeProps, LocaleProps, OnEventProps, StatusScopedProps {
  /** 递归渲染函数:将子 Schema 渲染为组件 */
  render: (region: string, node: SchemaNode, props?: PlainObject) => JSX.Element;
  /** 运行环境对象(fetcher, notify, jumpTo 等) */
  env: RendererEnv;
  /** 当前节点路径(如 'page/body/0/body/0') */
  $path: string;
  /** 原始 JSON Schema 配置 */
  $schema: any;
  /** 当前节点的 MST Store 实例 */
  store?: IIRendererStore;
  /** 当前节点的数据上下文 */
  data: { [propName: string]: any };
  /** 事件分发函数 */
  dispatchEvent: (e: string | React.MouseEvent, data: any, renderer?: React.Component, scoped?: IScopedContext) => Promise<RendererEvent>;
  /** 全局事件广播回调 */
  onBroadcast?: (type: string, rawEvent: RendererEvent, ctx: any) => any;
  /** 是否启用移动端原生 UI 模式 */
  mobileUI?: boolean;
}

6.2 环境接口契约 (TypeScript)

typescript
/**
 * amis 运行时环境契约
 * 使用方必须实现此接口来集成 amis
 */
export interface RendererEnv {
  /** 请求发送器:amis 所有 API 请求通过此方法发送 */
  fetcher: (config: FetcherConfig) => Promise<fetcherResult>;

  /** WebSocket 数据接收器 */
  wsFetcher?: (ws: WsObject, onMessage: (data: any) => void, onError: (error: any) => void) => {close: () => void};

  /** 请求是否可以取消(配合 useCancel 使用) */
  isCancel: (value: any) => boolean;

  /** 消息通知方法 */
  notify: (type: 'info' | 'success' | 'error' | 'warning', msg: string, conf?: any) => void;

  /** URL 跳转方法(amis 所有页面跳转均通过此方法) */
  jumpTo: (to: string, action?: any, ctx?: any) => void;

  /** 判断当前路由是否活跃 */
  isCurrentUrl?: (to: string) => boolean;

  /** URL 更新方法(SPA 模式下的路由更新) */
  updateLocation?: (location: any, replace?: boolean) => void;

  /** 剪贴板复制方法 */
  copy?: (contents: string, options?: any) => void;

  /** 用户行为埋点追踪 */
  tracker?: (eventTrack: EventTrack, props: any) => void;

  /** 主题对象 */
  theme?: any;

  /** HTML 过滤方法(可用于 XSS 防护) */
  filterHtml?: (input: string) => string;

  /** 是否为移动端 */
  isMobile?: () => boolean;

  /** 页面 ID 获取方法 */
  getPageId?: () => string;

  /** JSON 配置中的文本替换方法 */
  replaceText?: {[propName: string]: string};

  /** 文本替换时忽略的 key */
  replaceTextIgnoreKeys?: Array<string>;

  /** 渲染器自定义查找方法 */
  rendererResolver?: (path: string, schema: Schema) => null | RendererConfig;

  /** 页面 meta 信息更新回调 */
  pageMetaEffect?: (meta: AMISPageMeta) => void;

  /** URL 解析方法 */
  parseLocation?: () => { pathname: string; query: Record<string, string> };
}

6.3 MST Store 契约 (TypeScript)

typescript
/**
 * MST Store 节点基础契约
 * 所有 Store 类型都遵循此基础接口
 */
export interface IIRendererStore {
  /** Store 唯一 ID */
  id: string;
  /** Store 类型标识(如 'FormStore', 'CRUDStore') */
  storeType: string;
  /** 当前节点的路径 */
  path: string;
  /** 父 Store 的 ID */
  parentId: string;
  /** 数据域:包含了所有上层 Store 合并后的数据 */
  data: Record<string, any>;
  /** 下游合并数据(data + 当前层数据) */
  downStream: Record<string, any>;
  /** 是否有子 Store */
  hasChildren: boolean;
  /** 上下文数据(在弹窗/抽屉中也能继承) */
  context: Record<string, any>;
  /** 获取子 Store */
  getChildById(id: string): IIRendererStore | null;
  /** 获取所有子 Store */
  getChildren(): Array<IIRendererStore>;
}

/**
 * ServiceStore — API 数据服务契约
 */
export interface IServiceStore extends IStoreNode {
  /** 加载状态 */
  loading: boolean;
  /** 错误信息 */
  error?: string;
  /** 消息文本 */
  msg?: string;
  /** 获取 API 配置 */
  getApi: (api?: Api, ctx?: any) => ApiObject | undefined;
  /** 初始化数据加载 */
  initLoading: () => Promise<void>;
  /** 发送异步请求 */
  fetchData: (api: Api, ctx?: any) => Promise<any>;
  /** 重新加载 */
  reload: (subpath?: string, ctx?: any) => Promise<void>;
}

/**
 * FormStore — 表单状态管理契约
 */
export interface IFormStore extends IStoreNode {
  /** 当前表单值 */
  values: Record<string, any>;
  /** 表单错误信息 */
  errors: Record<string, string>;
  /** 是否正在提交 */
  submitting: boolean;
  /** 是否已触摸 */
  touched: boolean;
  /** 设置表单值 */
  setValues: (values: Record<string, any>) => void;
  /** 表单提交 */
  submit: () => Promise<any>;
  /** 表单校验 */
  validate: () => Promise<boolean>;
  /** 表单重置 */
  reset: () => void;
}

7. 快速开始

7.1 环境要求

  • Node.js 12/14/16/18
  • npm 7+(需支持 workspaces)

7.2 安装与运行

bash
# 安装项目依赖
npm i --legacy-peer-deps

# 启动开发服务器
npm start
# 访问 http://127.0.0.1:8888/examples/pages/simple

# 开发编辑器
# 访问 http://127.0.0.1:8888/packages/amis-editor/

7.3 测试

bash
# 构建(Jest 不直接支持 TypeScript)
npm run build

# 运行所有测试
npm test --workspaces

# 运行特定测试
npm test --workspace amis -- -t <spec-name>

# 查看覆盖率
npm run coverage

# 更新快照
npm run update-snapshot

7.4 典型用例

typescript
import { render } from 'amis';

// 定义页面 JSON Schema
const schema = {
  type: 'page',
  title: '示例页面',
  body: {
    type: 'form',
    api: '/api/submit',
    body: [
      { type: 'input-text', name: 'name', label: '姓名' },
      { type: 'input-email', name: 'email', label: '邮箱' }
    ]
  }
};

// 渲染到页面
const element = render(schema, {}, {
  fetcher: (config) => fetch(config.url, config).then(r => r.json())
});

ReactDOM.render(element, document.getElementById('root'));