概念共识

◻︎ 低代码平台的组成部分:物料体系、低代码设计器、工程化体系(如配置的存取、版本的管理、产物的打包发布)。
◻︎ 低代码设计器:低代码平台提供的用于可视化搭建页面或模块的地方,通常就在平台的”/edit”页面。是低代码平台的核心。
◻︎ 低代码引擎:用于研发低代码设计器的框架,作用是帮助低代码平台开发者快速产出自定义的低代码设计器。总结为两点,(1)实现了低代码设计器基础功能;(2)提供了定制扩展能力。
◻︎ 阿里低代码引擎提供的定制扩展能力体现在如下几个方面:物料、插件、设置器。

◻︎ 低代码设计器插件是设计器中的自定义按钮和图标,支持两种形式:(1)PanelDock,展示图标,内容在展开面板中展示(2)Widget,内容直接展示。

涉及到的仓库

build-scripts。项目使用的工程构建脚手架工具,基于 webpack,包名自 1.x 版本起从”@alib/build-scripts”更名为”build-scripts”。
lowcode-engine。低代码引擎,遵循低代码引擎白皮书介绍的设计思路。
lowcode-demo。将引擎、设置器、插件、物料等组合起来的示例工程。
lowcode-materials。包含 Demo 中使用的物料库(antd, fusion)。
lowcode-engine-ext。包含 Demo 中使用的设置器。
lowcode-plugins。包含 Demo 中使用的插件。

build-scripts

■ 通过 build-scripts 组织的项目本质还是使用 webpack 生态(API 函数、loader、plugin、webpack-dev-server)。
■ 设计思路,将调试&构建&测试流程做了如下三个层级的抽象:
(1)将通用流程化的内容封装到 build-scripts 命令行(start-开发调试 & build-打包 & test-测试)。
(2)将针对特定场景及特性的通用配置与处理逻辑封装到 build-scripts 插件。
(3)通过本地自定义插件提供项目特有的个性化配置。
■ 以上(2)(3)体现在 build.json 文件内容中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"entry": {
"preview": "./src/preview.tsx"
},
... ...
"plugins": [
[
"build-plugin-react-app"
],
... ...
"./build.plugin.js"
]
}

■ 以下是官方提供的 build-scripts 插件。支持发布自己的 build-scripts 插件。

■ build-scripts 使用webpack-chain管理 webpack 配置,最终通过 webpack-chain 的 toConfig()方法转为符合格式规则的配置内容传入内部 webpack 使用。本地自定义插件中修改配置也通过编写 webpack-chain 的过程化语句实现。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module.exports = ({ onGetWebpackConfig, context }) => {
onGetWebpackConfig((config) => {
... ...
// 设置alias
config.resolve.alias.set('@', path.resolve(__dirname, './src'));

// 修改publicPath
config.output.publicPath((process.env.PUBLIC_PATH || '') + '/');

// 定义常量
config.plugin('define').use(context.webpack.DefinePlugin, [
{
'process.env.DEPLOY_ENV': process.env.DEPLOY_ENV,
},
]);

// 设置webpackDevServer的代理
config.devServer.proxy({
'/api': {
target: 'https://api.service.com',
changeOrigin: true,
},
});
... ...
});
}

lowcode-engine

○ 项目通过 lerna 管理,功能模块以 npm 包的形式组织,各个 npm 包使用 build-scripts 管理。
○ 项目主要输出的包有三个:@alilc/lowcode-engine、@alilc/lowcode-react-renderer、@alilc/lowcode-react-simulator-renderer。
○ @alilc/lowcode-engine 是低代码引擎的核心包,也会依赖项目中的其他包,如@alilc/lowcode-designer、@alilc/lowcode-editor-core、@alilc/lowcode-editor-skeleton。模块依赖与所属包的关系如下图。

○ 各模块作用的简要说明:

模块作用
pulgins用于设计器定制内容(插件、设置器、物料)的动态引入
skeleton注册管理插件
setters注册管理设置器
material注册管理物料
hotkey绑定管理快捷键
event自定义事件处理
project管理编排功能相关的模型系统
config负责配置的读写

