8000 同步代码 by wangshihao111 · Pull Request #105 · alibaba/lowcode-plugins · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension 8000


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/plugin-multiple-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ await plugins.register(plugin);
4. 如需在 setter 内适用类型定义,请开启 base-editor 的单例模式,仅需在应用入口处调用如下方法即可:
5. 如果低码项目有使用出码,则需对出码进行定制,将 _sourceCodeMap 中的文件生成到项目中,并对文件的引用进行处理,具体处理方式可自行组织

__使用单例模式__
```ts
import { configure } from '@alilc/lowcode-plugin-base-monaco-editor';
configure({ singleton: true });
Expand Down
6 changes: 5 additions & 1 deletion packages/plugin-multiple-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"release": "fast-publish"
},
"dependencies": {
"@alilc/lowcode-types": "^1.0.3"
"@alilc/lowcode-types": "^1.0.3",
"@babel/types": "^7.16.0"
},
"devDependencies": {
"@alifd/next": "^1.25.29",
Expand Down Expand Up @@ -122,6 +123,9 @@
"webpackbar": "^5.0.2",
"workbox-webpack-plugin": "^6.4.1"
},
"resolutions": {
"@types/react": "^17.0.2"
},
"browserslist": {
"production": [
">0.2%",
Expand Down
34 changes: 27 additions & 7 deletions packages/plugin-multiple-editor/src/Context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
sortDir,
} from './utils/files';
import { editorController } from './Controller';
import { getDefaultFileList } from './MultipleFileEditor/util';

export type CurrentFile = {
file?: File;
Expand All @@ -39,11 +38,13 @@ export interface EditorContextType {
updateFileTreeByPath(
path: string[],
target: Dir | File,
operation: 'delete' | 'add'
operation: 'delete' | 'add' | 'rename',
newName?: string
): void;
selectFile(file: File | string, path: string[]): void;
selectFileByName(name: string): void;
updateState(state: Partial<StoreState>): void;
updateCurrentFile(content: string): void;
initialFileMap: Record<string, string>;
extraLibs: { path: string; content: string }[];
}
Expand Down Expand Up @@ -86,7 +87,9 @@ export const EditorProvider: FC<{
() => editorController.getCodeTemp()?._sourceCodeMap.files || {},
[]
);
const initFileTree = fileMap ? fileMapToTree(fileMap) : new Dir('/');
const initFileTree = fileMap
? fileMapToTree(fileMap)
: new Dir('/', [], [], '');
const initState: StoreState = {
declarations: '',
extraLibs: [],
Expand All @@ -103,7 +106,7 @@ export const EditorProvider: FC<{
if (typeof file === 'string') {
const { fileTree } = state;
const targetFile = getFileByPath(fileTree, file, path);
finalFile = targetFile || new File('index.js', '');
finalFile = targetFile || new File('index.js', '', 'index.js');
} else {
finalFile = file;
}
Expand All @@ -123,12 +126,14 @@ export const EditorProvider: FC<{
updateFileTree(tree: Dir) {
dispatch({ type: 'update', payload: { fileTree: sortDir(tree) } });
},
updateFileTreeByPath(path, target, operation) {
updateFileTreeByPath(path, target, operation, newName) {
const { fileTree } = state;
if (operation === 'add') {
insertNodeToTree(fileTree, path, target);
} else if (operation === 'delete') {
deleteNodeOnTree(fileTree, path, target);
} else if (operation === 'rename') {
target.name = newName as string;
}
const payload: Partial<StoreState> = { fileTree: sortDir(fileTree) };
// 新增文件时,选中当前文件
Expand All @@ -147,12 +152,27 @@ export const EditorProvider: FC<{
updateState(state: Partial<StoreState>) {
dispatch({ type: 'update', payload: state });
},
updateCurrentFile(content) {
if (this.currentFile.file) {
this.currentFile.file.content = content;
this.updateState({
currentFile: {
...this.currentFile,
file: {
...this.currentFile.file,
content,
},
},
});
// this.updateFileTree({...this.fileTree});
}
},
}),
[fileMap, selectFile, softSave, state]
[fileMap, mode, selectFile, softSave, state]
);
useEffect(() => {
const off = editorController.onSourceCodeChange((codeMap) => {
const fileTree = fileMapToTree(codeMap) || new Dir('/');
const fileTree = fileMapToTree(codeMap) || new Dir('/', [], [], '');
dispatch({ type: 'update', payload: { fileTree } });
const targetFile = getFileByPath(fileTree, 'index.js', []);
setTimeout(() => {
Expand Down
126 changes: 93 additions & 33 deletions packages/plugin-multiple-editor/src/Controller.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import type { Project, Event } from '@alilc/lowcode-shell';
import { skeleton, common } from '@alilc/lowcode-engine';
import { IPublicTypeProjectSchema } from '@alilc/lowcode-types';
import { skeleton } from '@alilc/lowcode-engine';
import {
beautifyCSS,
compatGetSourceCodeMap,
fileMapToTree,
getConstructorContent,
getDefaultDeclaration,
getInitFuncContent,
lintIndex,
treeToMap,
} from './utils';
import { FunctionEventParams, Monaco, ObjectType } from './types';
import type { editor } from 'monaco-editor';
import { common } from '@alilc/lowcode-engine';
import { editor } from 'monaco-editor';
import {
addFunction,
focusByFunctionName,
Expand All @@ -21,13 +24,14 @@ import { EditorContextType } from './Context';
import { Message } from '@alifd/next';
import { getMethods } from './utils/get-methods';
import { EditorHook, HookKeys } from './EditorHook';
import { Service } from './Service';
import { PluginHooks, Service } from './Service';
import { MonacoSuggestions } from './MonacoSuggestions';

export * from './EditorHook';

export interface EditorControllerState {
declarationsMap: Record<string, string>;
extraLibs: Array<{ path: string; content: string }>;
extraLibs: { path: string; content: string }[];
}

export type HookHandleFn<T = any> = (fn: T) => () => void;
Expand All @@ -49,7 +53,9 @@ export class EditorController extends EditorHook {

defaultFiles: ObjectType<string>;

monaco?: Monaco;
useLess?: boolean;

public monaco?: Monaco;

private codeTemp?: CodeTemp;

Expand All @@ -59,23 +65,30 @@ export class EditorController extends EditorHook {

private state: EditorControllerState;

codeEditor?: editor.IStandaloneCodeEditor;
public codeEditor?: editor.IStandaloneCodeEditor;

public codeEditorCtx?: EditorContextType;

public service!: Service;

private codeEditorCtx?: EditorContextType;
private loadMonacoPromise?: Promise<any>;

service!: Service;
private monacoSuggestions: MonacoSuggestions;

onImportSchema: HookHandleFn<(schema: any) => void | Promise<void>> =
this.hookFactory(HookKeys.onImport);
public onImportSchema: HookHandleFn<
(schema: IPublicTypeProjectSchema) => void | Promise<void>
> = this.hookFactory(HookKeys.onImport);

onSourceCodeChange: HookHandleFn<(code: any) => void> = this.hookFactory(
HookKeys.onSourceCodeChange
);
public onSourceCodeChange: HookHandleFn<(code: any) => void> =
this.hookFactory(HookKeys.onSourceCodeChange);

onEditCodeChange: HookHandleFn<
public onEditCodeChange: HookHandleFn<
(code: { content: string; file: string }) => void
> = this.hookFactory(HookKeys.onEditCodeChange);

public onMonacoLoaded: HookHandleFn<(monaco: Monaco) => void> =
this.hookFactory(HookKeys.onMonacoLoaded);

constructor() {
super();
this.state = {
Expand All @@ -85,6 +98,21 @@ export class EditorController extends EditorHook {
this.listeners = [];
this.defaultFiles = {};
this.extraLibMap = new Map();
this.monacoSuggestions = new MonacoSuggestions(this);
}

async initMonaco() {
if (!this.monaco) {
if (!this.loadMonacoPromise) {
const { getMonaco } = await import(
'@alilc/lowcode-plugin-base-monaco-editor'
);
this.loadMonacoPromise = getMonaco();
}
this.monaco = await this.loadMonacoPromise;
this.triggerHook(HookKeys.onMonacoLoaded, this.monaco);
this.service.triggerHook(PluginHooks.onMonacoLoaded, this.monaco);
}
}

init(project: Project, editor: Event, service: Service) {
Expand All @@ -94,6 +122,7 @@ export class EditorController extends EditorHook {
this.setupEventListeners();
this.initCodeTempBySchema(this.getSchema(true));
this.triggerHook(HookKeys.onImport, this.getSchema(true));
this.initMonaco();
}

initCodeEditor(
Expand All @@ -102,6 +131,7 @@ export class EditorController extends EditorHook {
) {
this.codeEditor = codeEditor;
this.codeEditorCtx = ctx;
this.monacoSuggestions.init();
}

setCodeTemp(code: any | ((old: CodeTemp) => CodeTemp)) {
Expand All @@ -122,7 +152,7 @@ export class EditorController extends EditorHook {
this.applyLibs();
}

addComponentDeclarations(list: Array<[string, string]> = []) {
addComponentDeclarations(list: [string, string][] = []) {
for (const [key, dec] of list) {
this.state.declarationsMap[key] = dec;
}
Expand All @@ -131,7 +161,7 @@ export class EditorController extends EditorHook {
}

private publishExtraLib() {
const libs: Array<{ path: string; content: string }> = [];
const libs: { path: string; content: string }[] = [];
this.extraLibMap.forEach((content, path) => libs.push({ content, path }));
this.state.extraLibs = libs;
this.publish();
Expand All @@ -151,10 +181,7 @@ export class EditorController extends EditorHook {

private async applyLibs() {
if (!this.monaco) {
const { getMonaco } = await import(
'@alilc/lowcode-plugin-base-monaco-editor'
);
this.monaco = await getMonaco(undefined) as any;
await this.initMonaco();
}
const decStr = Object.keys(this.state.declarationsMap).reduce(
(v, k) => `${v}\n${k}: ${this.state.declarationsMap[k]};\n`,
Expand All @@ -173,7 +200,7 @@ export class EditorController extends EditorHook {
});
}

getSchema(pure?: boolean): any {
getSchema(pure?: boolean): IPublicTypeProjectSchema {
const schema = this.project.exportSchema(
common.designerCabin.TransformStage.Save
);
Expand All @@ -182,15 +209,21 @@ export class EditorController extends EditorHook {
? treeToMap(this.codeEditorCtx.fileTree)
: this.codeTemp?._sourceCodeMap.files; // 获取最新的fileMap
if (fileMap && !pure) {
if (!this.compileSourceCode(fileMap)) {
throw new Error('编译失败');
try {
if (!this.compileSourceCode(fileMap)) {
// 下面会导致整个页面挂掉,先作为弱依赖,给个提示
throw new Error('编译失败');
}
Object.assign(schema.componentsTree[0], this.codeTemp);
} catch (error) {
console.error(error);
Message.error('源码编译失败,请返回修改');
}
Object.assign(schema.componentsTree[0], this.codeTemp);
}
return schema;
}

importSchema(schema: any) {
importSchema(schema: IPublicTypeProjectSchema) {
this.project.importSchema(schema);
this.initCodeTempBySchema(schema);
this.triggerHook(HookKeys.onImport, schema);
Expand All @@ -217,23 +250,22 @@ export class EditorController extends EditorHook {
};
}

initCodeTempBySchema(schema: any) {
public initCodeTempBySchema(schema: IPublicTypeProjectSchema) {
const componentSchema = schema.componentsTree[0] || {};
const { css, methods, state, lifeCycles } = componentSchema;
const { css, methods, state, lifeCycles } = componentSchema as any;
const codeMap = (componentSchema as any)._sourceCodeMap;
const defaultFileMap = {
...this.defaultFiles,
...getDefaultFileList(schema),
...getDefaultFileList(schema, this.useLess),
};
const compatMap = compatGetSourceCodeMap(codeMap);
const compatMap = compatGetSourceCodeMap(codeMap, defaultFileMap);
this.codeTemp = {
css,
methods,
state,
lifeCycles,
_sourceCodeMap: {
...compatMap,
files: defaultFileMap,
},
};
}
Expand All @@ -253,8 +285,8 @@ export class EditorController extends EditorHook {
this.editor?.on('common:codeEditor.addFunction', ((
params: FunctionEventParams
) => {
this.codeEditorCtx?.selectFile('index.js', []);
setTimeout(() => {
this.codeEditorCtx?.selectFile('index.js', []);
if (this.monaco && this.codeEditor) {
addFunction(this.codeEditor, params, this.monaco);
}
Expand Down Expand Up @@ -306,7 +338,20 @@ export class EditorController extends EditorHook {
pageNode.state = state;
pageNode.methods = methods;
pageNode.lifeCycles = lifeCycles;
pageNode.css = beautifyCSS(fileMap['index.css'] || '', {});
const lessContent = fileMap['index.less'];
// 没有less文件,走之前的逻辑
if (!lessContent) {
pageNode.css = beautifyCSS(fileMap['index.css'] || '', {});
}
if (this.useLess && lessContent) {
window.less?.render(lessContent, {}, (err: any, output: any) => {
if (err) {
Message.error('less 编译失败');
console.error(err);
}
pageNode.css = output?.css || '';
});
}
if (lifeCycles.constructor === {}.constructor) {
lifeCycles.constructor = {
originalCode: 'function constructor() { }',
Expand Down Expand Up @@ -341,10 +386,25 @@ export class EditorController extends EditorHook {
return true;
}

resetSaveStatus() {
public resetSaveStatus() {
this.codeEditorCtx?.updateState({ modifiedKeys: [] });
}

// 添加一堆文件
public addFiles(fileMap: ObjectType<string>) {
if (!Object.keys(fileMap || {}).length || !this.codeEditorCtx?.fileTree) {
return;
}
const subTree = fileMapToTree(fileMap);
const { files, dirs } = subTree;
const newTree = { ...this.codeEditorCtx?.fileTree };
newTree.files?.push(...files);
newTree.dirs?.push(...dirs);
this.codeEditorCtx.updateState({
fileTree: newTree,
});
}

triggerHook(key: HookKeys, ...args: any[]): void {
super.triggerHook(key, ...args);
}
Expand Down
Loading
0