mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-02-27 04:10:31 +00:00
147 lines
3.6 KiB
TypeScript
147 lines
3.6 KiB
TypeScript
import { COMMON_CHUNK_NAME } from '../../const/generator';
|
|
|
|
import {
|
|
BuilderComponentPlugin,
|
|
ChunkType,
|
|
CodeGeneratorError,
|
|
DependencyType,
|
|
FileType,
|
|
ICodeChunk,
|
|
ICodeStruct,
|
|
IDependency,
|
|
IExternalDependency,
|
|
IInternalDependency,
|
|
IWithDependency,
|
|
} from '../../types';
|
|
|
|
function groupDepsByPack(deps: IDependency[]): Record<string, IDependency[]> {
|
|
const depMap: Record<string, IDependency[]> = {};
|
|
|
|
const addDep = (pkg: string, dep: IDependency) => {
|
|
if (!depMap[pkg]) {
|
|
depMap[pkg] = [];
|
|
}
|
|
depMap[pkg].push(dep);
|
|
};
|
|
|
|
deps.forEach(dep => {
|
|
if (dep.dependencyType === DependencyType.Internal) {
|
|
addDep(
|
|
`${(dep as IInternalDependency).moduleName}${dep.main || ''}`,
|
|
dep,
|
|
);
|
|
} else {
|
|
addDep(`${(dep as IExternalDependency).package}${dep.main || ''}`, dep);
|
|
}
|
|
});
|
|
|
|
return depMap;
|
|
}
|
|
|
|
function buildPackageImport(
|
|
pkg: string,
|
|
deps: IDependency[],
|
|
isJSX: boolean,
|
|
): ICodeChunk[] {
|
|
const chunks: ICodeChunk[] = [];
|
|
let defaultImport: string = '';
|
|
let defaultImportAs: string = '';
|
|
const imports: Record<string, string> = {};
|
|
|
|
deps.forEach(dep => {
|
|
const srcName = dep.exportName;
|
|
let targetName = dep.importName || dep.exportName;
|
|
if (dep.subName) {
|
|
return;
|
|
}
|
|
|
|
if (dep.subName) {
|
|
chunks.push({
|
|
type: ChunkType.STRING,
|
|
fileType: isJSX ? FileType.JSX : FileType.JS,
|
|
name: COMMON_CHUNK_NAME.FileVarDefine,
|
|
content: `const ${targetName} = ${srcName}.${dep.subName};`,
|
|
linkAfter: [
|
|
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
],
|
|
});
|
|
|
|
targetName = srcName;
|
|
}
|
|
|
|
if (dep.destructuring) {
|
|
imports[srcName] = targetName;
|
|
} else if (defaultImport) {
|
|
throw new CodeGeneratorError(
|
|
`[${pkg}] has more than one default export.`,
|
|
);
|
|
} else {
|
|
defaultImport = srcName;
|
|
defaultImportAs = targetName;
|
|
}
|
|
});
|
|
|
|
const items = Object.keys(imports).map(src =>
|
|
src === imports[src] ? src : `${src} as ${imports[src]}`,
|
|
);
|
|
|
|
const statementL = ['import'];
|
|
if (defaultImport) {
|
|
statementL.push(defaultImportAs);
|
|
if (items.length > 0) {
|
|
statementL.push(',');
|
|
}
|
|
}
|
|
if (items.length > 0) {
|
|
statementL.push(`{ ${items.join(', ')} }`);
|
|
}
|
|
statementL.push('from');
|
|
|
|
if (deps[0].dependencyType === DependencyType.Internal) {
|
|
// TODO: Internal Deps path use project slot setting
|
|
statementL.push(`'@/${(deps[0] as IInternalDependency).type}/${pkg}';`);
|
|
chunks.push({
|
|
type: ChunkType.STRING,
|
|
fileType: isJSX ? FileType.JSX : FileType.JS,
|
|
name: COMMON_CHUNK_NAME.InternalDepsImport,
|
|
content: statementL.join(' '),
|
|
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport],
|
|
});
|
|
} else {
|
|
statementL.push(`'${pkg}';`);
|
|
chunks.push({
|
|
type: ChunkType.STRING,
|
|
fileType: isJSX ? FileType.JSX : FileType.JS,
|
|
name: COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
content: statementL.join(' '),
|
|
linkAfter: [],
|
|
});
|
|
}
|
|
|
|
return chunks;
|
|
}
|
|
|
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|
const next: ICodeStruct = {
|
|
...pre,
|
|
};
|
|
|
|
const isJSX = next.chunks.some(chunk => chunk.fileType === FileType.JSX);
|
|
|
|
const ir = next.ir as IWithDependency;
|
|
|
|
if (ir && ir.deps && ir.deps.length > 0) {
|
|
const packs = groupDepsByPack(ir.deps);
|
|
|
|
Object.keys(packs).forEach(pkg => {
|
|
const chunks = buildPackageImport(pkg, packs[pkg], isJSX);
|
|
next.chunks.push.apply(next.chunks, chunks);
|
|
});
|
|
}
|
|
|
|
return next;
|
|
};
|
|
|
|
export default plugin;
|