in modules/code-generator/src/generator/ProjectBuilder.ts [110:306]
async generateProject(originalSchema: IPublicTypeProjectSchema | string): Promise<ResultDir> {
// Init
const { schemaParser } = this;
let schema: IPublicTypeProjectSchema =
typeof originalSchema === 'string' ? JSON.parse(originalSchema) : originalSchema;
// 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);
const projectRoot = await this.template.generateTemplate(parseResult);
let buildResult: IModuleInfo[] = [];
const builders = this.createModuleBuilders({
extraContextData: {
projectRemark: parseResult?.project?.projectRemark,
template: this.template,
},
});
// 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,
});
}
// appConfig
if (builders.appConfig) {
const { files } = await builders.appConfig.generateModule(parseResult);
buildResult.push({
path: this.template.slots.appConfig.path,
files,
});
}
// buildConfig
if (builders.buildConfig) {
const { files } = await builders.buildConfig.generateModule(parseResult);
buildResult.push({
path: this.template.slots.buildConfig.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 (builders.i18n && this.template.slots.i18n) {
const { files } = await builders.i18n.generateModule(parseResult.project);
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,
});
}
// demo
if (parseResult.project && builders.demo) {
const { files } = await builders.demo.generateModule(parseResult.project);
buildResult.push({
path: this.template.slots.demo.path,
files,
});
}
// handle extra slots
await this.generateExtraSlots(builders, parseResult, buildResult);
// Post Process
const isSingleComponent = parseResult?.project?.projectRemark?.isSingleComponent;
// Combine Modules
buildResult.forEach((moduleInfo) => {
let targetDir = getDirFromRoot(projectRoot, moduleInfo.path);
// if project only contain single component, skip creation of directory.
if (moduleInfo.moduleName && !isSingleComponent) {
const dir = createResultDir(moduleInfo.moduleName);
addDirectory(targetDir, dir);
targetDir = dir;
}
moduleInfo.files.forEach((file) => addFile(targetDir, file));
});
// post-processors
let finalResult = projectRoot;
for (const projectPostProcessor of this.projectPostProcessors) {
// eslint-disable-next-line no-await-in-loop
finalResult = await projectPostProcessor(finalResult, schema, originalSchema, {
template: this.template,
parseResult,
});
}
return finalResult;
}