mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-01 13:40:41 +00:00
refactor: 💡 Rax 的出码插件有很多地方与 React 不同,还是单独拎出来为好
This commit is contained in:
parent
63d5b6e4b0
commit
a66ec82879
@ -0,0 +1,31 @@
|
||||
import { COMMON_CHUNK_NAME } from '../../../const/generator';
|
||||
|
||||
import {
|
||||
BuilderComponentPlugin,
|
||||
BuilderComponentPluginFactory,
|
||||
ChunkType,
|
||||
FileType,
|
||||
ICodeStruct,
|
||||
IContainerInfo,
|
||||
} from '../../../types';
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||
const next: ICodeStruct = {
|
||||
...pre,
|
||||
};
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
||||
content: `import { createElement, Component } from 'rax';`,
|
||||
linkAfter: [],
|
||||
});
|
||||
|
||||
return next;
|
||||
};
|
||||
return plugin;
|
||||
};
|
||||
|
||||
export default pluginFactory;
|
||||
@ -0,0 +1,9 @@
|
||||
export const RAX_CHUNK_NAME = {
|
||||
ClassRenderStart: 'RaxComponentClassRenderStart',
|
||||
ClassRenderPre: 'RaxComponentClassRenderPre',
|
||||
ClassRenderEnd: 'RaxComponentClassRenderEnd',
|
||||
ClassRenderJSX: 'RaxComponentClassRenderJSX',
|
||||
ClassDidMountStart: 'RaxComponentClassDidMountStart',
|
||||
ClassDidMountEnd: 'RaxComponentClassDidMountEnd',
|
||||
ClassDidMountContent: 'RaxComponentClassDidMountContent',
|
||||
};
|
||||
@ -0,0 +1,108 @@
|
||||
import changeCase from 'change-case';
|
||||
import { COMMON_CHUNK_NAME, CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
|
||||
import { RAX_CHUNK_NAME } from './const';
|
||||
|
||||
import {
|
||||
BuilderComponentPlugin,
|
||||
BuilderComponentPluginFactory,
|
||||
ChunkType,
|
||||
FileType,
|
||||
ICodeStruct,
|
||||
IContainerInfo,
|
||||
} from '../../../types';
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||
const next: ICodeStruct = {
|
||||
...pre,
|
||||
};
|
||||
|
||||
const ir = next.ir as IContainerInfo;
|
||||
|
||||
// 将模块名转换成 PascalCase 的格式,并添加特定后缀,防止命名冲突
|
||||
const componentClassName = `${changeCase.pascalCase(ir.moduleName)}$$Page`;
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.Start,
|
||||
content: `class ${componentClassName} extends Component {`,
|
||||
linkAfter: [
|
||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
||||
COMMON_CHUNK_NAME.FileVarDefine,
|
||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
||||
],
|
||||
});
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.End,
|
||||
content: `}`,
|
||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start, RAX_CHUNK_NAME.ClassRenderEnd],
|
||||
});
|
||||
|
||||
// next.chunks.push({
|
||||
// type: ChunkType.STRING,
|
||||
// fileType: FileType.JSX,
|
||||
// name: CLASS_DEFINE_CHUNK_NAME.ConstructorStart,
|
||||
// content: 'constructor(props, context) { super(props); ',
|
||||
// linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
|
||||
// });
|
||||
|
||||
// next.chunks.push({
|
||||
// type: ChunkType.STRING,
|
||||
// fileType: FileType.JSX,
|
||||
// name: CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
||||
// content: '}',
|
||||
// linkAfter: [
|
||||
// CLASS_DEFINE_CHUNK_NAME.ConstructorStart,
|
||||
// CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
||||
// ],
|
||||
// });
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: RAX_CHUNK_NAME.ClassRenderStart,
|
||||
content: 'render() {',
|
||||
linkAfter: [
|
||||
CLASS_DEFINE_CHUNK_NAME.Start,
|
||||
CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
||||
CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
||||
],
|
||||
});
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: RAX_CHUNK_NAME.ClassRenderEnd,
|
||||
content: '}',
|
||||
linkAfter: [
|
||||
RAX_CHUNK_NAME.ClassRenderStart,
|
||||
RAX_CHUNK_NAME.ClassRenderPre,
|
||||
RAX_CHUNK_NAME.ClassRenderJSX,
|
||||
],
|
||||
});
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: FileType.JSX,
|
||||
name: COMMON_CHUNK_NAME.FileExport,
|
||||
content: `export default ${componentClassName};`,
|
||||
linkAfter: [
|
||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
||||
COMMON_CHUNK_NAME.FileVarDefine,
|
||||
COMMON_CHUNK_NAME.FileUtilDefine,
|
||||
CLASS_DEFINE_CHUNK_NAME.End,
|
||||
],
|
||||
});
|
||||
|
||||
return next;
|
||||
};
|
||||
return plugin;
|
||||
};
|
||||
|
||||
export default pluginFactory;
|
||||
@ -0,0 +1,52 @@
|
||||
import { CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
|
||||
|
||||
import { generateCompositeType } from '../../../utils/compositeType';
|
||||
|
||||
import {
|
||||
BuilderComponentPlugin,
|
||||
BuilderComponentPluginFactory,
|
||||
ChunkType,
|
||||
FileType,
|
||||
ICodeStruct,
|
||||
IContainerInfo,
|
||||
} from '../../../types';
|
||||
|
||||
type PluginConfig = {
|
||||
fileType: string;
|
||||
}
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||
const cfg: PluginConfig = {
|
||||
fileType: FileType.JSX,
|
||||
...config,
|
||||
};
|
||||
|
||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||
const next: ICodeStruct = {
|
||||
...pre,
|
||||
};
|
||||
|
||||
const ir = next.ir as IContainerInfo;
|
||||
|
||||
if (ir.state) {
|
||||
const state = ir.state;
|
||||
const fields = Object.keys(state).map<string>(stateName => {
|
||||
const [isString, value] = generateCompositeType(state[stateName]);
|
||||
return `${stateName}: ${isString ? `'${value}'` : value},`;
|
||||
});
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
||||
content: `this.state = { ${fields.join('')} };`,
|
||||
linkAfter: [CLASS_DEFINE_CHUNK_NAME.ConstructorStart],
|
||||
});
|
||||
}
|
||||
|
||||
return next;
|
||||
};
|
||||
return plugin;
|
||||
};
|
||||
|
||||
export default pluginFactory;
|
||||
@ -0,0 +1,64 @@
|
||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
||||
|
||||
import { generateCompositeType } from '../../../utils/compositeType';
|
||||
|
||||
import {
|
||||
BuilderComponentPlugin,
|
||||
BuilderComponentPluginFactory,
|
||||
ChunkType,
|
||||
FileType,
|
||||
ICodeStruct,
|
||||
IContainerInfo,
|
||||
} from '../../../types';
|
||||
|
||||
type PluginConfig = {
|
||||
fileType: string;
|
||||
implementType: 'inConstructor' | 'insMember' | 'hooks';
|
||||
}
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||
const cfg: PluginConfig = {
|
||||
fileType: FileType.JSX,
|
||||
implementType: 'inConstructor',
|
||||
...config,
|
||||
};
|
||||
|
||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||
const next: ICodeStruct = {
|
||||
...pre,
|
||||
};
|
||||
|
||||
const ir = next.ir as IContainerInfo;
|
||||
|
||||
if (ir.state) {
|
||||
const state = ir.state;
|
||||
const fields = Object.keys(state).map<string>(stateName => {
|
||||
const [isString, value] = generateCompositeType(state[stateName]);
|
||||
return `${stateName}: ${isString ? `'${value}'` : value},`;
|
||||
});
|
||||
|
||||
if (cfg.implementType === 'inConstructor') {
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
||||
content: `this.state = { ${fields.join('')} };`,
|
||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorContent]],
|
||||
});
|
||||
} else if (cfg.implementType === 'insMember') {
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
|
||||
content: `state = { ${fields.join('')} };`,
|
||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsVar]],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return next;
|
||||
};
|
||||
return plugin;
|
||||
};
|
||||
|
||||
export default pluginFactory;
|
||||
@ -0,0 +1,40 @@
|
||||
import { CLASS_DEFINE_CHUNK_NAME } from '../../../const/generator';
|
||||
|
||||
import {
|
||||
BuilderComponentPlugin,
|
||||
BuilderComponentPluginFactory,
|
||||
ChunkType,
|
||||
FileType,
|
||||
ICodeStruct,
|
||||
} from '../../../types';
|
||||
|
||||
type PluginConfig = {
|
||||
fileType: string;
|
||||
}
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||
const cfg: PluginConfig = {
|
||||
fileType: FileType.JSX,
|
||||
...config,
|
||||
};
|
||||
|
||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||
const next: ICodeStruct = {
|
||||
...pre,
|
||||
};
|
||||
|
||||
// TODO: utils 怎么注入?
|
||||
// next.chunks.push({
|
||||
// type: ChunkType.STRING,
|
||||
// fileType: cfg.fileType,
|
||||
// name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
||||
// content: `this.utils = utils;`,
|
||||
// linkAfter: [CLASS_DEFINE_CHUNK_NAME.ConstructorStart],
|
||||
// });
|
||||
|
||||
return next;
|
||||
};
|
||||
return plugin;
|
||||
};
|
||||
|
||||
export default pluginFactory;
|
||||
@ -0,0 +1,90 @@
|
||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
||||
import { RAX_CHUNK_NAME } from './const';
|
||||
|
||||
import {
|
||||
getFuncExprBody,
|
||||
transformFuncExpr2MethodMember,
|
||||
} from '../../../utils/jsExpression';
|
||||
|
||||
import {
|
||||
BuilderComponentPlugin,
|
||||
BuilderComponentPluginFactory,
|
||||
ChunkType,
|
||||
CodeGeneratorError,
|
||||
FileType,
|
||||
ICodeChunk,
|
||||
ICodeStruct,
|
||||
IContainerInfo,
|
||||
IJSExpression,
|
||||
} from '../../../types';
|
||||
|
||||
type PluginConfig = {
|
||||
fileType: string;
|
||||
exportNameMapping: Record<string, string>;
|
||||
normalizeNameMapping: Record<string, string>;
|
||||
}
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||
const cfg: PluginConfig = {
|
||||
fileType: FileType.JSX,
|
||||
exportNameMapping: {},
|
||||
normalizeNameMapping: {},
|
||||
...config,
|
||||
};
|
||||
|
||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||
const next: ICodeStruct = {
|
||||
...pre,
|
||||
};
|
||||
|
||||
const ir = next.ir as IContainerInfo;
|
||||
|
||||
if (ir.lifeCycles) {
|
||||
const lifeCycles = ir.lifeCycles;
|
||||
const chunks = Object.keys(lifeCycles).map<ICodeChunk>(lifeCycleName => {
|
||||
const normalizeName = cfg.normalizeNameMapping[lifeCycleName] || lifeCycleName;
|
||||
const exportName = cfg.exportNameMapping[lifeCycleName] || lifeCycleName;
|
||||
if (normalizeName === 'constructor') {
|
||||
return {
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
||||
content: getFuncExprBody(
|
||||
(lifeCycles[lifeCycleName] as IJSExpression).value,
|
||||
),
|
||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorStart]],
|
||||
};
|
||||
}
|
||||
if (normalizeName === 'render') {
|
||||
return {
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: RAX_CHUNK_NAME.ClassRenderPre,
|
||||
content: getFuncExprBody(
|
||||
(lifeCycles[lifeCycleName] as IJSExpression).value,
|
||||
),
|
||||
linkAfter: [RAX_CHUNK_NAME.ClassRenderStart],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
||||
content: transformFuncExpr2MethodMember(
|
||||
exportName,
|
||||
(lifeCycles[lifeCycleName] as IJSExpression).value,
|
||||
),
|
||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
|
||||
};
|
||||
});
|
||||
|
||||
next.chunks.push.apply(next.chunks, chunks);
|
||||
}
|
||||
|
||||
return next;
|
||||
};
|
||||
return plugin;
|
||||
};
|
||||
|
||||
export default pluginFactory;
|
||||
@ -0,0 +1,54 @@
|
||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
||||
|
||||
import { transformFuncExpr2MethodMember } from '../../../utils/jsExpression';
|
||||
|
||||
import {
|
||||
BuilderComponentPlugin,
|
||||
BuilderComponentPluginFactory,
|
||||
ChunkType,
|
||||
FileType,
|
||||
ICodeChunk,
|
||||
ICodeStruct,
|
||||
IContainerInfo,
|
||||
IJSExpression,
|
||||
} from '../../../types';
|
||||
|
||||
type PluginConfig = {
|
||||
fileType: string;
|
||||
}
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||
const cfg: PluginConfig = {
|
||||
fileType: FileType.JSX,
|
||||
...config,
|
||||
};
|
||||
|
||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||
const next: ICodeStruct = {
|
||||
...pre,
|
||||
};
|
||||
|
||||
const ir = next.ir as IContainerInfo;
|
||||
|
||||
if (ir.methods) {
|
||||
const methods = ir.methods;
|
||||
const chunks = Object.keys(methods).map<ICodeChunk>(methodName => ({
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
||||
content: transformFuncExpr2MethodMember(
|
||||
methodName,
|
||||
(methods[methodName] as IJSExpression).value,
|
||||
),
|
||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
|
||||
}));
|
||||
|
||||
next.chunks.push.apply(next.chunks, chunks);
|
||||
}
|
||||
|
||||
return next;
|
||||
};
|
||||
return plugin;
|
||||
};
|
||||
|
||||
export default pluginFactory;
|
||||
50
packages/code-generator/src/plugins/component/rax/jsx.ts
Normal file
50
packages/code-generator/src/plugins/component/rax/jsx.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import {
|
||||
BuilderComponentPlugin,
|
||||
BuilderComponentPluginFactory,
|
||||
ChunkType,
|
||||
FileType,
|
||||
ICodeStruct,
|
||||
IContainerInfo,
|
||||
} from '../../../types';
|
||||
|
||||
import { RAX_CHUNK_NAME } from './const';
|
||||
|
||||
import { createReactNodeGenerator } from '../../../utils/nodeToJSX';
|
||||
|
||||
type PluginConfig = {
|
||||
fileType: string;
|
||||
}
|
||||
|
||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||
const cfg: PluginConfig = {
|
||||
fileType: FileType.JSX,
|
||||
...config,
|
||||
};
|
||||
|
||||
const generator = createReactNodeGenerator();
|
||||
|
||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||
const next: ICodeStruct = {
|
||||
...pre,
|
||||
};
|
||||
|
||||
const ir = next.ir as IContainerInfo;
|
||||
const jsxContent = generator(ir);
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.STRING,
|
||||
fileType: cfg.fileType,
|
||||
name: RAX_CHUNK_NAME.ClassRenderJSX,
|
||||
content: `return ${jsxContent};`,
|
||||
linkAfter: [
|
||||
RAX_CHUNK_NAME.ClassRenderStart,
|
||||
RAX_CHUNK_NAME.ClassRenderPre,
|
||||
],
|
||||
});
|
||||
|
||||
return next;
|
||||
};
|
||||
return plugin;
|
||||
};
|
||||
|
||||
export default pluginFactory;
|
||||
@ -3,13 +3,13 @@ import { IProjectBuilder } from '../types';
|
||||
import { createProjectBuilder } from '../generator/ProjectBuilder';
|
||||
|
||||
import esModule from '../plugins/common/esmodule';
|
||||
import containerClass from '../plugins/component/react/containerClass';
|
||||
import containerInitState from '../plugins/component/react/containerInitState';
|
||||
import containerInjectUtils from '../plugins/component/react/containerInjectUtils';
|
||||
import containerLifeCycle from '../plugins/component/react/containerLifeCycle';
|
||||
import containerMethod from '../plugins/component/react/containerMethod';
|
||||
import jsx from '../plugins/component/react/jsx';
|
||||
import reactCommonDeps from '../plugins/component/react/reactCommonDeps';
|
||||
import containerClass from '../plugins/component/rax/containerClass';
|
||||
import containerInitState from '../plugins/component/rax/containerInitState';
|
||||
import containerInjectUtils from '../plugins/component/rax/containerInjectUtils';
|
||||
import containerLifeCycle from '../plugins/component/rax/containerLifeCycle';
|
||||
import containerMethod from '../plugins/component/rax/containerMethod';
|
||||
import jsx from '../plugins/component/rax/jsx';
|
||||
import commonDeps from '../plugins/component/rax/commonDeps';
|
||||
import css from '../plugins/component/style/css';
|
||||
import constants from '../plugins/project/constants';
|
||||
import i18n from '../plugins/project/i18n';
|
||||
@ -24,7 +24,7 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
|
||||
template: raxApp.template,
|
||||
plugins: {
|
||||
components: [
|
||||
reactCommonDeps(),
|
||||
commonDeps(),
|
||||
esModule({
|
||||
fileType: 'jsx',
|
||||
}),
|
||||
@ -37,7 +37,7 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
|
||||
css(),
|
||||
],
|
||||
pages: [
|
||||
reactCommonDeps(),
|
||||
commonDeps(),
|
||||
esModule({
|
||||
fileType: 'jsx',
|
||||
}),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user