mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-12 17:08:14 +00:00
fix: 🐛 bugs about deps
This commit is contained in:
parent
84da70d9db
commit
1eabd506e3
@ -6,6 +6,7 @@
|
||||
import { SUPPORT_SCHEMA_VERSION_LIST } from '../const';
|
||||
|
||||
import { handleChildren } from '../utils/nodeToJSX';
|
||||
import { uniqueArray } from '../utils/common';
|
||||
|
||||
import {
|
||||
ChildNodeType,
|
||||
@ -24,6 +25,7 @@ import {
|
||||
IProjectSchema,
|
||||
ISchemaParser,
|
||||
IUtilItem,
|
||||
INpmPackage,
|
||||
} from '../types';
|
||||
|
||||
const defaultContainer: IContainerInfo = {
|
||||
@ -36,17 +38,15 @@ const defaultContainer: IContainerInfo = {
|
||||
};
|
||||
|
||||
class SchemaParser implements ISchemaParser {
|
||||
public validate(schema: IBasicSchema): boolean {
|
||||
validate(schema: IBasicSchema): boolean {
|
||||
if (SUPPORT_SCHEMA_VERSION_LIST.indexOf(schema.version) < 0) {
|
||||
throw new CompatibilityError(
|
||||
`Not support schema with version [${schema.version}]`,
|
||||
);
|
||||
throw new CompatibilityError(`Not support schema with version [${schema.version}]`);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public parse(schemaSrc: IProjectSchema | string): IParseResult {
|
||||
parse(schemaSrc: IProjectSchema | string): IParseResult {
|
||||
// TODO: collect utils depends in JSExpression
|
||||
const compDeps: Record<string, IExternalDependency> = {};
|
||||
const internalDeps: Record<string, IInternalDependency> = {};
|
||||
@ -64,7 +64,7 @@ class SchemaParser implements ISchemaParser {
|
||||
}
|
||||
|
||||
// 解析三方组件依赖
|
||||
schema.componentsMap.forEach(info => {
|
||||
schema.componentsMap.forEach((info) => {
|
||||
info.dependencyType = DependencyType.External;
|
||||
info.importName = info.componentName;
|
||||
compDeps[info.componentName] = info;
|
||||
@ -73,8 +73,7 @@ class SchemaParser implements ISchemaParser {
|
||||
let containers: IContainerInfo[];
|
||||
// Test if this is a lowcode component without container
|
||||
if (schema.componentsTree.length > 0) {
|
||||
const firstRoot: IContainerNodeItem = schema
|
||||
.componentsTree[0] as IContainerNodeItem;
|
||||
const firstRoot: IContainerNodeItem = schema.componentsTree[0] as IContainerNodeItem;
|
||||
|
||||
if (!firstRoot.fileName) {
|
||||
// 整个 schema 描述一个容器,且无根节点定义
|
||||
@ -85,7 +84,7 @@ class SchemaParser implements ISchemaParser {
|
||||
containers = [container];
|
||||
} else {
|
||||
// 普通带 1 到多个容器的 schema
|
||||
containers = schema.componentsTree.map(n => {
|
||||
containers = schema.componentsTree.map((n) => {
|
||||
const subRoot = n as IContainerNodeItem;
|
||||
const container: IContainerInfo = {
|
||||
...subRoot,
|
||||
@ -100,7 +99,7 @@ class SchemaParser implements ISchemaParser {
|
||||
}
|
||||
|
||||
// 建立所有容器的内部依赖索引
|
||||
containers.forEach(container => {
|
||||
containers.forEach((container) => {
|
||||
let type;
|
||||
switch (container.containerType) {
|
||||
case 'Page':
|
||||
@ -126,22 +125,20 @@ class SchemaParser implements ISchemaParser {
|
||||
});
|
||||
|
||||
// 分析容器内部组件依赖
|
||||
containers.forEach(container => {
|
||||
containers.forEach((container) => {
|
||||
if (container.children) {
|
||||
// const depNames = this.getComponentNames(container.children);
|
||||
// container.deps = uniqueArray<string>(depNames)
|
||||
// .map(depName => internalDeps[depName] || compDeps[depName])
|
||||
// .filter(dep => !!dep);
|
||||
container.deps = Object.keys(compDeps).map(
|
||||
depName => compDeps[depName],
|
||||
);
|
||||
const depNames = this.getComponentNames(container.children);
|
||||
container.deps = uniqueArray<string>(depNames, (i: string) => i)
|
||||
.map((depName) => internalDeps[depName] || compDeps[depName])
|
||||
.filter((dep) => !!dep);
|
||||
// container.deps = Object.keys(compDeps).map((depName) => compDeps[depName]);
|
||||
}
|
||||
});
|
||||
|
||||
// 分析路由配置
|
||||
const routes = containers
|
||||
.filter(container => container.containerType === 'Page')
|
||||
.map(page => {
|
||||
.filter((container) => container.containerType === 'Page')
|
||||
.map((page) => {
|
||||
const meta = page.meta as IPageMeta;
|
||||
if (meta) {
|
||||
return {
|
||||
@ -156,20 +153,28 @@ class SchemaParser implements ISchemaParser {
|
||||
});
|
||||
|
||||
const routerDeps = routes
|
||||
.map(r => internalDeps[r.componentName] || compDeps[r.componentName])
|
||||
.filter(dep => !!dep);
|
||||
.map((r) => internalDeps[r.componentName] || compDeps[r.componentName])
|
||||
.filter((dep) => !!dep);
|
||||
|
||||
// 分析 Utils 依赖
|
||||
let utils: IUtilItem[];
|
||||
if (schema.utils) {
|
||||
utils = schema.utils;
|
||||
utilsDeps = schema.utils
|
||||
.filter(u => u.type !== 'function')
|
||||
.map(u => u.content as IExternalDependency);
|
||||
utilsDeps = schema.utils.filter((u) => u.type !== 'function').map((u) => u.content as IExternalDependency);
|
||||
} else {
|
||||
utils = [];
|
||||
}
|
||||
|
||||
// 分析项目 npm 依赖
|
||||
let npms: INpmPackage[] = [];
|
||||
containers.forEach((con) => {
|
||||
const p = (con.deps || [])
|
||||
.map((dep) => (dep.dependencyType === DependencyType.External ? dep : null))
|
||||
.filter((dep) => dep !== null);
|
||||
npms.push(...((p as unknown) as INpmPackage[]));
|
||||
});
|
||||
npms = uniqueArray<INpmPackage>(npms, (i) => i.package);
|
||||
|
||||
return {
|
||||
containers,
|
||||
globalUtils: {
|
||||
@ -187,13 +192,16 @@ class SchemaParser implements ISchemaParser {
|
||||
css: schema.css,
|
||||
constants: schema.constants,
|
||||
i18n: schema.i18n,
|
||||
packages: npms,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public getComponentNames(children: ChildNodeType): string[] {
|
||||
getComponentNames(children: ChildNodeType): string[] {
|
||||
return handleChildren<string>(children, {
|
||||
node: (i: IComponentNodeItem) => [i.componentName],
|
||||
}, {
|
||||
rerun: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,11 +28,11 @@ function groupDepsByPack(deps: IDependency[]): Record<string, IDependency[]> {
|
||||
deps.forEach(dep => {
|
||||
if (dep.dependencyType === DependencyType.Internal) {
|
||||
addDep(
|
||||
`${(dep as IInternalDependency).moduleName}${dep.main || ''}`,
|
||||
`${(dep as IInternalDependency).moduleName}${`/${dep.main}` || ''}`,
|
||||
dep,
|
||||
);
|
||||
} else {
|
||||
addDep(`${(dep as IExternalDependency).package}${dep.main || ''}`, dep);
|
||||
addDep(`${(dep as IExternalDependency).package}${`/${dep.main}` || ''}`, dep);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -73,6 +73,8 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||
originTemplate: '@alifd/scaffold-lite-js',
|
||||
};
|
||||
|
||||
ir.packages.forEach((packageInfo) => (packageJson.dependencies[packageInfo.package] = packageInfo.version));
|
||||
|
||||
next.chunks.push({
|
||||
type: ChunkType.JSON,
|
||||
fileType: FileType.JSON,
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
export interface INpmPackage {
|
||||
package: string; // 组件包的名称
|
||||
version: string; // 组件包的版本
|
||||
}
|
||||
|
||||
/**
|
||||
* 外部依赖描述
|
||||
*
|
||||
* @export
|
||||
* @interface IExternalDependency
|
||||
*/
|
||||
export interface IExternalDependency extends IDependency {
|
||||
package: string; // 组件包的名称
|
||||
version: string; // 组件包的版本
|
||||
}
|
||||
export interface IExternalDependency extends INpmPackage, IDependency {}
|
||||
|
||||
export enum InternalDependencyType {
|
||||
PAGE = 'pages',
|
||||
|
||||
@ -5,6 +5,7 @@ import {
|
||||
IDependency,
|
||||
II18nMap,
|
||||
IInternalDependency,
|
||||
INpmPackage,
|
||||
IUtilItem,
|
||||
} from './index';
|
||||
|
||||
@ -42,6 +43,7 @@ export interface IProjectInfo {
|
||||
css?: string;
|
||||
constants?: Record<string, string>;
|
||||
i18n?: II18nMap;
|
||||
packages: INpmPackage[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -22,7 +22,10 @@ export function upperCaseFirst(inputValue: string): string {
|
||||
return changeCase.upperCaseFirst(inputValue);
|
||||
}
|
||||
|
||||
export function uniqueArray<T>(arr: T[]) {
|
||||
const uniqueItems = [...new Set<T>(arr)];
|
||||
export function uniqueArray<T>(arr: T[], by: (i: T) => string) {
|
||||
const map: Record<string, T> = {};
|
||||
arr.forEach((item) => (map[by(item)] = item));
|
||||
const uniqueKeys = [...new Set<string>(Object.keys(map))];
|
||||
const uniqueItems = uniqueKeys.map((key) => map[key]);
|
||||
return uniqueItems;
|
||||
}
|
||||
|
||||
@ -16,14 +16,26 @@ import { generateExpression } from './jsExpression';
|
||||
// tslint:disable-next-line: no-empty
|
||||
const noop = () => [];
|
||||
|
||||
const handleChildrenDefaultOptions = {
|
||||
rerun: false,
|
||||
};
|
||||
|
||||
export function handleChildren<T>(
|
||||
children: ChildNodeType,
|
||||
handlers: HandlerSet<T>,
|
||||
options?: {
|
||||
rerun?: boolean,
|
||||
},
|
||||
): T[] {
|
||||
const opt = {
|
||||
...handleChildrenDefaultOptions,
|
||||
...(options || {}),
|
||||
};
|
||||
|
||||
if (Array.isArray(children)) {
|
||||
const list: ChildNodeItem[] = children as ChildNodeItem[];
|
||||
return list
|
||||
.map(child => handleChildren(child, handlers))
|
||||
.map(child => handleChildren(child, handlers, opt))
|
||||
.reduce((p, c) => p.concat(c), []);
|
||||
} else if (typeof children === 'string') {
|
||||
const handler = handlers.string || handlers.common || noop;
|
||||
@ -33,7 +45,12 @@ export function handleChildren<T>(
|
||||
return handler(children as IJSExpression);
|
||||
} else {
|
||||
const handler = handlers.node || handlers.common || noop;
|
||||
return handler(children as IComponentNodeItem);
|
||||
let curRes = handler(children as IComponentNodeItem);
|
||||
if (opt.rerun && children.children) {
|
||||
const childRes = handleChildren(children.children, handlers, opt);
|
||||
curRes = curRes.concat(childRes || []);
|
||||
}
|
||||
return curRes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user