mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-11 18:42:56 +00:00
feat: support UIPaaS-Component code generator solution
This commit is contained in:
parent
82b6a01533
commit
1ca940c880
@ -559,8 +559,8 @@ codealike.json
|
||||
"registry": "https://registry.npm.xxx.com"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alilc/lowcode-code-generator": "^1.0.0-beta.16",
|
||||
"@alilc/lowcode-types": "^1.0.0-beta.21",
|
||||
"@alilc/lowcode-code-generator": "^1.0.0",
|
||||
"@alilc/lowcode-types": "^1.0.0",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -62,10 +62,10 @@ export class ProjectBuilder implements IProjectBuilder {
|
||||
private projectPostProcessors: ProjectPostProcessor[];
|
||||
|
||||
/** 是否处于严格模式 */
|
||||
public readonly inStrictMode: boolean;
|
||||
readonly inStrictMode: boolean;
|
||||
|
||||
/** 一些额外的上下文数据 */
|
||||
public readonly extraContextData: IContextData;
|
||||
readonly extraContextData: IContextData;
|
||||
|
||||
constructor({
|
||||
template,
|
||||
@ -260,7 +260,10 @@ export class ProjectBuilder implements IProjectBuilder {
|
||||
let finalResult = projectRoot;
|
||||
for (const projectPostProcessor of this.projectPostProcessors) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
finalResult = await projectPostProcessor(finalResult, schema, originalSchema);
|
||||
finalResult = await projectPostProcessor(finalResult, schema, originalSchema, {
|
||||
template: this.template,
|
||||
parseResult,
|
||||
});
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
|
||||
@ -32,7 +32,7 @@ import {
|
||||
import { SUPPORT_SCHEMA_VERSION_LIST } from '../const';
|
||||
|
||||
import { getErrorMessage } from '../utils/errors';
|
||||
import { handleSubNodes } from '../utils/schema';
|
||||
import { handleSubNodes, isValidContainerType } from '../utils/schema';
|
||||
import { uniqueArray } from '../utils/common';
|
||||
import { componentAnalyzer } from '../analyzer/componentAnalyzer';
|
||||
import { ensureValidClassName } from '../utils/validate';
|
||||
@ -141,7 +141,7 @@ export class SchemaParser implements ISchemaParser {
|
||||
if (schema.componentsTree.length > 0) {
|
||||
const firstRoot: ContainerSchema = schema.componentsTree[0] as ContainerSchema;
|
||||
|
||||
if (!('fileName' in firstRoot) || !firstRoot.fileName) {
|
||||
if (!firstRoot.fileName && !isValidContainerType(firstRoot)) {
|
||||
// 整个 schema 描述一个容器,且无根节点定义
|
||||
const container: IContainerInfo = {
|
||||
...firstRoot,
|
||||
@ -259,8 +259,7 @@ export class SchemaParser implements ISchemaParser {
|
||||
utils = schema.utils;
|
||||
utilsDeps = schema.utils
|
||||
.filter(
|
||||
(u): u is { name: string; type: 'npm' | 'tnpm'; content: NpmInfo } =>
|
||||
u.type !== 'function',
|
||||
(u): u is { name: string; type: 'npm' | 'tnpm'; content: NpmInfo } => u.type !== 'function',
|
||||
)
|
||||
.map(
|
||||
(u): IExternalDependency => ({
|
||||
|
||||
@ -9,7 +9,7 @@ const PARSERS = ['css', 'scss', 'less', 'json', 'html', 'vue'];
|
||||
|
||||
export interface ProcessorConfig {
|
||||
customFileTypeParser: Record<string, string>;
|
||||
plugins?: Array<prettier.Plugin>;
|
||||
plugins?: prettier.Plugin[];
|
||||
}
|
||||
|
||||
const factory: PostProcessorFactory<ProcessorConfig> = (config?: ProcessorConfig) => {
|
||||
@ -33,6 +33,8 @@ const factory: PostProcessorFactory<ProcessorConfig> = (config?: ProcessorConfig
|
||||
return prettier.format(content, {
|
||||
parser,
|
||||
plugins: [parserBabel, parserPostCss, parserHtml, ...(cfg.plugins || [])],
|
||||
singleQuote: true,
|
||||
jsxSingleQuote: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -170,11 +170,17 @@ export interface IProjectBuilder {
|
||||
/** 项目级别的前置处理器 */
|
||||
export type ProjectPreProcessor = (schema: ProjectSchema) => Promise<ProjectSchema> | ProjectSchema;
|
||||
|
||||
export interface ProjectPostProcessorOptions {
|
||||
parseResult?: IParseResult;
|
||||
template?: IProjectTemplate;
|
||||
}
|
||||
|
||||
/** 项目级别的后置处理器 */
|
||||
export type ProjectPostProcessor = (
|
||||
result: ResultDir,
|
||||
schema: ProjectSchema,
|
||||
originalSchema: ProjectSchema | string,
|
||||
options: ProjectPostProcessorOptions,
|
||||
) => Promise<ResultDir> | ResultDir;
|
||||
|
||||
/** 模块级别的后置处理器的工厂方法 */
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import changeCase from 'change-case';
|
||||
import type { IProjectInfo } from '../types/intermediate';
|
||||
|
||||
export type DataSourceDependenciesConfig = {
|
||||
export interface DataSourceDependenciesConfig {
|
||||
/** 数据源引擎的版本 */
|
||||
engineVersion?: string;
|
||||
/** 数据源引擎的包名 */
|
||||
@ -14,7 +14,7 @@ export type DataSourceDependenciesConfig = {
|
||||
handlersPackages?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export function buildDataSourceDependencies(
|
||||
ir: IProjectInfo,
|
||||
@ -22,13 +22,13 @@ export function buildDataSourceDependencies(
|
||||
): Record<string, string> {
|
||||
return {
|
||||
// 数据源引擎的依赖包
|
||||
[cfg.enginePackage || '@alilc/lowcode-datasource-engine']: cfg.engineVersion || 'latest',
|
||||
[cfg.enginePackage || '@alilc/lowcode-datasource-engine']: cfg.engineVersion || '^1.0.0',
|
||||
|
||||
// 各种数据源的 handlers 的依赖包
|
||||
...(ir.dataSourcesTypes || []).reduce(
|
||||
(acc, dsType) => ({
|
||||
...acc,
|
||||
[getDataSourceHandlerPackageName(dsType)]: cfg.handlersVersion?.[dsType] || 'latest',
|
||||
[getDataSourceHandlerPackageName(dsType)]: cfg.handlersVersion?.[dsType] || '^1.0.0',
|
||||
}),
|
||||
{},
|
||||
),
|
||||
|
||||
@ -11,6 +11,7 @@ import * as schema from './schema';
|
||||
import * as version from './version';
|
||||
import * as scope from './Scope';
|
||||
import * as expressionParser from './expressionParser';
|
||||
import * as dataSource from './dataSource';
|
||||
|
||||
export {
|
||||
common,
|
||||
@ -25,4 +26,5 @@ export {
|
||||
version,
|
||||
scope,
|
||||
expressionParser,
|
||||
dataSource,
|
||||
};
|
||||
|
||||
@ -182,7 +182,7 @@ function generateSimpleNode(
|
||||
function linkPieces(pieces: CodePiece[]): string {
|
||||
const tagsPieces = pieces.filter((p) => p.type === PIECE_TYPE.TAG);
|
||||
if (tagsPieces.length !== 1) {
|
||||
throw new CodeGeneratorError('One node only need one tag define');
|
||||
throw new CodeGeneratorError('Only one tag definition required', tagsPieces);
|
||||
}
|
||||
const tagName = tagsPieces[0].value;
|
||||
|
||||
@ -270,8 +270,7 @@ export function generateReactLoopCtrl(
|
||||
const loopDataExpr = pipe(
|
||||
nodeItem.loop,
|
||||
// 将 JSExpression 转换为 JS 表达式代码:
|
||||
(expr) =>
|
||||
generateCompositeType(expr, scope, {
|
||||
(expr) => generateCompositeType(expr, scope, {
|
||||
handlers: config?.handlers,
|
||||
tolerateEvalErrors: false, // 这个内部不需要包 try catch, 下面会统一加的
|
||||
}),
|
||||
@ -391,8 +390,7 @@ export function createNodeGenerator(cfg: NodeGeneratorConfig = {}): NodeGenerato
|
||||
return `{${valueStr}}`;
|
||||
};
|
||||
|
||||
return (nodeItem: NodeDataType, scope: IScope) =>
|
||||
unwrapJsExprQuoteInJsx(generateNode(nodeItem, scope));
|
||||
return (nodeItem: NodeDataType, scope: IScope) => unwrapJsExprQuoteInJsx(generateNode(nodeItem, scope));
|
||||
}
|
||||
|
||||
const defaultReactGeneratorConfig: NodeGeneratorConfig = {
|
||||
|
||||
@ -138,3 +138,11 @@ export function handleSubNodes<T>(
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export function isValidContainerType(schema: NodeSchema) {
|
||||
return [
|
||||
'Page',
|
||||
'Component',
|
||||
'Block',
|
||||
].includes(schema.componentName);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user