diff --git a/modules/code-generator/src/generator/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index 1cac2dea2..0d0c5fe84 100644 --- a/modules/code-generator/src/generator/ProjectBuilder.ts +++ b/modules/code-generator/src/generator/ProjectBuilder.ts @@ -90,31 +90,34 @@ export class ProjectBuilder implements IProjectBuilder { async generateProject(originalSchema: ProjectSchema | string): Promise { // Init const { schemaParser } = this; - const builders = this.createModuleBuilders(); const projectRoot = await this.template.generateTemplate(); let schema: ProjectSchema = typeof originalSchema === 'string' ? JSON.parse(originalSchema) : originalSchema; - // Validate - if (!schemaParser.validate(schema)) { - throw new CodeGeneratorError('Schema is invalid'); - } - // Parse / Format - // Preprocess for (const preProcessor of this.projectPreProcessors) { // eslint-disable-next-line no-await-in-loop schema = await preProcessor(schema); } + // Validate + if (!schemaParser.validate(schema)) { + throw new CodeGeneratorError('Schema is invalid'); + } + // Collect Deps // Parse JSExpression const parseResult: IParseResult = schemaParser.parse(schema); let buildResult: IModuleInfo[] = []; + const builders = this.createModuleBuilders({ + extraContextData: { + projectRemark: parseResult?.project?.projectRemark, + }, + }); // Generator Code module // components // pages @@ -253,11 +256,12 @@ export class ProjectBuilder implements IProjectBuilder { // TODO: 更多 slots 的处理??是不是可以考虑把 template 中所有的 slots 都处理下? // Post Process - + const isSingleComponent = parseResult?.project?.projectRemark?.isSingleComponent; // Combine Modules buildResult.forEach((moduleInfo) => { let targetDir = getDirFromRoot(projectRoot, moduleInfo.path); - if (moduleInfo.moduleName) { + // if project only contain single component, skip creation of directory. + if (moduleInfo.moduleName && !isSingleComponent) { const dir = createResultDir(moduleInfo.moduleName); addDirectory(targetDir, dir); targetDir = dir; @@ -278,7 +282,8 @@ export class ProjectBuilder implements IProjectBuilder { return finalResult; } - private createModuleBuilders(): Record { + private createModuleBuilders(extraContextData: Record = {}): + Record { const builders: Record = {}; Object.keys(this.plugins).forEach((pluginName) => { @@ -291,10 +296,12 @@ export class ProjectBuilder implements IProjectBuilder { plugins: this.plugins[pluginName], postProcessors: this.postProcessors, contextData: { + // template: this.template, inStrictMode: this.inStrictMode, tolerateEvalErrors: true, evalErrorsHandler: '', ...this.extraContextData, + ...extraContextData, }, ...options, }); diff --git a/modules/code-generator/src/parser/SchemaParser.ts b/modules/code-generator/src/parser/SchemaParser.ts index ab4636561..ad055250d 100644 --- a/modules/code-generator/src/parser/SchemaParser.ts +++ b/modules/code-generator/src/parser/SchemaParser.ts @@ -36,6 +36,7 @@ import { handleSubNodes, isValidContainerType } from '../utils/schema'; import { uniqueArray } from '../utils/common'; import { componentAnalyzer } from '../analyzer/componentAnalyzer'; import { ensureValidClassName } from '../utils/validate'; +import type { ProjectRemark } from '../types/intermediate'; const defaultContainer: IContainerInfo = { containerType: 'Component', @@ -319,10 +320,17 @@ export class SchemaParser implements ISchemaParser { utilsDeps, packages: npms || [], dataSourcesTypes: this.collectDataSourcesTypes(schema), + projectRemark: this.getProjectRemark(containers), }, }; } + getProjectRemark(containers: IContainerInfo[]): ProjectRemark { + return { + isSingleComponent: containers.length === 1 && containers[0].containerType === 'Component', + }; + } + getComponentNames(children: NodeDataType): string[] { return handleSubNodes( children, diff --git a/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts b/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts index 20302dea9..2141c6309 100644 --- a/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts +++ b/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts @@ -27,7 +27,7 @@ import { import { generateCompositeType } from '../../../utils/compositeType'; import { parseExpressionConvertThis2Context } from '../../../utils/expressionParser'; -import { isContainerSchema } from '../../../utils/schema'; +import { isValidContainerType } from '../../../utils/schema'; import { REACT_CHUNK_NAME } from './const'; export interface PluginConfig { @@ -67,7 +67,7 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => }; const scope = Scope.createRootScope(); - const dataSourceConfig = isContainerSchema(pre.ir) ? pre.ir.dataSource : null; + const dataSourceConfig = isValidContainerType(pre.ir) ? pre.ir.dataSource : null; const dataSourceItems: InterpretDataSourceConfig[] = (dataSourceConfig && dataSourceConfig.list) || []; const dataSourceEngineOptions = { runtimeConfig: true }; diff --git a/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts b/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts index 6c614f143..33fc8c28d 100644 --- a/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts +++ b/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts @@ -11,6 +11,7 @@ import { FileType, ICodeStruct, IContainerInfo, + IProjectTemplate, } from '../../../types'; export interface PluginConfig { @@ -32,6 +33,19 @@ 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, @@ -89,7 +103,7 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => type: ChunkType.STRING, fileType: cfg.fileType, name: CLASS_DEFINE_CHUNK_NAME.InsMethod, - content: ` $ = () => null; `, + content: ' $ = () => null; ', linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]], }); @@ -97,7 +111,7 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => type: ChunkType.STRING, fileType: cfg.fileType, name: CLASS_DEFINE_CHUNK_NAME.InsMethod, - content: ` $$ = () => []; `, + content: ' $$ = () => []; ', linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]], }); } diff --git a/modules/code-generator/src/types/intermediate.ts b/modules/code-generator/src/types/intermediate.ts index 43d8f0e84..30ef1e84b 100644 --- a/modules/code-generator/src/types/intermediate.ts +++ b/modules/code-generator/src/types/intermediate.ts @@ -33,6 +33,14 @@ export interface IRouterInfo extends IWithDependency { }>; } +/** + * project's remarks + */ +export interface ProjectRemark { + /** if current project only contain one container which type is `Component` */ + isSingleComponent?: boolean; +} + export interface IProjectInfo { css?: string; containersDeps?: IDependency[]; @@ -43,6 +51,7 @@ export interface IProjectInfo { meta?: { name?: string; title?: string } | Record; config?: Record; dataSourcesTypes?: string[]; + projectRemark?: ProjectRemark; } export interface IPageMeta {