好傢伙,
demo-general專案執行後主介面如下
解析阿里低開引擎中的初始化方法init
拆解專案來自阿里的lowcode engine目錄下的 demo general專案
0.找到入口檔案
可以看到整個專案用到的外掛非常之多
於是
-
init:
init
方法用於初始化低程式碼引擎,負責載入各種外掛並配置引擎的執行環境。 -
plugins:
plugins
是一個外掛集合,包含了多個外掛,用於擴充套件低程式碼引擎的功能。 -
createFetchHandler:
createFetchHandler
方法用於建立一個資料來源的處理器,用於處理資料來源相關的操作。 -
EditorInitPlugin: 編輯器初始化外掛,用於初始化低程式碼引擎的編輯器。
-
UndoRedoPlugin: 撤銷重做外掛,提供撤銷和重做操作的功能。
-
ZhEnPlugin: 中英文切換外掛,用於實現介面語言的切換。
-
CodeGenPlugin: 程式碼生成外掛,用於生成程式碼。
-
DataSourcePanePlugin: 資料來源皮膚外掛,用於管理資料來源。
-
SchemaPlugin: Schema 外掛,用於處理資料模型的定義和管理。
-
CodeEditorPlugin: 程式碼編輯器外掛,用於提供程式碼編輯功能。
-
ManualPlugin: 手冊外掛,提供使用者手冊和幫助文件。
-
InjectPlugin: 注入外掛,用於注入特定功能或程式碼。
-
SimulatorResizerPlugin: 模擬器調整外掛,用於調整模擬器的大小。
-
ComponentPanelPlugin: 元件皮膚外掛,用於管理可用元件。
-
DefaultSettersRegistryPlugin: 預設設定註冊外掛,用於註冊預設設定。
-
LoadIncrementalAssetsWidgetPlugin: 載入增量資源小部件外掛,用於載入增量資源。
-
SaveSamplePlugin: 儲存示例外掛,用於儲存示例程式碼。
-
PreviewSamplePlugin: 預覽示例外掛,用於預覽示例程式碼。
-
CustomSetterSamplePlugin: 自定義設定示例外掛,用於自定義設定示例。
-
SetRefPropPlugin: 設定引用屬性外掛,用於設定引用屬性。
-
LogoSamplePlugin: Logo 示例外掛,用於展示 Logo 示例。
-
SimulatorLocalePlugin: 模擬器語言外掛,用於設定模擬器的語言。
-
lowcodePlugin: 低程式碼元件外掛,用於提供低程式碼元件功能。
-
appHelper: 應用程式輔助方法,可能包含一些輔助函式或工具函式。
-
global.scss: 全域性樣式檔案,定義了全域性的樣式規則
那麼把我們主要要解析的檔案拿出來
就這行
import { init, plugins } from '@alilc/lowcode-engine';
1.官方文件定位包位置
2.在lowcode-engine中尋找init方法
直接找到
engine-core引擎核心,是他沒錯了
我們來看看這段程式碼到底在做什麼?
//engine-core.ts
export async function init( container?: HTMLElement, options?: IPublicTypeEngineOptions, pluginPreference?: PluginPreference, ) { await destroy(); let engineOptions = null; if (isPlainObject(container)) { engineOptions = container; engineContainer = document.createElement('div'); engineContainer.id = 'engine'; document.body.appendChild(engineContainer); } else { engineOptions = options; engineContainer = container; if (!container) { engineContainer = document.createElement('div'); engineContainer.id = 'engine'; document.body.appendChild(engineContainer); } } engineConfig.setEngineOptions(engineOptions as any); const { Workbench } = common.skeletonCabin; if (options && options.enableWorkspaceMode) { const disposeFun = await pluginPromise; disposeFun && disposeFun(); render( createElement(WorkSpaceWorkbench, { workspace: innerWorkspace, // skeleton: workspace.skeleton, className: 'engine-main', topAreaItemClassName: 'engine-actionitem', }), engineContainer, ); innerWorkspace.enableAutoOpenFirstWindow = engineConfig.get('enableAutoOpenFirstWindow', true); innerWorkspace.setActive(true); innerWorkspace.initWindow(); innerHotkey.activate(false); await innerWorkspace.plugins.init(pluginPreference); return; } await plugins.init(pluginPreference as any); render( createElement(Workbench, { skeleton: innerSkeleton, className: 'engine-main', topAreaItemClassName: 'engine-actionitem', }), engineContainer, ); }
回到前面demo-general專案中中初始化部分
//index.tx
(async function main() {
await registerPlugins();
init(document.getElementById('lce-container')!, {
locale: 'zh-CN',
enableCondition: true,
enableCanvasLock: true,
// 預設繫結變數
supportVariableGlobally: true,
requestHandlersMap: {
fetch: createFetchHandler(),
},
appHelper,
});
})();
3.解釋init()
export async function init(
container?: HTMLElement, // 初始化函式引數:容器元素,可選
options?: IPublicTypeEngineOptions, // 初始化函式引數:引擎選項,可選
pluginPreference?: PluginPreference, // 初始化函式引數:外掛偏好設定,可選
) {
await destroy(); // 銷燬之前的狀態,確保初始化乾淨
let engineOptions = null; // 初始化引擎選項變數
if (isPlainObject(container)) { // 如果容器是一個普通物件
engineOptions = container; // 將容器作為引擎選項
engineContainer = document.createElement('div'); // 建立一個新的 div 元素作為引擎容器
engineContainer.id = 'engine'; // 設定容器的 id 為 'engine'
document.body.appendChild(engineContainer); // 將容器新增到 body 中
} else {
engineOptions = options; // 使用傳入的引擎選項
engineContainer = container; // 使用傳入的容器
if (!container) { // 如果容器不存在
engineContainer = document.createElement('div'); // 建立一個新的 div 元素作為引擎容器
engineContainer.id = 'engine'; // 設定容器的 id 為 'engine'
document.body.appendChild(engineContainer); // 將容器新增到文件的 body 中
}
}
engineConfig.setEngineOptions(engineOptions as any); // 設定引擎配置的選項
const { Workbench } = common.skeletonCabin; // 從骨架中解構出 Workbench 元件
if (options && options.enableWorkspaceMode) { // 如果啟用工作區模式
const disposeFun = await pluginPromise; // 等待外掛 Promise 的解析
disposeFun && disposeFun(); // 如果存在 disposeFun 函式,則執行
render( // 渲染工作區工作臺元件
createElement(WorkSpaceWorkbench, {
workspace: innerWorkspace, // 傳入內部工作區
className: 'engine-main', // 設定類名
topAreaItemClassName: 'engine-actionitem', // 設定頂部區域項的類名
}),
engineContainer, // 渲染到引擎容器中
);
innerWorkspace.enableAutoOpenFirstWindow = engineConfig.get('enableAutoOpenFirstWindow', true); // 設定內部工作區自動開啟第一個視窗的屬性
innerWorkspace.setActive(true); // 設定工作區為活動狀態
innerWorkspace.initWindow(); // 初始化視窗
innerHotkey.activate(false); // 啟用快捷鍵
await innerWorkspace.plugins.init(pluginPreference); // 初始化工作區外掛
return; // 返回
}
await plugins.init(pluginPreference as any); // 初始化外掛
render( // 渲染工作臺元件
createElement(Workbench, {
skeleton: innerSkeleton, // 傳入內部骨架
className: 'engine-main', // 設定類名
topAreaItemClassName: 'engine-actionitem', // 設定頂部區域項的類名
}),
engineContainer, // 渲染到引擎容器中
);
}
再來找
最後,來到workbench.tsx中
4.workbench.tsx
export class Workbench extends Component<{
workspace: Workspace; // 工作空間物件
config?: EditorConfig; // 編輯器配置(可選)
components?: PluginClassSet; // 外掛類集合
className?: string; // 類名
topAreaItemClassName?: string; // 頂部區域項的類名
}, {
workspaceEmptyComponent: any; // 工作空間為空時的元件
theme?: string; // 主題
}> {
constructor(props: any) {
super(props);
const { config, components, workspace } = this.props;
const { skeleton } = workspace;
skeleton.buildFromConfig(config, components); // 從配置和元件構建骨架
engineConfig.onGot('theme', (theme) => {
this.setState({
theme,
});
});
engineConfig.onGot('workspaceEmptyComponent', (workspaceEmptyComponent) => {
this.setState({
workspaceEmptyComponent,
});
});
this.state = {
workspaceEmptyComponent: engineConfig.get('workspaceEmptyComponent'), // 獲取工作空間為空時的元件
theme: engineConfig.get('theme'), // 獲取主題
};
}
render() {
const { workspace, className, topAreaItemClassName } = this.props;
const { skeleton } = workspace;
const { workspaceEmptyComponent: WorkspaceEmptyComponent, theme } = this.state;
return (
<div className={classNames('lc-workspace-workbench', className, theme)}>
<SkeletonContext.Provider value={skeleton}>
<TopArea className="lc-workspace-top-area" area={skeleton.topArea} itemClassName={topAreaItemClassName} /> {/* 渲染頂部區域 */}
<div className="lc-workspace-workbench-body">
<LeftArea className="lc-workspace-left-area lc-left-area" area={skeleton.leftArea} /> {/* 渲染左側區域 */}
<LeftFloatPane area={skeleton.leftFloatArea} /> {/* 渲染左側浮動區域 */}
<LeftFixedPane area={skeleton.leftFixedArea} /> {/* 渲染左側固定區域 */}
<div className="lc-workspace-workbench-center">
<div className="lc-workspace-workbench-center-content">
<SubTopArea area={skeleton.subTopArea} itemClassName={topAreaItemClassName} /> {/* 渲染中上區域 */}
<div className="lc-workspace-workbench-window">
{
workspace.windows.map(d => (
<WindowView
active={d.id === workspace.window?.id} // 判斷視窗是否啟用
window={d}
key={d.id}
/>
))
}
{
!workspace.windows.length && WorkspaceEmptyComponent ? <WorkspaceEmptyComponent /> : null // 根據條件渲染工作空間為空時的元件
}
</div>
</div>
<MainArea area={skeleton.mainArea} /> {/* 渲染主區域 */}
<BottomArea area={skeleton.bottomArea} /> {/* 渲染底部區域 */}
</div>
{/* <RightArea area={skeleton.rightArea} /> */}
</div>
<TipContainer /> {/* 渲染提示容器 */}
</SkeletonContext.Provider>
</div>
);
}
}
5.main-area.tsx
export default class MainArea extends Component<{ area: Area<any, Panel | Widget> }> {
render() {
const { area } = this.props;
return (
<div className={classNames('lc-main-area engine-workspacepane')}>
{area.container.items.map((item) => item.content)}
</div>
);
}
}
以上程式碼,
將area.container.items陣列中每個元素的content屬性渲染到頁面上,展示在MainArea元件所代表的區域內。
至此,低開引擎的初始化完成