mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-13 09:41:57 +00:00
227 lines
6.0 KiB
TypeScript
227 lines
6.0 KiB
TypeScript
import {
|
|
IModuleBuilder,
|
|
IParseResult,
|
|
IProjectBuilder,
|
|
IProjectPlugins,
|
|
IProjectSchema,
|
|
IProjectTemplate,
|
|
IResultDir,
|
|
IResultFile,
|
|
ISchemaParser,
|
|
PostProcessor,
|
|
} from '../types';
|
|
|
|
import ResultDir from '../model/ResultDir';
|
|
import SchemaParser from '../parser/SchemaParser';
|
|
|
|
import { createModuleBuilder } from '../generator/ModuleBuilder';
|
|
|
|
interface IModuleInfo {
|
|
moduleName?: string;
|
|
path: string[];
|
|
files: IResultFile[];
|
|
}
|
|
|
|
function getDirFromRoot(root: IResultDir, path: string[]): IResultDir {
|
|
let current: IResultDir = root;
|
|
path.forEach((p) => {
|
|
const exist = current.dirs.find((d) => d.name === p);
|
|
if (exist) {
|
|
current = exist;
|
|
} else {
|
|
const newDir = new ResultDir(p);
|
|
current.addDirectory(newDir);
|
|
current = newDir;
|
|
}
|
|
});
|
|
|
|
return current;
|
|
}
|
|
|
|
export class ProjectBuilder implements IProjectBuilder {
|
|
private template: IProjectTemplate;
|
|
private plugins: IProjectPlugins;
|
|
private postProcessors: PostProcessor[];
|
|
|
|
constructor({
|
|
template,
|
|
plugins,
|
|
postProcessors,
|
|
}: {
|
|
template: IProjectTemplate;
|
|
plugins: IProjectPlugins;
|
|
postProcessors: PostProcessor[];
|
|
}) {
|
|
this.template = template;
|
|
this.plugins = plugins;
|
|
this.postProcessors = postProcessors;
|
|
}
|
|
|
|
async generateProject(schema: IProjectSchema | string): Promise<IResultDir> {
|
|
// Init
|
|
const schemaParser: ISchemaParser = new SchemaParser();
|
|
const builders = this.createModuleBuilders();
|
|
const projectRoot = this.template.generateTemplate();
|
|
|
|
// Validate
|
|
// Parse / Format
|
|
|
|
// Preprocess
|
|
// Collect Deps
|
|
// Parse JSExpression
|
|
const parseResult: IParseResult = schemaParser.parse(schema);
|
|
let buildResult: IModuleInfo[] = [];
|
|
|
|
// Generator Code module
|
|
// components
|
|
// pages
|
|
const containerBuildResult: IModuleInfo[] = await Promise.all<IModuleInfo>(
|
|
parseResult.containers.map(async (containerInfo) => {
|
|
let builder: IModuleBuilder;
|
|
let path: string[];
|
|
if (containerInfo.containerType === 'Page') {
|
|
builder = builders.pages;
|
|
path = this.template.slots.pages.path;
|
|
} else {
|
|
builder = builders.components;
|
|
path = this.template.slots.components.path;
|
|
}
|
|
|
|
const { files } = await builder.generateModule(containerInfo);
|
|
|
|
return {
|
|
moduleName: containerInfo.moduleName,
|
|
path,
|
|
files,
|
|
};
|
|
}),
|
|
);
|
|
buildResult = buildResult.concat(containerBuildResult);
|
|
|
|
// router
|
|
if (parseResult.globalRouter && builders.router) {
|
|
const { files } = await builders.router.generateModule(parseResult.globalRouter);
|
|
|
|
buildResult.push({
|
|
path: this.template.slots.router.path,
|
|
files,
|
|
});
|
|
}
|
|
|
|
// entry
|
|
if (parseResult.project && builders.entry) {
|
|
const { files } = await builders.entry.generateModule(parseResult.project);
|
|
|
|
buildResult.push({
|
|
path: this.template.slots.entry.path,
|
|
files,
|
|
});
|
|
}
|
|
// constants?
|
|
if (parseResult.project && builders.constants && this.template.slots.constants) {
|
|
const { files } = await builders.constants.generateModule(parseResult.project);
|
|
|
|
buildResult.push({
|
|
path: this.template.slots.constants.path,
|
|
files,
|
|
});
|
|
}
|
|
// utils?
|
|
if (parseResult.globalUtils && builders.utils && this.template.slots.utils) {
|
|
const { files } = await builders.utils.generateModule(parseResult.globalUtils);
|
|
|
|
buildResult.push({
|
|
path: this.template.slots.utils.path,
|
|
files,
|
|
});
|
|
}
|
|
// i18n?
|
|
if (parseResult.globalI18n && builders.i18n && this.template.slots.i18n) {
|
|
const { files } = await builders.i18n.generateModule(parseResult.globalI18n);
|
|
|
|
buildResult.push({
|
|
path: this.template.slots.i18n.path,
|
|
files,
|
|
});
|
|
}
|
|
// globalStyle
|
|
if (parseResult.project && builders.globalStyle) {
|
|
const { files } = await builders.globalStyle.generateModule(parseResult.project);
|
|
|
|
buildResult.push({
|
|
path: this.template.slots.globalStyle.path,
|
|
files,
|
|
});
|
|
}
|
|
// htmlEntry
|
|
if (parseResult.project && builders.htmlEntry) {
|
|
const { files } = await builders.htmlEntry.generateModule(parseResult.project);
|
|
|
|
buildResult.push({
|
|
path: this.template.slots.htmlEntry.path,
|
|
files,
|
|
});
|
|
}
|
|
// packageJSON
|
|
if (parseResult.project && builders.packageJSON) {
|
|
const { files } = await builders.packageJSON.generateModule(parseResult.project);
|
|
|
|
buildResult.push({
|
|
path: this.template.slots.packageJSON.path,
|
|
files,
|
|
});
|
|
}
|
|
|
|
// Post Process
|
|
|
|
// Combine Modules
|
|
buildResult.forEach((moduleInfo) => {
|
|
let targetDir = getDirFromRoot(projectRoot, moduleInfo.path);
|
|
if (moduleInfo.moduleName) {
|
|
const dir = new ResultDir(moduleInfo.moduleName);
|
|
targetDir.addDirectory(dir);
|
|
targetDir = dir;
|
|
}
|
|
moduleInfo.files.forEach((file) => targetDir.addFile(file));
|
|
});
|
|
|
|
return projectRoot;
|
|
}
|
|
|
|
private createModuleBuilders(): Record<string, IModuleBuilder> {
|
|
const builders: Record<string, IModuleBuilder> = {};
|
|
|
|
Object.keys(this.plugins).forEach((pluginName) => {
|
|
if (this.plugins[pluginName].length > 0) {
|
|
const options: { mainFileName?: string } = {};
|
|
if (this.template.slots[pluginName] && this.template.slots[pluginName].fileName) {
|
|
options.mainFileName = this.template.slots[pluginName].fileName;
|
|
}
|
|
builders[pluginName] = createModuleBuilder({
|
|
plugins: this.plugins[pluginName],
|
|
postProcessors: this.postProcessors,
|
|
...options,
|
|
});
|
|
}
|
|
});
|
|
|
|
return builders;
|
|
}
|
|
}
|
|
|
|
export function createProjectBuilder({
|
|
template,
|
|
plugins,
|
|
postProcessors,
|
|
}: {
|
|
template: IProjectTemplate;
|
|
plugins: IProjectPlugins;
|
|
postProcessors: PostProcessor[];
|
|
}): IProjectBuilder {
|
|
return new ProjectBuilder({
|
|
template,
|
|
plugins,
|
|
postProcessors,
|
|
});
|
|
}
|