diff --git a/packages/code-generator/src/const/file.ts b/packages/code-generator/src/const/file.ts new file mode 100644 index 000000000..d29ea43a3 --- /dev/null +++ b/packages/code-generator/src/const/file.ts @@ -0,0 +1,3 @@ +import { FileType } from '../types/core'; + +export const FILE_TYPE_FAMILY = [[FileType.TSX, FileType.TS, FileType.JSX, FileType.JS]]; diff --git a/packages/code-generator/src/generator/ChunkBuilder.ts b/packages/code-generator/src/generator/ChunkBuilder.ts index 18ff63991..67ecd504e 100644 --- a/packages/code-generator/src/generator/ChunkBuilder.ts +++ b/packages/code-generator/src/generator/ChunkBuilder.ts @@ -1,28 +1,72 @@ -import { - BuilderComponentPlugin, - IChunkBuilder, - ICodeChunk, - ICodeStruct, -} from '../types'; +import { BuilderComponentPlugin, IChunkBuilder, ICodeChunk, ICodeStruct, FileType } from '../types'; import { COMMON_SUB_MODULE_NAME } from '../const/generator'; +import { FILE_TYPE_FAMILY } from '../const/file'; + +type ChunkGroupInfo = { + chunk: ICodeChunk; + familyIdx?: number; +}; + +function whichFamily(type: FileType): [number, FileType[]] | undefined { + const idx = FILE_TYPE_FAMILY.findIndex((family) => family.indexOf(type) >= 0); + if (idx < 0) { + return undefined; + } + return [idx, FILE_TYPE_FAMILY[idx]]; +} export const groupChunks = (chunks: ICodeChunk[]): ICodeChunk[][] => { - const col = chunks.reduce( - (chunksSet: Record, chunk) => { - const fileKey = `${chunk.subModule || COMMON_SUB_MODULE_NAME}.${ - chunk.fileType - }`; - if (!chunksSet[fileKey]) { - chunksSet[fileKey] = []; + const tmp: Record> = {}; + const col = chunks.reduce((chunksSet: Record, chunk) => { + const fileKey = chunk.subModule || COMMON_SUB_MODULE_NAME; + if (!chunksSet[fileKey]) { + chunksSet[fileKey] = []; + } + const res = whichFamily(chunk.fileType as FileType); + const info: ChunkGroupInfo = { + chunk, + }; + if (res) { + const [familyIdx, family] = res; + const rank = family.indexOf(chunk.fileType as FileType); + if (tmp[fileKey]) { + if (tmp[fileKey][familyIdx] !== undefined) { + if (tmp[fileKey][familyIdx] > rank) { + tmp[fileKey][familyIdx] = rank; + } + } else { + tmp[fileKey][familyIdx] = rank; + } + } else { + tmp[fileKey] = {}; + tmp[fileKey][familyIdx] = rank; } - chunksSet[fileKey].push(chunk); - return chunksSet; - }, - {}, - ); + info.familyIdx = familyIdx; + } - return Object.keys(col).map(key => col[key]); + chunksSet[fileKey].push(info); + return chunksSet; + }, {}); + + const result: ICodeChunk[][] = []; + Object.keys(col).forEach((key) => { + const byType: Record = {}; + col[key].forEach((info) => { + let t: string = info.chunk.fileType; + if (info.familyIdx !== undefined) { + t = FILE_TYPE_FAMILY[info.familyIdx][tmp[key][info.familyIdx]]; + info.chunk.fileType = t; + } + if (!byType[t]) { + byType[t] = []; + } + byType[t].push(info.chunk); + }); + result.push(...Object.keys(byType).map((t) => byType[t])); + }); + + return result; }; /** @@ -39,7 +83,7 @@ export default class ChunkBuilder implements IChunkBuilder { this.plugins = plugins; } - public async run( + async run( ir: unknown, initialStructure: ICodeStruct = { ir, @@ -64,11 +108,11 @@ export default class ChunkBuilder implements IChunkBuilder { }; } - public getPlugins() { + getPlugins() { return this.plugins; } - public addPlugin(plugin: BuilderComponentPlugin) { + addPlugin(plugin: BuilderComponentPlugin) { this.plugins.push(plugin); } } diff --git a/packages/code-generator/src/generator/ModuleBuilder.ts b/packages/code-generator/src/generator/ModuleBuilder.ts index 991ffedec..063434cb4 100644 --- a/packages/code-generator/src/generator/ModuleBuilder.ts +++ b/packages/code-generator/src/generator/ModuleBuilder.ts @@ -37,29 +37,23 @@ export function createModuleBuilder( const generateModule = async (input: unknown): Promise => { const moduleMainName = options.mainFileName || COMMON_SUB_MODULE_NAME; if (chunkGenerator.getPlugins().length <= 0) { - throw new CodeGeneratorError( - 'No plugins found. Component generation cannot work without any plugins!', - ); + throw new CodeGeneratorError('No plugins found. Component generation cannot work without any plugins!'); } let files: IResultFile[] = []; const { chunks } = await chunkGenerator.run(input); - chunks.forEach(fileChunkList => { + chunks.forEach((fileChunkList) => { const content = linker.link(fileChunkList); - const file = new ResultFile( - fileChunkList[0].subModule || moduleMainName, - fileChunkList[0].fileType, - content, - ); + const file = new ResultFile(fileChunkList[0].subModule || moduleMainName, fileChunkList[0].fileType, content); files.push(file); }); if (options.postProcessors.length > 0) { - files = files.map(file => { + files = files.map((file) => { let content = file.content; const type = file.ext; - options.postProcessors.forEach(processer => { + options.postProcessors.forEach((processer) => { content = processer(content, type); }); @@ -81,25 +75,18 @@ export function createModuleBuilder( const { files } = await generateModule(containerInfo); const dir = new ResultDir(containerInfo.moduleName); - files.forEach(file => dir.addFile(file)); + files.forEach((file) => dir.addFile(file)); return dir; - } + }; - const linkCodeChunks = ( - chunks: Record, - fileName: string, - ) => { + const linkCodeChunks = (chunks: Record, fileName: string) => { const files: IResultFile[] = []; - Object.keys(chunks).forEach(fileKey => { + Object.keys(chunks).forEach((fileKey) => { const fileChunkList = chunks[fileKey]; const content = linker.link(fileChunkList); - const file = new ResultFile( - fileChunkList[0].subModule || fileName, - fileChunkList[0].fileType, - content, - ); + const file = new ResultFile(fileChunkList[0].subModule || fileName, fileChunkList[0].fileType, content); files.push(file); });