From 574e348c1e8fa160129d6b90e3a19e2bebb2b301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 2 Feb 2023 20:12:37 +0800 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20esModule#pre?= =?UTF-8?q?ferClassProperty=20=E9=85=8D=E7=BD=AE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/generator/ProjectBuilder.ts | 19 ++++++++++++ .../src/plugins/common/esmodule.ts | 4 ++- .../component/react/containerInjectUtils.ts | 29 ++++++++++++++----- .../src/postprocessor/prettier/index.ts | 2 ++ modules/code-generator/src/types/core.ts | 3 ++ .../code-generator/src/types/intermediate.ts | 1 + 6 files changed, 50 insertions(+), 8 deletions(-) diff --git a/modules/code-generator/src/generator/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index 819f37c5c..040136057 100644 --- a/modules/code-generator/src/generator/ProjectBuilder.ts +++ b/modules/code-generator/src/generator/ProjectBuilder.ts @@ -24,22 +24,31 @@ interface IModuleInfo { } export interface ProjectBuilderInitOptions { + /** 项目模板 */ template: IProjectTemplate; + /** 项目插件 */ plugins: IProjectPlugins; + /** 模块后置处理器 */ postProcessors: PostProcessor[]; + /** Schema 解析器 */ schemaParser?: ISchemaParser; + /** 项目级别的前置处理器 */ projectPreProcessors?: ProjectPreProcessor[]; + /** 项目级别的后置处理器 */ projectPostProcessors?: ProjectPostProcessor[]; + /** 是否处于严格模式 */ inStrictMode?: boolean; + /** 一些额外的上下文数据 */ extraContextData?: Record; + /** * Hook which is used to customize original options, we can reorder/add/remove plugins/processors * of the existing solution. @@ -264,6 +273,16 @@ export class ProjectBuilder implements IProjectBuilder { } // TODO: 更多 slots 的处理??是不是可以考虑把 template 中所有的 slots 都处理下? + // const whitelistSlotNames = [ + // 'router', + // 'entry', + // 'appConfig', + // 'buildConfig', + // 'router', + // ]; + // Object.keys(this.template.slots).forEach((slotName: string) => { + + // }); // Post Process const isSingleComponent = parseResult?.project?.projectRemark?.isSingleComponent; diff --git a/modules/code-generator/src/plugins/common/esmodule.ts b/modules/code-generator/src/plugins/common/esmodule.ts index 04dfd1ce2..09c6aec59 100644 --- a/modules/code-generator/src/plugins/common/esmodule.ts +++ b/modules/code-generator/src/plugins/common/esmodule.ts @@ -443,6 +443,7 @@ function buildPackageImport( export interface PluginConfig { fileType?: string; // 导出的文件类型 useAliasName?: boolean; // 是否使用 componentName 重命名组件 identifier + filter?: (deps: IDependency[]) => IDependency[]; // 支持过滤能力 } const pluginFactory: BuilderComponentPluginFactory = (config?: PluginConfig) => { @@ -460,7 +461,8 @@ const pluginFactory: BuilderComponentPluginFactory = (config?: Plu const ir = next.ir as IWithDependency; if (ir && ir.deps && ir.deps.length > 0) { - const packs = groupDepsByPack(ir.deps); + const deps = cfg.filter ? cfg.filter(ir.deps) : ir.deps; + const packs = groupDepsByPack(deps); Object.keys(packs).forEach((pkg) => { const chunks = buildPackageImport(pkg, packs[pkg], cfg.fileType, cfg.useAliasName); diff --git a/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts b/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts index 33fc8c28d..c5c566e17 100644 --- a/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts +++ b/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts @@ -16,6 +16,9 @@ import { export interface PluginConfig { fileType: string; + + /** prefer using class property to define utils */ + preferClassProperty?: boolean; } const pluginFactory: BuilderComponentPluginFactory = (config?) => { @@ -57,13 +60,25 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport], }); - 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], - }); + if (cfg.preferClassProperty) { + // mode: class property + next.chunks.push({ + type: ChunkType.STRING, + fileType: cfg.fileType, + name: CLASS_DEFINE_CHUNK_NAME.InsVar, + content: 'utils = utils;', + linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsVar]], + }); + } else { + // mode: assign in constructor + 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], + }); + } if (useRef) { next.chunks.push({ diff --git a/modules/code-generator/src/postprocessor/prettier/index.ts b/modules/code-generator/src/postprocessor/prettier/index.ts index d4e61e3c0..b4c3188f3 100644 --- a/modules/code-generator/src/postprocessor/prettier/index.ts +++ b/modules/code-generator/src/postprocessor/prettier/index.ts @@ -22,6 +22,8 @@ const factory: PostProcessorFactory = (config?: ProcessorConfig let parser: prettier.BuiltInParserName | any; if (fileType === 'js' || fileType === 'jsx') { parser = 'babel'; + } else if (fileType === 'json') { + parser = 'json-stringify'; } else if (PARSERS.indexOf(fileType) >= 0) { parser = fileType; } else if (cfg.customFileTypeParser[fileType]) { diff --git a/modules/code-generator/src/types/core.ts b/modules/code-generator/src/types/core.ts index 39e4c32ba..30c86a7e9 100644 --- a/modules/code-generator/src/types/core.ts +++ b/modules/code-generator/src/types/core.ts @@ -22,8 +22,10 @@ export enum FileType { LESS = 'less', HTML = 'html', JS = 'js', + MJS = 'mjs', JSX = 'jsx', TS = 'ts', + MTS = 'mts', TSX = 'tsx', JSON = 'json', MD = 'md', @@ -168,6 +170,7 @@ export interface IProjectBuilderOptions { * - expr: 求值的表达式 */ evalErrorsHandler?: string; + /** * Hook which is used to customize original options, we can reorder/add/remove plugins/processors * of the existing solution. diff --git a/modules/code-generator/src/types/intermediate.ts b/modules/code-generator/src/types/intermediate.ts index 30d6c4f7f..7cba0bd44 100644 --- a/modules/code-generator/src/types/intermediate.ts +++ b/modules/code-generator/src/types/intermediate.ts @@ -42,6 +42,7 @@ export interface IRouterInfo extends IWithDependency { * project's remarks */ export interface ProjectRemark { + /** if current project only contain one container which type is `Component` */ isSingleComponent?: boolean; } From da7ff590661823100eff75c68b43c741bab6f5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 8 Feb 2023 14:49:52 +0800 Subject: [PATCH 02/15] =?UTF-8?q?fix:=20=E5=85=BC=E5=AE=B9=20isJSExpressio?= =?UTF-8?q?n=20=E4=B8=8D=E5=8C=85=E5=90=AB=E5=87=BD=E6=95=B0=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/rax/containerLifeCycle.ts | 2 ++ .../src/plugins/component/rax/jsx.ts | 3 +-- .../react/containerInjectDataSourceEngine.ts | 8 +++++--- .../code-generator/src/plugins/project/i18n.ts | 3 ++- modules/code-generator/src/utils/common.ts | 5 +++++ .../code-generator/src/utils/compositeType.ts | 3 ++- modules/code-generator/src/utils/dataSource.ts | 4 ++++ .../code-generator/src/utils/jsExpression.ts | 18 ++++++++++++------ modules/code-generator/src/utils/schema.ts | 2 ++ 9 files changed, 35 insertions(+), 13 deletions(-) diff --git a/modules/code-generator/src/plugins/component/rax/containerLifeCycle.ts b/modules/code-generator/src/plugins/component/rax/containerLifeCycle.ts index f928c3995..bbee6367f 100644 --- a/modules/code-generator/src/plugins/component/rax/containerLifeCycle.ts +++ b/modules/code-generator/src/plugins/component/rax/containerLifeCycle.ts @@ -13,6 +13,7 @@ import { IContainerInfo, } from '../../../types'; import { debug } from '../../../utils/debug'; +import { isJSExpressionFn } from '../../../utils/common'; export interface PluginConfig { fileType: string; @@ -49,6 +50,7 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => // 过滤掉非法数据(有些场景下会误传入空字符串或 null) if ( !isJSFunction(lifeCycles[lifeCycleName]) && + !isJSExpressionFn(lifeCycles[lifeCycleName]) && !isJSExpression(lifeCycles[lifeCycleName]) ) { return; diff --git a/modules/code-generator/src/plugins/component/rax/jsx.ts b/modules/code-generator/src/plugins/component/rax/jsx.ts index 98c80a492..ddae619cd 100644 --- a/modules/code-generator/src/plugins/component/rax/jsx.ts +++ b/modules/code-generator/src/plugins/component/rax/jsx.ts @@ -75,8 +75,7 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => // 注意:这里其实隐含了一个假设:schema 中的 componentName 应该是一个有效的 JS 标识符,而且是大写字母打头的 // FIXME: 为了快速修复临时加的逻辑,需要用 pre-process 的方式替代处理。 - const mapComponentNameToAliasOrKeepIt = (componentName: string) => - componentsNameAliasMap.get(componentName) || componentName; + const mapComponentNameToAliasOrKeepIt = (componentName: string) => componentsNameAliasMap.get(componentName) || componentName; // 然后过滤掉所有的别名 chunks next.chunks = next.chunks.filter((chunk) => !isImportAliasDefineChunk(chunk)); diff --git a/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts b/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts index bc5fa54ba..c4385017b 100644 --- a/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts +++ b/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts @@ -29,6 +29,7 @@ import { generateCompositeType } from '../../../utils/compositeType'; import { parseExpressionConvertThis2Context } from '../../../utils/expressionParser'; import { isValidContainerType } from '../../../utils/schema'; import { REACT_CHUNK_NAME } from './const'; +import { isJSExpressionFn } from '../../../utils/common'; export interface PluginConfig { fileType?: string; @@ -37,6 +38,7 @@ export interface PluginConfig { * 数据源配置 */ datasourceConfig?: { + /** 数据源引擎的版本 */ engineVersion?: string; @@ -188,15 +190,15 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => export default pluginFactory; function wrapAsFunction(value: IPublicTypeCompositeValue, scope: IScope): IPublicTypeCompositeValue { - if (isJSExpression(value) || isJSFunction(value)) { + if (isJSExpression(value) || isJSFunction(value) || isJSExpressionFn(value)) { return { type: 'JSExpression', - value: `function(){ return ((${value.value}))}`, + value: `function(){ return ((${value.value}))}.bind(this)`, }; } return { type: 'JSExpression', - value: `function(){return((${generateCompositeType(value, scope)}))}`, + value: `function(){return((${generateCompositeType(value, scope)}))}.bind(this)`, }; } diff --git a/modules/code-generator/src/plugins/project/i18n.ts b/modules/code-generator/src/plugins/project/i18n.ts index ae568f972..d1d32ff32 100644 --- a/modules/code-generator/src/plugins/project/i18n.ts +++ b/modules/code-generator/src/plugins/project/i18n.ts @@ -25,7 +25,8 @@ const pluginFactory: BuilderComponentPluginFactory = () => { content: ` const i18nConfig = ${i18nStr}; - let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN'; + // let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN'; + let locale = 'zh-CN'; const getLocale = () => locale; diff --git a/modules/code-generator/src/utils/common.ts b/modules/code-generator/src/utils/common.ts index cfba393e9..d822fdf81 100644 --- a/modules/code-generator/src/utils/common.ts +++ b/modules/code-generator/src/utils/common.ts @@ -1,3 +1,4 @@ +import type { IPublicTypeJSExpression, IPublicTypeJSFunction } from '@alilc/lowcode-types'; import changeCase from 'change-case'; import short from 'short-uuid'; @@ -39,3 +40,7 @@ export function getStaticExprValue(expr: string): T { // eslint-disable-next-line no-new-func return Function(`"use strict";return (${expr})`)(); } + +export function isJSExpressionFn(data: any): data is IPublicTypeJSFunction { + return data?.type === 'JSExpression' && data?.extType === 'function'; +} \ No newline at end of file diff --git a/modules/code-generator/src/utils/compositeType.ts b/modules/code-generator/src/utils/compositeType.ts index 2e09e2da0..0dd612641 100644 --- a/modules/code-generator/src/utils/compositeType.ts +++ b/modules/code-generator/src/utils/compositeType.ts @@ -16,6 +16,7 @@ import { generateExpression, generateFunction } from './jsExpression'; import { generateJsSlot } from './jsSlot'; import { executeFunctionStack } from './aopHelper'; import { parseExpressionGetKeywords } from './expressionParser'; +import { isJSExpressionFn } from './common'; interface ILegaoVariable { type: 'variable'; @@ -159,7 +160,7 @@ function generateUnknownType( return generateExpression(value, scope); } - if (isJSFunction(value)) { + if (isJSFunction(value) || isJSExpressionFn(value)) { if (options.handlers?.function) { return executeFunctionStack(value, scope, options.handlers.function, genFunction, options); } diff --git a/modules/code-generator/src/utils/dataSource.ts b/modules/code-generator/src/utils/dataSource.ts index cd1035162..5595b8def 100644 --- a/modules/code-generator/src/utils/dataSource.ts +++ b/modules/code-generator/src/utils/dataSource.ts @@ -2,14 +2,18 @@ import changeCase from 'change-case'; import type { IProjectInfo } from '../types/intermediate'; export interface DataSourceDependenciesConfig { + /** 数据源引擎的版本 */ engineVersion?: string; + /** 数据源引擎的包名 */ enginePackage?: string; + /** 数据源 handlers 的版本 */ handlersVersion?: { [key: string]: string; }; + /** 数据源 handlers 的包名 */ handlersPackages?: { [key: string]: string; diff --git a/modules/code-generator/src/utils/jsExpression.ts b/modules/code-generator/src/utils/jsExpression.ts index 1162d0820..40099b1e2 100644 --- a/modules/code-generator/src/utils/jsExpression.ts +++ b/modules/code-generator/src/utils/jsExpression.ts @@ -5,6 +5,7 @@ import * as t from '@babel/types'; import { IPublicTypeJSExpression, IPublicTypeJSFunction, isJSExpression, isJSFunction } from '@alilc/lowcode-types'; import { CodeGeneratorError, IScope } from '../types'; import { transformExpressionLocalRef, ParseError } from './expressionParser'; +import { isJSExpressionFn } from './common'; function parseFunction(content: string): t.FunctionExpression | null { try { @@ -79,7 +80,7 @@ function getBodyStatements(content: string) { } export function isJsCode(value: unknown): boolean { - return isJSExpression(value) || isJSFunction(value); + return isJSExpressionFn(value) || isJSFunction(value); } export function generateExpression(value: any, scope: IScope): string { @@ -96,6 +97,10 @@ export function generateExpression(value: any, scope: IScope): string { throw new CodeGeneratorError('Not a JSExpression'); } +function getFunctionSource(cfg: IPublicTypeJSFunction): string { + return cfg.source || cfg.value || cfg.compiled; +} + export function generateFunction( value: any, config: { @@ -114,19 +119,20 @@ export function generateFunction( ) { if (isJsCode(value)) { const functionCfg = value as IPublicTypeJSFunction; + const functionSource = getFunctionSource(functionCfg); if (config.isMember) { - return transformFuncExpr2MethodMember(config.name || '', functionCfg.value); + return transformFuncExpr2MethodMember(config.name || '', functionSource); } if (config.isBlock) { - return getBodyStatements(functionCfg.value); + return getBodyStatements(functionSource); } if (config.isArrow) { - return getArrowFunction(functionCfg.value); + return getArrowFunction(functionSource); } if (config.isBindExpr) { - return `(${functionCfg.value}).bind(this)`; + return `(${functionSource}).bind(this)`; } - return functionCfg.value; + return functionSource; } throw new CodeGeneratorError('Not a JSFunction or JSExpression'); diff --git a/modules/code-generator/src/utils/schema.ts b/modules/code-generator/src/utils/schema.ts index 509977277..0b8295aac 100644 --- a/modules/code-generator/src/utils/schema.ts +++ b/modules/code-generator/src/utils/schema.ts @@ -13,6 +13,7 @@ import { isJSFunction, } from '@alilc/lowcode-types'; import { CodeGeneratorError } from '../types/error'; +import { isJSExpressionFn } from './common'; export function isContainerSchema(x: any): x is IPublicTypeContainerSchema { return ( @@ -128,6 +129,7 @@ export function handleSubNodes( // IPublicTypeCompositeObject if ( !isJSExpression(value) && + !isJSExpressionFn(value) && !isJSFunction(value) && typeof value === 'object' && value !== null From 62289e5995fe151d80aea2dfa5073b8d4aa9a578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 8 Feb 2023 16:38:37 +0800 Subject: [PATCH 03/15] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20lifeCycles=20?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E6=AD=A3=E5=B8=B8=E5=87=BA=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/plugins/component/react/containerLifeCycle.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/code-generator/src/plugins/component/react/containerLifeCycle.ts b/modules/code-generator/src/plugins/component/react/containerLifeCycle.ts index 8caa9b105..75dcada63 100644 --- a/modules/code-generator/src/plugins/component/react/containerLifeCycle.ts +++ b/modules/code-generator/src/plugins/component/react/containerLifeCycle.ts @@ -13,6 +13,7 @@ import { IContainerInfo, } from '../../../types'; import { isJSFunction, isJSExpression } from '@alilc/lowcode-types'; +import { isJSExpressionFn } from '../../../utils/common'; export interface PluginConfig { fileType: string; @@ -41,6 +42,7 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => // 过滤掉非法数据(有些场景下会误传入空字符串或 null) if ( !isJSFunction(lifeCycles[lifeCycleName]) && + !isJSExpressionFn(lifeCycles[lifeCycleName]) && !isJSExpression(lifeCycles[lifeCycleName]) ) { return null; From df8a7507467e8ceef1d9fa8db437dd202239c6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 8 Feb 2023 19:50:51 +0800 Subject: [PATCH 04/15] =?UTF-8?q?fix:=20=E5=85=BC=E5=AE=B9=E6=9F=90?= =?UTF-8?q?=E4=BA=9B=E8=80=81=E7=9A=84=E9=80=9A=E8=BF=87=20JSE=20=E6=9D=A5?= =?UTF-8?q?=E8=A1=A8=E8=BE=BE=E5=87=BD=E6=95=B0=E7=9A=84=E5=9C=BA=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/code-generator/src/utils/jsExpression.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/code-generator/src/utils/jsExpression.ts b/modules/code-generator/src/utils/jsExpression.ts index 40099b1e2..25c7f47fd 100644 --- a/modules/code-generator/src/utils/jsExpression.ts +++ b/modules/code-generator/src/utils/jsExpression.ts @@ -135,5 +135,9 @@ export function generateFunction( return functionSource; } + if (isJSExpression(value)) { + return value.value; + } + throw new CodeGeneratorError('Not a JSFunction or JSExpression'); } From 37e07bb238396942e11e16719859bc60da34f166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 10 Feb 2023 22:10:17 +0800 Subject: [PATCH 05/15] fix: replace the top-level context only --- modules/code-generator/src/utils/expressionParser.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/code-generator/src/utils/expressionParser.ts b/modules/code-generator/src/utils/expressionParser.ts index cbc950bbc..fc1fe4195 100644 --- a/modules/code-generator/src/utils/expressionParser.ts +++ b/modules/code-generator/src/utils/expressionParser.ts @@ -271,7 +271,7 @@ export function parseExpressionConvertThis2Context( const localVariablesSet = new Set(localVariables); - let thisScopeLevel = CROSS_THIS_SCOPE_TYPE_NODE[exprAst.type] ? -1 : 0; + let thisScopeLevel = -1; traverse(fileAst, { enter(path) { if (CROSS_THIS_SCOPE_TYPE_NODE[path.node.type]) { @@ -303,7 +303,7 @@ export function parseExpressionConvertThis2Context( } // 替换 this (只在顶层替换) - if (thisScopeLevel <= 0) { + if (thisScopeLevel === 0) { obj.replaceWith(t.identifier(contextName)); } }, @@ -317,7 +317,7 @@ export function parseExpressionConvertThis2Context( return; } - if (thisScopeLevel <= 0) { + if (thisScopeLevel === 0) { path.replaceWith(t.identifier(contextName)); } }, From 76f5ee4cf80552efac75cc62707611e94b934148 Mon Sep 17 00:00:00 2001 From: eternalsky Date: Mon, 13 Feb 2023 10:09:10 +0800 Subject: [PATCH 06/15] feat: console the expression error --- modules/code-generator/src/generator/ProjectBuilder.ts | 2 +- modules/code-generator/src/utils/jsExpression.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/code-generator/src/generator/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index 040136057..6db81b0d7 100644 --- a/modules/code-generator/src/generator/ProjectBuilder.ts +++ b/modules/code-generator/src/generator/ProjectBuilder.ts @@ -328,7 +328,7 @@ export class ProjectBuilder implements IProjectBuilder { // template: this.template, inStrictMode: this.inStrictMode, tolerateEvalErrors: true, - evalErrorsHandler: '', + evalErrorsHandler: 'console.error(error)', ...this.extraContextData, ...extraContextData, }, diff --git a/modules/code-generator/src/utils/jsExpression.ts b/modules/code-generator/src/utils/jsExpression.ts index 25c7f47fd..08d2fafd8 100644 --- a/modules/code-generator/src/utils/jsExpression.ts +++ b/modules/code-generator/src/utils/jsExpression.ts @@ -79,7 +79,12 @@ function getBodyStatements(content: string) { throw new Error('Can not find Function Statement'); } -export function isJsCode(value: unknown): boolean { +/** + * 是否是广义上的 JSFunction + * @param value + * @returns + */ +export function isBroadJSFunction(value: unknown): boolean { return isJSExpressionFn(value) || isJSFunction(value); } @@ -117,7 +122,7 @@ export function generateFunction( isBindExpr: false, }, ) { - if (isJsCode(value)) { + if (isBroadJSFunction(value)) { const functionCfg = value as IPublicTypeJSFunction; const functionSource = getFunctionSource(functionCfg); if (config.isMember) { From 20b34b74a257497a6b766796076cc88b045af49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 14 Feb 2023 17:49:58 +0800 Subject: [PATCH 07/15] feat: handle extra slots --- modules/code-generator/src/const/index.ts | 21 +++++++++++++ .../src/generator/ProjectBuilder.ts | 30 ++++++++++++------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/modules/code-generator/src/const/index.ts b/modules/code-generator/src/const/index.ts index 103d912db..24449ca42 100644 --- a/modules/code-generator/src/const/index.ts +++ b/modules/code-generator/src/const/index.ts @@ -8,5 +8,26 @@ export const CONTAINER_TYPE = { export const SUPPORT_SCHEMA_VERSION_LIST = ['0.0.1', '1.0.0']; +// built-in slot names which have been handled in ProjectBuilder +export const BUILTIN_SLOT_NAMES = [ + 'pages', + 'components', + 'router', + 'entry', + 'appConfig', + 'buildConfig', + 'constants', + 'utils', + 'i18n', + 'globalStyle', + 'htmlEntry', + 'packageJSON', + 'demo', +]; + +export const isBuiltinSlotName = function (name: string) { + return BUILTIN_SLOT_NAMES.includes(name); +}; + export * from './file'; export * from './generator'; diff --git a/modules/code-generator/src/generator/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index 040136057..f3fb5fc1c 100644 --- a/modules/code-generator/src/generator/ProjectBuilder.ts +++ b/modules/code-generator/src/generator/ProjectBuilder.ts @@ -16,6 +16,7 @@ import { createResultDir, addDirectory, addFile } from '../utils/resultHelper'; import { createModuleBuilder } from './ModuleBuilder'; import { ProjectPreProcessor, ProjectPostProcessor, IContextData } from '../types/core'; import { CodeGeneratorError } from '../types/error'; +import { isBuiltinSlotName } from '../const'; interface IModuleInfo { moduleName?: string; @@ -272,17 +273,8 @@ export class ProjectBuilder implements IProjectBuilder { }); } - // TODO: 更多 slots 的处理??是不是可以考虑把 template 中所有的 slots 都处理下? - // const whitelistSlotNames = [ - // 'router', - // 'entry', - // 'appConfig', - // 'buildConfig', - // 'router', - // ]; - // Object.keys(this.template.slots).forEach((slotName: string) => { - - // }); + // handle extra slots + await this.generateExtraSlots(builders, parseResult, buildResult); // Post Process const isSingleComponent = parseResult?.project?.projectRemark?.isSingleComponent; @@ -339,6 +331,22 @@ export class ProjectBuilder implements IProjectBuilder { return builders; } + + private async generateExtraSlots( + builders: Record, + parseResult: IParseResult, + buildResult: IModuleInfo[], + ) { + for (const slotName in this.template.slots) { + if (!isBuiltinSlotName(slotName)) { + const { files } = await builders[slotName].generateModule(parseResult); + buildResult.push({ + path: this.template.slots[slotName].path, + files, + }); + } + } + } } export function createProjectBuilder(initOptions: ProjectBuilderInitOptions): IProjectBuilder { From b3a29913d2b3f6b26ce572c23b3b26e1ad8bf425 Mon Sep 17 00:00:00 2001 From: eternalsky Date: Mon, 27 Feb 2023 09:53:32 +0800 Subject: [PATCH 08/15] =?UTF-8?q?feat:=20=E7=9B=B8=E5=AF=B9=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E7=94=9F=E6=88=90=E5=8A=A8=E6=80=81=E5=8C=96=20&=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E9=83=A8=E5=88=86=E6=8F=92=E4=BB=B6=20ts=20?= =?UTF-8?q?=E5=A3=B0=E6=98=8E=E9=97=AE=E9=A2=98=20(#1618)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: console the expression error * feat: 相对路径生成动态化 * chore: 暂时恢复一些变化,用于更新测试 * chore: 修改错误的 schema * fix: 修复错误的 schema & 更新数据快照 --- modules/code-generator/example-schema.json | 8 ++-- modules/code-generator/example-schema.json5 | 8 ++-- .../src/generator/ProjectBuilder.ts | 3 +- modules/code-generator/src/index.ts | 3 +- .../component/react/containerInitState.ts | 4 +- .../component/react/containerInjectI18n.ts | 4 +- .../component/react/containerInjectUtils.ts | 22 ++-------- .../src/plugins/project/i18n.ts | 3 +- .../src/utils/expressionParser.ts | 6 +-- modules/code-generator/src/utils/index.ts | 2 + .../code-generator/src/utils/pathHelper.ts | 41 +++++++++++++++++++ .../demo-project/src/pages/Home/index.jsx | 2 - .../demo1/expected/demo-project/package.json | 13 ++++-- .../demo-project/src/pages/Test/index.jsx | 14 +++---- .../test-cases/react-app/demo1/schema.json5 | 2 +- .../expected/demo-project/package.json | 13 ++++-- .../demo-project/src/pages/Aaaa/index.jsx | 4 +- .../demo2/expected/demo-project/package.json | 13 ++++-- .../test-cases/react-app/demo2/schema.json5 | 2 +- .../demo3/expected/demo-project/package.json | 13 ++++-- .../demo4/expected/demo-project/package.json | 13 ++++-- .../demo-project/src/pages/Test/index.jsx | 4 +- .../demo5/expected/demo-project/package.json | 13 ++++-- .../expected/demo-project/package.json | 13 ++++-- .../demo-project/src/pages/Test/index.jsx | 14 +++---- .../demo6-literal-condition/schema.json5 | 8 ++-- .../expected/demo-project/package.json | 13 ++++-- .../demo-project/src/pages/Test/index.jsx | 2 + .../expected/demo-project/package.json | 13 ++++-- .../demo-project/src/pages/Example/index.jsx | 4 +- .../expected/demo-project/package.json | 13 ++++-- .../demo-project/src/pages/$/index.jsx | 4 +- .../expected/demo-project/package.json | 13 ++++-- .../demo-project/src/pages/Test/index.jsx | 2 - .../expected/demo-project/package.json | 13 ++++-- .../demo-project/src/pages/Test/index.jsx | 3 -- .../demo1/expected/demo-project/package.json | 13 ++++-- .../__snapshots__/prettier.test.ts.snap | 7 +++- 38 files changed, 231 insertions(+), 114 deletions(-) create mode 100644 modules/code-generator/src/utils/pathHelper.ts diff --git a/modules/code-generator/example-schema.json b/modules/code-generator/example-schema.json index aaf3a3e0d..304cf2927 100644 --- a/modules/code-generator/example-schema.json +++ b/modules/code-generator/example-schema.json @@ -71,7 +71,7 @@ }, "lifeCycles": { "componentDidMount": { - "type": "JSExpression", + "type": "JSFunction", "value": "function() { console.log('componentDidMount'); }" } }, @@ -91,7 +91,7 @@ "isSync": true }, "dataHandler": { - "type": "JSExpression", + "type": "JSFunction", "value": "function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data;\n}" } }, @@ -105,13 +105,13 @@ "isSync": true }, "dataHandler": { - "type": "JSExpression", + "type": "JSFunction", "value": "function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data.result;\n}" } } ], "dataHandler": { - "type": "JSExpression", + "type": "JSFunction", "value": "function (dataMap) {\n console.info(\"All datasources loaded:\", dataMap);\n}" } }, diff --git a/modules/code-generator/example-schema.json5 b/modules/code-generator/example-schema.json5 index f71096fc4..13fa019b4 100644 --- a/modules/code-generator/example-schema.json5 +++ b/modules/code-generator/example-schema.json5 @@ -71,7 +71,7 @@ }, lifeCycles: { componentDidMount: { - type: 'JSExpression', + type: 'JSFunction', value: "function() { console.log('componentDidMount'); }", }, }, @@ -91,7 +91,7 @@ isSync: true, }, dataHandler: { - type: 'JSExpression', + type: 'JSFunction', value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data;\n}', }, }, @@ -105,13 +105,13 @@ isSync: true, }, dataHandler: { - type: 'JSExpression', + type: 'JSFunction', value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data.result;\n}', }, }, ], dataHandler: { - type: 'JSExpression', + type: 'JSFunction', value: 'function (dataMap) {\n console.info("All datasources loaded:", dataMap);\n}', }, }, diff --git a/modules/code-generator/src/generator/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index 6db81b0d7..f7262777c 100644 --- a/modules/code-generator/src/generator/ProjectBuilder.ts +++ b/modules/code-generator/src/generator/ProjectBuilder.ts @@ -135,6 +135,7 @@ export class ProjectBuilder implements IProjectBuilder { const builders = this.createModuleBuilders({ extraContextData: { projectRemark: parseResult?.project?.projectRemark, + template: this.template, }, }); // Generator Code module @@ -328,7 +329,7 @@ export class ProjectBuilder implements IProjectBuilder { // template: this.template, inStrictMode: this.inStrictMode, tolerateEvalErrors: true, - evalErrorsHandler: 'console.error(error)', + evalErrorsHandler: '', ...this.extraContextData, ...extraContextData, }, diff --git a/modules/code-generator/src/index.ts b/modules/code-generator/src/index.ts index 7cf861e6f..742b2e6a8 100644 --- a/modules/code-generator/src/index.ts +++ b/modules/code-generator/src/index.ts @@ -1,6 +1,6 @@ /** * 低代码引擎的出码模块,负责将编排产出的 Schema 转换成实际可执行的代码。 - * 注意:为了保持 API 的稳定性, 这里所有导出的 API 均要显式命名方式导出 + * 注意:为了保持 API 的稳定性,这里所有导出的 API 均要显式命名方式导出 * (即用 export { xxx } from 'xx' 的方式,不要直接 export * from 'xxx') * 而且所有导出的 API 务必在 tests/public 中编写单元测试 */ @@ -51,6 +51,7 @@ export default { }, plugins: { common: { + /** * 处理 ES Module * @deprecated please use esModule diff --git a/modules/code-generator/src/plugins/component/react/containerInitState.ts b/modules/code-generator/src/plugins/component/react/containerInitState.ts index 5f246e115..d1dd0d1dd 100644 --- a/modules/code-generator/src/plugins/component/react/containerInitState.ts +++ b/modules/code-generator/src/plugins/component/react/containerInitState.ts @@ -13,12 +13,12 @@ import { } from '../../../types'; export interface PluginConfig { - fileType: string; + fileType?: string; implementType: 'inConstructor' | 'insMember' | 'hooks'; } const pluginFactory: BuilderComponentPluginFactory = (config?) => { - const cfg: PluginConfig = { + const cfg: PluginConfig & { fileType: string } = { fileType: FileType.JSX, implementType: 'inConstructor', ...config, diff --git a/modules/code-generator/src/plugins/component/react/containerInjectI18n.ts b/modules/code-generator/src/plugins/component/react/containerInjectI18n.ts index da04029c0..aff42af15 100644 --- a/modules/code-generator/src/plugins/component/react/containerInjectI18n.ts +++ b/modules/code-generator/src/plugins/component/react/containerInjectI18n.ts @@ -11,6 +11,7 @@ import { FileType, ICodeStruct, } from '../../../types'; +import { getSlotRelativePath } from '../../../utils/pathHelper'; export interface PluginConfig { fileType: string; @@ -31,9 +32,8 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => type: ChunkType.STRING, fileType: cfg.fileType, name: COMMON_CHUNK_NAME.InternalDepsImport, - // TODO: 下面这个路径有没有更好的方式来获取?而非写死 content: ` - import * as __$$i18n from '../../i18n'; + import * as __$$i18n from '${getSlotRelativePath({ contextData: next.contextData, from: 'components', to: 'i18n' })}'; `, linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport], }); diff --git a/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts b/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts index c5c566e17..d9eb14f76 100644 --- a/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts +++ b/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts @@ -11,18 +11,18 @@ import { FileType, ICodeStruct, IContainerInfo, - IProjectTemplate, } from '../../../types'; +import { getSlotRelativePath } from '../../../utils/pathHelper'; export interface PluginConfig { - fileType: string; + fileType?: string; /** prefer using class property to define utils */ preferClassProperty?: boolean; } const pluginFactory: BuilderComponentPluginFactory = (config?) => { - const cfg: PluginConfig = { + const cfg: PluginConfig & { fileType: string } = { fileType: FileType.JSX, ...config, }; @@ -36,26 +36,12 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => next.contextData.useRefApi = true; const useRef = !!ir.analyzeResult?.isUsingRef; - // const isSingleComponent = next.contextData?.projectRemark?.isSingleComponent; - // const template = next.contextData?.template; - - // function getRelativeUtilsPath(template: IProjectTemplate, isSingleComponent: boolean) { - // let relativeUtilsPath = '../../utils'; - // const utilsPath = template.slots.utils.path; - // if (ir.containerType === 'Component') { - // // TODO: isSingleComponent - // relativeUtilsPath = getRelativePath(template.slots.components.path.join('/'), utilsPath.join('/')); - // } - // return relativeUtilsPath; - // } - next.chunks.push({ type: ChunkType.STRING, fileType: cfg.fileType, name: COMMON_CHUNK_NAME.InternalDepsImport, - // TODO: 下面这个路径有没有更好的方式来获取?而非写死 content: ` - import utils${useRef ? ', { RefsManager }' : ''} from '../../utils'; + import utils${useRef ? ', { RefsManager }' : ''} from '${getSlotRelativePath({ contextData: next.contextData, from: 'components', to: 'utils' })}'; `, linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport], }); diff --git a/modules/code-generator/src/plugins/project/i18n.ts b/modules/code-generator/src/plugins/project/i18n.ts index d1d32ff32..ae568f972 100644 --- a/modules/code-generator/src/plugins/project/i18n.ts +++ b/modules/code-generator/src/plugins/project/i18n.ts @@ -25,8 +25,7 @@ const pluginFactory: BuilderComponentPluginFactory = () => { content: ` const i18nConfig = ${i18nStr}; - // let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN'; - let locale = 'zh-CN'; + let locale = typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language : 'zh-CN'; const getLocale = () => locale; diff --git a/modules/code-generator/src/utils/expressionParser.ts b/modules/code-generator/src/utils/expressionParser.ts index fc1fe4195..cbc950bbc 100644 --- a/modules/code-generator/src/utils/expressionParser.ts +++ b/modules/code-generator/src/utils/expressionParser.ts @@ -271,7 +271,7 @@ export function parseExpressionConvertThis2Context( const localVariablesSet = new Set(localVariables); - let thisScopeLevel = -1; + let thisScopeLevel = CROSS_THIS_SCOPE_TYPE_NODE[exprAst.type] ? -1 : 0; traverse(fileAst, { enter(path) { if (CROSS_THIS_SCOPE_TYPE_NODE[path.node.type]) { @@ -303,7 +303,7 @@ export function parseExpressionConvertThis2Context( } // 替换 this (只在顶层替换) - if (thisScopeLevel === 0) { + if (thisScopeLevel <= 0) { obj.replaceWith(t.identifier(contextName)); } }, @@ -317,7 +317,7 @@ export function parseExpressionConvertThis2Context( return; } - if (thisScopeLevel === 0) { + if (thisScopeLevel <= 0) { path.replaceWith(t.identifier(contextName)); } }, diff --git a/modules/code-generator/src/utils/index.ts b/modules/code-generator/src/utils/index.ts index cac63d415..8c41d678f 100644 --- a/modules/code-generator/src/utils/index.ts +++ b/modules/code-generator/src/utils/index.ts @@ -12,6 +12,7 @@ import * as version from './version'; import * as scope from './Scope'; import * as expressionParser from './expressionParser'; import * as dataSource from './dataSource'; +import * as pathHelper from './pathHelper'; export { common, @@ -27,4 +28,5 @@ export { scope, expressionParser, dataSource, + pathHelper, }; diff --git a/modules/code-generator/src/utils/pathHelper.ts b/modules/code-generator/src/utils/pathHelper.ts new file mode 100644 index 000000000..8440089d8 --- /dev/null +++ b/modules/code-generator/src/utils/pathHelper.ts @@ -0,0 +1,41 @@ +import { IContextData } from '../types'; + +function relativePath(from: string[], to: string[]): string[] { + const length = Math.min(from.length, to.length); + let samePartsLength = length; + for (let i = 0; i < length; i++) { + if (from[i] !== to[i]) { + samePartsLength = i; + break; + } + } + if (samePartsLength === 0) { + return to; + } + let outputParts = []; + for (let i = samePartsLength; i < from.length; i++) { + outputParts.push('..'); + } + outputParts = [...outputParts, ...to.slice(samePartsLength)]; + if (outputParts[0] !== '..') { + outputParts.unshift('.'); + } + return outputParts; +} + +export function getSlotRelativePath(options: { + contextData: IContextData; + from: string; + to: string; +}) { + const { contextData, from, to } = options; + const isSingleComponent = contextData?.extraContextData?.projectRemark?.isSingleComponent; + const template = contextData?.extraContextData?.template; + let toPath = template.slots[to].path; + toPath = [...toPath, template.slots[to].fileName!]; + let fromPath = template.slots[from].path; + if (!isSingleComponent && ['components', 'pages'].indexOf(from) !== -1) { + fromPath = [...fromPath, 'pageName']; + } + return relativePath(fromPath, toPath).join('/'); +} \ No newline at end of file diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/src/pages/Home/index.jsx b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/src/pages/Home/index.jsx index 7bfda59ca..06e39454d 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/src/pages/Home/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/src/pages/Home/index.jsx @@ -253,7 +253,6 @@ class Home$$Page extends Component { if (!response.success) { throw new Error(response.message); } - return response.data; }, isInit: true, @@ -280,7 +279,6 @@ class Home$$Page extends Component { if (!response.success) { throw new Error(response.message); } - return response.data.result; }, isInit: true, diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/package.json index 36eaf12f2..d18604922 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/package.json @@ -31,9 +31,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/pages/Test/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/pages/Test/index.jsx index c8db61db7..070020b74 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/pages/Test/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/pages/Test/index.jsx @@ -71,10 +71,10 @@ class Test$$Page extends React.Component { type: 'urlParams', isInit: function () { return undefined; - }, + }.bind(_this), options: function () { return undefined; - }, + }.bind(_this), }, { id: 'user', @@ -85,17 +85,16 @@ class Test$$Page extends React.Component { uri: 'https://shs.xxx.com/mock/1458/demo/user', isSync: true, }; - }, + }.bind(_this), dataHandler: function (response) { if (!response.data.success) { throw new Error(response.data.message); } - return response.data.data; }, isInit: function () { return undefined; - }, + }.bind(_this), }, { id: 'orders', @@ -106,17 +105,16 @@ class Test$$Page extends React.Component { uri: 'https://shs.xxx.com/mock/1458/demo/orders', isSync: true, }; - }, + }.bind(_this), dataHandler: function (response) { if (!response.data.success) { throw new Error(response.data.message); } - return response.data.data.result; }, isInit: function () { return undefined; - }, + }.bind(_this), }, ], dataHandler: function (dataMap) { diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/schema.json5 b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/schema.json5 index 5a1cfc4d9..76c52fb5e 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/schema.json5 +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/schema.json5 @@ -71,7 +71,7 @@ }, "lifeCycles": { "componentDidMount": { - "type": "JSExpression", + "type": "JSFunction", "value": "function() { console.log('componentDidMount'); }" } }, diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo2-utils-name-alias/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo2-utils-name-alias/expected/demo-project/package.json index 8ce6c9280..d83d45e32 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo2-utils-name-alias/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo2-utils-name-alias/expected/demo-project/package.json @@ -34,9 +34,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo2-utils-name-alias/expected/demo-project/src/pages/Aaaa/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo2-utils-name-alias/expected/demo-project/src/pages/Aaaa/index.jsx index a1b052424..2945a9d8f 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo2-utils-name-alias/expected/demo-project/src/pages/Aaaa/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo2-utils-name-alias/expected/demo-project/src/pages/Aaaa/index.jsx @@ -67,10 +67,10 @@ class Aaaa$$Page extends React.Component { return { uri: '', }; - }, + }.bind(_this), isInit: function () { return undefined; - }, + }.bind(_this), }, ], }; diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo2/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo2/expected/demo-project/package.json index 5fdcfad85..03820c157 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo2/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo2/expected/demo-project/package.json @@ -29,9 +29,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo2/schema.json5 b/modules/code-generator/tests/fixtures/test-cases/react-app/demo2/schema.json5 index 8678b4e92..222821206 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo2/schema.json5 +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo2/schema.json5 @@ -71,7 +71,7 @@ }, "lifeCycles": { "componentDidMount": { - "type": "JSExpression", + "type": "JSFunction", "value": "function() { console.log('componentDidMount'); }" } }, diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo3/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo3/expected/demo-project/package.json index 5fdcfad85..03820c157 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo3/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo3/expected/demo-project/package.json @@ -29,9 +29,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo4/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo4/expected/demo-project/package.json index b91e8870f..6190fc023 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo4/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo4/expected/demo-project/package.json @@ -31,9 +31,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo4/expected/demo-project/src/pages/Test/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo4/expected/demo-project/src/pages/Test/index.jsx index 9058b0aa7..6400d7445 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo4/expected/demo-project/src/pages/Test/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo4/expected/demo-project/src/pages/Test/index.jsx @@ -76,7 +76,7 @@ class Test$$Page extends React.Component { type: 'fetch', isInit: function () { return true; - }, + }.bind(_this), options: function () { return { params: {}, @@ -86,7 +86,7 @@ class Test$$Page extends React.Component { headers: {}, uri: 'https://mocks.xxx.com/mock/jjpin/user/list', }; - }, + }.bind(_this), id: 'users', }, ], diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo5/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo5/expected/demo-project/package.json index 2a2915e54..b31603b3a 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo5/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo5/expected/demo-project/package.json @@ -32,9 +32,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/expected/demo-project/package.json index 36eaf12f2..d18604922 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/expected/demo-project/package.json @@ -31,9 +31,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/expected/demo-project/src/pages/Test/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/expected/demo-project/src/pages/Test/index.jsx index 7a5c6fdfa..c27cce153 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/expected/demo-project/src/pages/Test/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/expected/demo-project/src/pages/Test/index.jsx @@ -71,10 +71,10 @@ class Test$$Page extends React.Component { type: 'urlParams', isInit: function () { return undefined; - }, + }.bind(_this), options: function () { return undefined; - }, + }.bind(_this), }, { id: 'user', @@ -85,17 +85,16 @@ class Test$$Page extends React.Component { uri: 'https://shs.xxx.com/mock/1458/demo/user', isSync: true, }; - }, + }.bind(_this), dataHandler: function (response) { if (!response.data.success) { throw new Error(response.data.message); } - return response.data.data; }, isInit: function () { return undefined; - }, + }.bind(_this), }, { id: 'orders', @@ -106,17 +105,16 @@ class Test$$Page extends React.Component { uri: 'https://shs.xxx.com/mock/1458/demo/orders', isSync: true, }; - }, + }.bind(_this), dataHandler: function (response) { if (!response.data.success) { throw new Error(response.data.message); } - return response.data.data.result; }, isInit: function () { return undefined; - }, + }.bind(_this), }, ], dataHandler: function (dataMap) { diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/schema.json5 b/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/schema.json5 index 6d3a60137..5b6776c1e 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/schema.json5 +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo6-literal-condition/schema.json5 @@ -71,7 +71,7 @@ }, lifeCycles: { componentDidMount: { - type: 'JSExpression', + type: 'JSFunction', value: "function() { console.log('componentDidMount'); }", }, }, @@ -91,7 +91,7 @@ isSync: true, }, dataHandler: { - type: 'JSExpression', + type: 'JSFunction', value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data;\n}', }, }, @@ -105,13 +105,13 @@ isSync: true, }, dataHandler: { - type: 'JSExpression', + type: 'JSFunction', value: 'function (response) {\nif (!response.data.success){\n throw new Error(response.data.message);\n }\n return response.data.data.result;\n}', }, }, ], dataHandler: { - type: 'JSExpression', + type: 'JSFunction', value: 'function (dataMap) {\n console.info("All datasources loaded:", dataMap);\n}', }, }, diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo7-literal-condition2/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo7-literal-condition2/expected/demo-project/package.json index 4ac494ebe..84141875e 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo7-literal-condition2/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo7-literal-condition2/expected/demo-project/package.json @@ -31,9 +31,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo7-literal-condition2/expected/demo-project/src/pages/Test/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo7-literal-condition2/expected/demo-project/src/pages/Test/index.jsx index e9cc592f1..9e93a3ff6 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo7-literal-condition2/expected/demo-project/src/pages/Test/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo7-literal-condition2/expected/demo-project/src/pages/Test/index.jsx @@ -151,6 +151,7 @@ class Test$$Page extends React.Component { onOkModifyDialogThird() { //第三步 修改 对话框 确定 + this.setState({ currentStep: 0, isModifyDialogVisible: false, @@ -159,6 +160,7 @@ class Test$$Page extends React.Component { onCancelModifyDialogThird() { //第三步 修改 对话框 取消 + this.setState({ isModifyDialogVisible: false, }); diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo8-datasource-prop/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo8-datasource-prop/expected/demo-project/package.json index 10269e8fd..91da69eef 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo8-datasource-prop/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo8-datasource-prop/expected/demo-project/package.json @@ -30,9 +30,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo8-datasource-prop/expected/demo-project/src/pages/Example/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo8-datasource-prop/expected/demo-project/src/pages/Example/index.jsx index d1046bd0d..9a661ad75 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo8-datasource-prop/expected/demo-project/src/pages/Example/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo8-datasource-prop/expected/demo-project/src/pages/Example/index.jsx @@ -63,10 +63,10 @@ class Example$$Page extends React.Component { return { uri: 'https://api.example.com/user/list', }; - }, + }.bind(_this), isInit: function () { return undefined; - }, + }.bind(_this), }, ], }; diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/package.json index 1dac338e3..939adb779 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/package.json @@ -30,9 +30,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/src/pages/$/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/src/pages/$/index.jsx index 9226280c7..1f2bf9041 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/src/pages/$/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/src/pages/$/index.jsx @@ -59,14 +59,14 @@ class $$Page extends React.Component { id: 'todos', isInit: function () { return true; - }, + }.bind(_this), type: 'jsonp', options: function () { return { method: 'GET', uri: 'https://a0ee9135-6a7f-4c0f-a215-f0f247ad907d.mock.pstmn.io', }; - }, + }.bind(_this), dataHandler: function dataHandler(data) { return data.data; }, diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo_10-jsslot/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo_10-jsslot/expected/demo-project/package.json index 2ab1720fc..41f379d7a 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo_10-jsslot/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo_10-jsslot/expected/demo-project/package.json @@ -32,9 +32,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo_10-jsslot/expected/demo-project/src/pages/Test/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo_10-jsslot/expected/demo-project/src/pages/Test/index.jsx index aa14cb916..922ad47ad 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo_10-jsslot/expected/demo-project/src/pages/Test/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo_10-jsslot/expected/demo-project/src/pages/Test/index.jsx @@ -65,7 +65,6 @@ class Test$$Page extends React.Component { }; this.__jp__init(); - this.statusDesc = { 0: '失败', 1: '成功', @@ -163,7 +162,6 @@ class Test$$Page extends React.Component { if (!item) { return '暂无结果'; } - const { channel, plat, version, status } = item; return [channel, plat, version, status].join('-'); } diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo_11-jsslot-2/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo_11-jsslot-2/expected/demo-project/package.json index a3a7ba8ab..2b45dfc53 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo_11-jsslot-2/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo_11-jsslot-2/expected/demo-project/package.json @@ -32,9 +32,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo_11-jsslot-2/expected/demo-project/src/pages/Test/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo_11-jsslot-2/expected/demo-project/src/pages/Test/index.jsx index d40458cf8..5630342f3 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo_11-jsslot-2/expected/demo-project/src/pages/Test/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo_11-jsslot-2/expected/demo-project/src/pages/Test/index.jsx @@ -67,7 +67,6 @@ class Test$$Page extends React.Component { }; this.__jp__init(); - this.statusDesc = { 0: '失败', 1: '成功', @@ -202,12 +201,10 @@ class Test$$Page extends React.Component { componentDidMount() { this.$ds.resolve('PROJECTS'); - if (this.userTimeout) { clearTimeout(this.userTimeout); this.userTimeout = null; } - if (this.projectTimeout) { clearTimeout(this.projectTimeout); this.projectTimeout = null; diff --git a/modules/code-generator/tests/fixtures/test-cases/react-module/demo1/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-module/demo1/expected/demo-project/package.json index ebb17b143..d32b684dc 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-module/demo1/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-module/demo1/expected/demo-project/package.json @@ -25,9 +25,16 @@ "eslint": "eslint --cache --ext .js,.jsx ./", "stylelint": "stylelint ./**/*.scss" }, - "ideMode": { "name": "ice-react" }, - "iceworks": { "type": "react", "adapter": "adapter-react-v3" }, - "engines": { "node": ">=8.0.0" }, + "ideMode": { + "name": "ice-react" + }, + "iceworks": { + "type": "react", + "adapter": "adapter-react-v3" + }, + "engines": { + "node": ">=8.0.0" + }, "repository": { "type": "git", "url": "http://gitlab.xxx.com/msd/leak-scan/tree/master" diff --git a/modules/code-generator/tests/postprocessor/__snapshots__/prettier.test.ts.snap b/modules/code-generator/tests/postprocessor/__snapshots__/prettier.test.ts.snap index 37d8d786b..db47e1829 100644 --- a/modules/code-generator/tests/postprocessor/__snapshots__/prettier.test.ts.snap +++ b/modules/code-generator/tests/postprocessor/__snapshots__/prettier.test.ts.snap @@ -19,7 +19,12 @@ export function App() { `; exports[`postprocessor/prettier should works for json file 1`] = ` -"{ \\"components\\": [\\"Button\\", \\"Block\\"] } +"{ + \\"components\\": [ + \\"Button\\", + \\"Block\\" + ] +} " `; From a2d857b143ac11342ba076bebc02e05618b31f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 2 Mar 2023 10:38:31 +0800 Subject: [PATCH 09/15] feat: add file name as the third argument which passed to module post processor --- .eslintrc.js | 26 ++++++++--------- .../src/generator/ModuleBuilder.ts | 5 ++-- modules/code-generator/src/types/core.ts | 29 ++++++++----------- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 1ec3834e6..eba1bac04 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,7 +15,6 @@ module.exports = { 'no-prototype-builtins': 1, 'no-useless-constructor': 1, 'no-empty-function': 1, - '@typescript-eslint/member-ordering': 0, 'lines-between-class-members': 0, 'no-await-in-loop': 0, 'no-plusplus': 0, @@ -35,22 +34,23 @@ module.exports = { '@typescript-eslint/indent': 0, 'import/no-cycle': 0, '@typescript-eslint/no-shadow': 0, - "@typescript-eslint/method-signature-style": 0, - "@typescript-eslint/consistent-type-assertions": 0, - "@typescript-eslint/no-useless-constructor": 0, + '@typescript-eslint/method-signature-style': 0, + '@typescript-eslint/consistent-type-assertions': 0, + '@typescript-eslint/no-useless-constructor': 0, '@typescript-eslint/dot-notation': 0, // for lint performance '@typescript-eslint/restrict-plus-operands': 0, // for lint performance 'no-unexpected-multiline': 1, - 'no-multiple-empty-lines': ['error', { "max": 1 }], + 'no-multiple-empty-lines': ['error', { max: 1 }], 'lines-around-comment': ['error', { - "beforeBlockComment": true, - "afterBlockComment": false, - "afterLineComment": false, - "allowBlockStart": true, + beforeBlockComment: true, + afterBlockComment: false, + afterLineComment: false, + allowBlockStart: true, }], - "@typescript-eslint/member-ordering": [ - "error", - { "default": ["signature", "field", "constructor", "method"] } + 'comma-dangle': ['error', 'always-multiline'], + '@typescript-eslint/member-ordering': [ + 'error', + { default: ['signature', 'field', 'constructor', 'method'] }, ], - } + }, }; \ No newline at end of file diff --git a/modules/code-generator/src/generator/ModuleBuilder.ts b/modules/code-generator/src/generator/ModuleBuilder.ts index 755ca20c6..e172f716e 100644 --- a/modules/code-generator/src/generator/ModuleBuilder.ts +++ b/modules/code-generator/src/generator/ModuleBuilder.ts @@ -62,10 +62,9 @@ export function createModuleBuilder( if (options.postProcessors.length > 0) { files = files.map((file) => { - let { content } = file; - const type = file.ext; + let { content, ext: type, name } = file; options.postProcessors.forEach((processer) => { - content = processer(content, type); + content = processer(content, type, name); }); return createResultFile(file.name, type, content); diff --git a/modules/code-generator/src/types/core.ts b/modules/code-generator/src/types/core.ts index 30c86a7e9..1a85db965 100644 --- a/modules/code-generator/src/types/core.ts +++ b/modules/code-generator/src/types/core.ts @@ -1,20 +1,15 @@ import { - IPublicTypeJSONArray, - IPublicTypeJSONObject, IPublicTypeCompositeArray, - IPublicTypeCompositeObject, - ResultDir, + IPublicTypeCompositeObject, IPublicTypeJSExpression, + IPublicTypeJSFunction, IPublicTypeJSONArray, + IPublicTypeJSONObject, IPublicTypeJSSlot, IPublicTypeNodeDataType, + IPublicTypeProjectSchema, ResultDir, ResultFile, - IPublicTypeNodeDataType, - IPublicTypeProjectSchema, - IPublicTypeJSExpression, - IPublicTypeJSFunction, - IPublicTypeJSSlot, } from '@alilc/lowcode-types'; -import { IParseResult } from './intermediate'; -import { IScopeBindings } from '../utils/ScopeBindings'; import type { ProjectBuilderInitOptions } from '../generator/ProjectBuilder'; +import { IScopeBindings } from '../utils/ScopeBindings'; +import { IParseResult } from './intermediate'; export enum FileType { CSS = 'css', @@ -69,16 +64,16 @@ export interface ICodeStruct extends IBaseCodeStruct { /** 上下文数据,用来在插件之间共享一些数据 */ export interface IContextData extends IProjectBuilderOptions { - /** - * 是否使用了 Ref 的 API (this.$/this.$$) - * */ - useRefApi?: boolean; - /** * 其他自定义数据 * (三方自定义插件也可以在此放一些数据,建议起个长一点的名称,用自己的插件名做前缀,以防冲突) */ [key: string]: any; + + /** + * 是否使用了 Ref 的 API (this.$/this.$$) + * */ + useRefApi?: boolean; } export type BuilderComponentPlugin = (initStruct: ICodeStruct) => Promise; @@ -202,7 +197,7 @@ export type ProjectPostProcessor = ( export type PostProcessorFactory = (config?: T) => PostProcessor; /** 模块级别的后置处理器 */ -export type PostProcessor = (content: string, fileType: string) => string; +export type PostProcessor = (content: string, fileType: string, name: string) => string; // TODO: temp interface, need modify export interface IPluginOptions { From 676e49ee2c48b01807d9220e6a554e24126aa6cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 2 Mar 2023 19:37:59 +0800 Subject: [PATCH 10/15] fix: use original moduleName --- modules/code-generator/src/parser/SchemaParser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/src/parser/SchemaParser.ts b/modules/code-generator/src/parser/SchemaParser.ts index 3108fee47..24fc68687 100644 --- a/modules/code-generator/src/parser/SchemaParser.ts +++ b/modules/code-generator/src/parser/SchemaParser.ts @@ -161,7 +161,7 @@ export class SchemaParser implements ISchemaParser { ...subRoot, componentName: getRootComponentName(subRoot.componentName, compDeps), containerType: subRoot.componentName, - moduleName: ensureValidClassName(changeCase.pascalCase(subRoot.fileName)), + moduleName: subRoot.fileName, }; return container; }); From a8ab86ebb558c6aaba2b2384590c6db969029074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 9 Mar 2023 20:02:35 +0800 Subject: [PATCH 11/15] feat: add static field displayName for Component type --- .../src/plugins/component/react/containerClass.ts | 14 +++++++++++++- modules/code-generator/src/types/deps.ts | 2 +- modules/code-generator/src/utils/common.ts | 13 +++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/modules/code-generator/src/plugins/component/react/containerClass.ts b/modules/code-generator/src/plugins/component/react/containerClass.ts index 0758c893e..b4c474b38 100644 --- a/modules/code-generator/src/plugins/component/react/containerClass.ts +++ b/modules/code-generator/src/plugins/component/react/containerClass.ts @@ -26,7 +26,7 @@ const pluginFactory: BuilderComponentPluginFactory = () => { // 将模块名转换成 PascalCase 的格式,并添加特定后缀,防止命名冲突 const componentClassName = ensureValidClassName( - `${changeCase.pascalCase(ir.moduleName)}$$Page`, + `${changeCase.pascalCase(ir.moduleName)}$$${ir.containerType}`, ); next.chunks.push({ @@ -43,6 +43,18 @@ const pluginFactory: BuilderComponentPluginFactory = () => { ], }); + if (ir.containerType === 'Component') { + next.chunks.push({ + type: ChunkType.STRING, + fileType: FileType.JSX, + name: CLASS_DEFINE_CHUNK_NAME.InsVar, + content: `static displayName = '${changeCase.pascalCase(ir.moduleName)}';`, + linkAfter: [ + CLASS_DEFINE_CHUNK_NAME.Start, + ], + }); + } + next.chunks.push({ type: ChunkType.STRING, fileType: FileType.JSX, diff --git a/modules/code-generator/src/types/deps.ts b/modules/code-generator/src/types/deps.ts index cb2fb5eac..a6531092d 100644 --- a/modules/code-generator/src/types/deps.ts +++ b/modules/code-generator/src/types/deps.ts @@ -35,4 +35,4 @@ export interface IDependency { main?: string; // 包导出组件入口文件路径 /lib/input dependencyType?: DependencyType; // 依赖类型 内/外 componentName?: string; // 导入后名称 -} +} \ No newline at end of file diff --git a/modules/code-generator/src/utils/common.ts b/modules/code-generator/src/utils/common.ts index d822fdf81..fa7ab30a9 100644 --- a/modules/code-generator/src/utils/common.ts +++ b/modules/code-generator/src/utils/common.ts @@ -1,6 +1,7 @@ import type { IPublicTypeJSExpression, IPublicTypeJSFunction } from '@alilc/lowcode-types'; import changeCase from 'change-case'; import short from 'short-uuid'; +import { DependencyType, IDependency, IExternalDependency, IInternalDependency } from '../types'; // Doc: https://www.npmjs.com/package/change-case @@ -43,4 +44,16 @@ export function getStaticExprValue(expr: string): T { export function isJSExpressionFn(data: any): data is IPublicTypeJSFunction { return data?.type === 'JSExpression' && data?.extType === 'function'; +} + +export function isInternalDependency( + dependency: IDependency, +): dependency is IInternalDependency { + return dependency.dependencyType === DependencyType.Internal; +} + +export function isExternalDependency( + dependency: IDependency, +): dependency is IExternalDependency { + return dependency.dependencyType === DependencyType.External; } \ No newline at end of file From 8474644e9991c5d4c2c837c7eade2684d857d186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 10 Mar 2023 10:37:18 +0800 Subject: [PATCH 12/15] chore: make the second argument of module post processor optional --- modules/code-generator/src/types/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/src/types/core.ts b/modules/code-generator/src/types/core.ts index 1a85db965..33abad1d1 100644 --- a/modules/code-generator/src/types/core.ts +++ b/modules/code-generator/src/types/core.ts @@ -197,7 +197,7 @@ export type ProjectPostProcessor = ( export type PostProcessorFactory = (config?: T) => PostProcessor; /** 模块级别的后置处理器 */ -export type PostProcessor = (content: string, fileType: string, name: string) => string; +export type PostProcessor = (content: string, fileType: string, name?: string) => string; // TODO: temp interface, need modify export interface IPluginOptions { From c61694581b5dd0dbb9456c196178b00f04048df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 10 Mar 2023 10:37:33 +0800 Subject: [PATCH 13/15] Revert "fix: use original moduleName" This reverts commit 676e49ee2c48b01807d9220e6a554e24126aa6cc. --- modules/code-generator/src/parser/SchemaParser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/src/parser/SchemaParser.ts b/modules/code-generator/src/parser/SchemaParser.ts index 24fc68687..3108fee47 100644 --- a/modules/code-generator/src/parser/SchemaParser.ts +++ b/modules/code-generator/src/parser/SchemaParser.ts @@ -161,7 +161,7 @@ export class SchemaParser implements ISchemaParser { ...subRoot, componentName: getRootComponentName(subRoot.componentName, compDeps), containerType: subRoot.componentName, - moduleName: subRoot.fileName, + moduleName: ensureValidClassName(changeCase.pascalCase(subRoot.fileName)), }; return container; }); From 9ab2934aacbceea75e4317a8e758489f45d2ddea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 10 Mar 2023 14:52:09 +0800 Subject: [PATCH 14/15] chore(release): code-generator - 1.0.8 --- modules/code-generator/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index 97863584c..72388a4ac 100644 --- a/modules/code-generator/package.json +++ b/modules/code-generator/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-code-generator", - "version": "1.0.7", + "version": "1.0.8", "description": "出码引擎 for LowCode Engine", "license": "MIT", "main": "lib/index.js", From 108108cf51e26e9aeafb2b9e98ac530c54f205d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 10 Mar 2023 16:00:00 +0800 Subject: [PATCH 15/15] chore: fix ts errors --- modules/code-generator/src/types/core.ts | 3 ++- modules/code-generator/src/utils/nodeToJSX.ts | 2 +- modules/code-generator/src/utils/schema.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/code-generator/src/types/core.ts b/modules/code-generator/src/types/core.ts index 33abad1d1..fb2a780c1 100644 --- a/modules/code-generator/src/types/core.ts +++ b/modules/code-generator/src/types/core.ts @@ -178,7 +178,8 @@ export interface IProjectBuilder { } /** 项目级别的前置处理器 */ -export type ProjectPreProcessor = (schema: IPublicTypeProjectSchema) => Promise | IPublicTypeProjectSchema; +export type ProjectPreProcessor = (schema: IPublicTypeProjectSchema) => + Promise | IPublicTypeProjectSchema; export interface ProjectPostProcessorOptions { parseResult?: IParseResult; diff --git a/modules/code-generator/src/utils/nodeToJSX.ts b/modules/code-generator/src/utils/nodeToJSX.ts index 73dba862c..ad79288ba 100644 --- a/modules/code-generator/src/utils/nodeToJSX.ts +++ b/modules/code-generator/src/utils/nodeToJSX.ts @@ -126,7 +126,7 @@ function generateAttrs( if (props) { if (!Array.isArray(props)) { Object.keys(props).forEach((propName: string) => { - pieces = pieces.concat(generateAttr(propName, props[propName], scope, config)); + pieces = pieces.concat(generateAttr(propName, props[propName] as IPublicTypeCompositeValue, scope, config)); }); } else { props.forEach((prop) => { diff --git a/modules/code-generator/src/utils/schema.ts b/modules/code-generator/src/utils/schema.ts index 0b8295aac..831b38965 100644 --- a/modules/code-generator/src/utils/schema.ts +++ b/modules/code-generator/src/utils/schema.ts @@ -101,7 +101,7 @@ export function handleSubNodes( }); } else { Object.values(child.props).forEach((value) => { - const childRes = handleCompositeValueInProps(value); + const childRes = handleCompositeValueInProps(value as IPublicTypeCompositeValue); childrenRes.push(...childRes); }); }