○ @alilc/lowcode-react-renderer 是低代码设计器产物的渲染组件。
○ @alilc/lowcode-react-simulator-renderer 是低代码设计器中的画布组件。

lowcode-demo

■ 项目主要输出两类页面:(1)可视化编辑页面(2)可视化编辑页面产物的预览页面。
■ 项目入口如下,除了 “build.json” 中的 preview 之外,还有在“build.plugin.js”中动态写入的 scenarios 文件夹中各子文件夹。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
preview: [
"src/preview.tsx", // 预览页面入口
],
"antd-pro-with-formily": [
"src/scenarios/antd-pro-with-formily/index.ts",
],
"basic-antd": [
"src/scenarios/basic-antd/index.ts",
],
"basic-formily": [
"src/scenarios/basic-formily/index.ts",
],
... ... // scenarios文件夹中各个子文件夹,对应各场景的编辑页面
index: [
"src/scenarios/index/index.ts", // 综合编辑页面,提供了场景切换功能
],
}
编辑页面

● 编辑页面首先使用官方提供的插件、设置器、物料库对引擎做了定制。其中动态异步加载的地方都通过plugins.register()实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/** src/universal/plugin.tsx **/

import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext'; // 官方设置器

import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator';
... '@alilc/lowcode-plugin-xxxx';
import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; // ...官方插件


...
const { setterMap, pluginMap } = AliLowCodeEngineExt;
setters.registerSetter(setterMap); // 注册设置器
...

// 注册插件
skeleton.add({
name: 'saveSample',
area: 'topArea',
type: 'Widget',
props: {
align: 'right',
},
content: <Button onClick={() => saveSchema()}>保存到本地</Button>,
});
...

// 以资产包的方式注册物料库
await material.setAssets(await injectAssets(assets));
...

● 其中的 assets 是使用”资产包”的形式描述的物料库,格式遵循低代码引擎物料规范,示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
"packages": [
{
"package": "moment",
"version": "2.24.0",
"urls": [
"https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"
],
"library": "moment"
},
...
],
"components": [
{
"exportName": "AlilcLowcodeMaterialsMeta",
"npm": {
"package": "@alilc/lowcode-materials"
},
"url": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.js",
"urls": {
"default": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.js",
"design": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.design.js"
}
},
...
],
"sort": {
"groupList": []
},
...
}

● 最终通过@alilc/lowcode-engine 提供的 init()函数完成渲染,基本语法如下。

1
2
3
4
5
6
import { init } from '@alilc/lowcode-engine';

init(document.getElementById('lce-container'), {
...options,
}, preference);

预览页面

○ 预览页面将”schema+物料库描述”渲染成页面。其中物料库描述就是”资产包”中的“packages”内容,schema 包含了组件树结构及相关配置信息,内容格式遵循低代码引擎搭建协议规范,示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
"version": "1.0.0",
"componentsMap": [
{
"package": "@alifd/pro-layout",
"version": "1.0.1-beta.6",
"exportName": "Col",
"main": "lib/index.js",
"destructuring": true,
"subName": "",
"componentName": "NextCol"
},
...
],
"componentsTree": [
{
"componentName": "Page",
"id": "node_dockcviv8fo1",
"props": { "ref": "outerView", "style": { "height": "100%" } },
"fileName": "/",
...
"children": [
{
"componentName": "NextPage",
"id": "node_ockzs2vw431",
"props": {
...
},
"children": ...
}
]
}
],
"i18n": {}
}

○ 最终是通过@alilc/lowcode-react-renderer 完成渲染,基本语法如下。

1
2
3
4
5
6
7
8
9
import ReactRenderer from '@alilc/lowcode-react-renderer';
import ReactDOM from 'react-dom';

ReactDOM.render((
<ReactRenderer
schema={schema}
components={components}
/>
), document.getElementById('root'));

关于设计器的定制实践

API 文档
starter 项目,见白皮书中“定制插件”、“定制设置器”“定制物料”章节。