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