fix: 解决 package.json 中误添加了没有用到的数据源类型的 handler 的包的问题 (#56)

This commit is contained in:
Clarence-pan 2022-03-08 14:25:35 +08:00
parent 4a01c97ea6
commit 76341c8456
7 changed files with 206 additions and 23 deletions

View File

@ -319,6 +319,7 @@ export class SchemaParser implements ISchemaParser {
containersDeps,
utilsDeps,
packages: npms || [],
dataSourcesTypes: this.collectDataSourcesTypes(schema),
},
};
}
@ -350,6 +351,27 @@ export class SchemaParser implements ISchemaParser {
}
return schema;
}
private collectDataSourcesTypes(schema: ProjectSchema): string[] {
const dataSourcesTypes = new Set<string>();
// 数据源的默认类型为 fetch
const defaultDataSourceType = 'fetch';
// 收集应用级别的数据源
schema.dataSource?.list?.forEach((ds) => {
dataSourcesTypes.add(ds.type || defaultDataSourceType);
});
// 收集容器级别的数据源(页面/组件/区块)
schema.componentsTree.forEach((rootNode) => {
rootNode.dataSource?.list?.forEach((ds) => {
dataSourcesTypes.add(ds.type || defaultDataSourceType);
});
});
return Array.from(dataSourcesTypes.values());
}
}
export default SchemaParser;

View File

@ -10,6 +10,7 @@ import {
ICodeStruct,
IProjectInfo,
} from '../../../../../types';
import { buildDataSourceDependencies } from '../../../../../utils/dataSource';
interface IIceJsPackageJSON extends PackageJSON {
ideMode: {
@ -22,7 +23,31 @@ interface IIceJsPackageJSON extends PackageJSON {
originTemplate: string;
}
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
export type IceJsPackageJsonPluginConfig = {
/**
*
*/
datasourceConfig?: {
/** 数据源引擎的版本 */
engineVersion?: string;
/** 数据源引擎的包名 */
enginePackage?: string;
/** 数据源 handlers 的版本 */
handlersVersion?: {
[key: string]: string;
};
/** 数据源 handlers 的包名 */
handlersPackages?: {
[key: string]: string;
};
};
/** 包名 */
packageName?: string;
/** 版本 */
packageVersion?: string;
};
const pluginFactory: BuilderComponentPluginFactory<IceJsPackageJsonPluginConfig> = (cfg) => {
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
const next: ICodeStruct = {
...pre,
@ -31,21 +56,18 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
const ir = next.ir as IProjectInfo;
const packageJson: IIceJsPackageJSON = {
name: '@alifd/scaffold-lite-js',
version: '0.1.5',
name: cfg?.packageName || 'icejs-demo-app',
version: cfg?.packageVersion || '0.1.5',
description: '轻量级模板,使用 JavaScript仅包含基础的 Layout。',
dependencies: {
moment: '^2.24.0',
react: '^16.4.1',
'react-dom': '^16.4.1',
'@alifd/theme-design-pro': '^0.x',
'@alilc/lowcode-datasource-engine': '*',
// TODO: 如何动态获取下面这些依赖?
'@alilc/lowcode-datasource-url-params-handler': '*',
'@alilc/lowcode-datasource-fetch-handler': '*',
'@alilc/lowcode-datasource-mtop-handler': '*',
'@alilc/lowcode-datasource-mopen-handler': '*',
'intl-messageformat': '^9.3.6',
// 数据源相关的依赖:
...buildDataSourceDependencies(ir, cfg?.datasourceConfig),
},
devDependencies: {
'@ice/spec': '^1.0.0',

View File

@ -1,4 +1,3 @@
import changeCase from 'change-case';
import { NpmInfo, PackageJSON } from '@alilc/lowcode-types';
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
@ -14,6 +13,7 @@ import { isNpmInfo } from '../../../../../utils/schema';
import { getErrorMessage } from '../../../../../utils/errors';
import { calcCompatibleVersion } from '../../../../../utils/version';
import { RaxFrameworkOptions } from '../types/RaxFrameworkOptions';
import { buildDataSourceDependencies } from '../../../../../utils/dataSource';
const pluginFactory: BuilderComponentPluginFactory<RaxFrameworkOptions> = (cfg) => {
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
@ -26,7 +26,7 @@ const pluginFactory: BuilderComponentPluginFactory<RaxFrameworkOptions> = (cfg)
const npmDeps = getNpmDependencies(ir);
const packageJson: PackageJSON = {
name: cfg?.packageName || '@alilc/rax-app-demo',
name: cfg?.packageName || 'rax-demo-app',
private: true,
version: cfg?.packageVersion || '1.0.0',
scripts: {
@ -39,18 +39,7 @@ const pluginFactory: BuilderComponentPluginFactory<RaxFrameworkOptions> = (cfg)
},
dependencies: {
// 数据源相关的依赖:
[cfg?.datasourceConfig?.enginePackage || '@alilc/lowcode-datasource-engine']:
cfg?.datasourceConfig?.engineVersion || 'latest',
// TODO: [p1] 如何动态获取下究竟用了哪些类型的数据源?
...['url-params', 'fetch', 'mtop', 'mopen'].reduce(
(acc, dsType) => ({
...acc,
[cfg?.datasourceConfig?.handlersPackages?.[dsType] ||
`@alilc/lowcode-datasource-${changeCase.kebab(dsType)}-handler`]:
cfg?.datasourceConfig?.handlersVersion?.[dsType] || 'latest',
}),
{},
),
...buildDataSourceDependencies(ir, cfg?.datasourceConfig),
// 环境判断
'universal-env': '^3.2.0',

View File

@ -42,6 +42,7 @@ export interface IProjectInfo {
packages: INpmPackage[];
meta?: { name?: string; title?: string } | Record<string, any>;
config?: Record<string, any>;
dataSourcesTypes?: string[];
}
export interface IPageMeta {

View File

@ -0,0 +1,43 @@
import changeCase from 'change-case';
import type { IProjectInfo } from '../types/intermediate';
export type DataSourceDependenciesConfig = {
/** 数据源引擎的版本 */
engineVersion?: string;
/** 数据源引擎的包名 */
enginePackage?: string;
/** 数据源 handlers 的版本 */
handlersVersion?: {
[key: string]: string;
};
/** 数据源 handlers 的包名 */
handlersPackages?: {
[key: string]: string;
};
};
export function buildDataSourceDependencies(
ir: IProjectInfo,
cfg: DataSourceDependenciesConfig = {},
): Record<string, string> {
return {
// 数据源引擎的依赖包
[cfg.enginePackage || '@alilc/lowcode-datasource-engine']: cfg.engineVersion || 'latest',
// 各种数据源的 handlers 的依赖包
...(ir.dataSourcesTypes || []).reduce(
(acc, dsType) => ({
...acc,
[getDataSourceHandlerPackageName(dsType)]: cfg.handlersVersion?.[dsType] || 'latest',
}),
{},
),
};
function getDataSourceHandlerPackageName(dsType: string) {
return (
cfg.handlersPackages?.[dsType] ||
`@alilc/lowcode-datasource-${changeCase.kebab(dsType)}-handler`
);
}
}

View File

@ -0,0 +1,57 @@
{
"version": "1.0.0",
"componentsMap": [
{
"package": "@alilc/lowcode-materials",
"version": "^1.0.0",
"exportName": "Page",
"destructuring": true,
"componentName": "Page"
},
{
"package": "@alilc/lowcode-materials",
"version": "^1.0.0",
"exportName": "Typography",
"destructuring": true,
"subName": "Text",
"componentName": "Text"
}
],
"componentsTree": [
{
"componentName": "Page",
"id": "node_dockcviv8fo1",
"props": {},
"fileName": "test",
"dataSource": {
"list": [
{
"id": "test",
"type": "fetch",
"options": {
"uri": "https://xxx.com/api/xxx"
}
}
]
},
"css": "body {\n font-size: 12px;\n}\n\n.botton {\n width: 100px;\n color: #ff00ff;\n}",
"lifeCycles": {},
"hidden": false,
"title": "",
"isLocked": false,
"condition": true,
"conditionGroup": "",
"state": {},
"children": [
{
"componentName": "Text",
"props": {
"text": "hello world"
}
}
]
}
],
"i18n": {}
}

View File

@ -0,0 +1,49 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
const testCaseBaseName = path.basename(__filename, '.test.ts');
test(testCaseBaseName, async () => {
const inputSchemaJsonFile = path.join(__dirname, `${testCaseBaseName}.schema.json`);
const outputDir = path.join(__dirname, `${testCaseBaseName}.generated`);
await exportProject(inputSchemaJsonFile, outputDir);
const generatedPackageJsonText = fs.readFileSync(
path.join(outputDir, 'demo-project/package.json'),
'utf-8',
);
const generatedPackageJson = JSON.parse(generatedPackageJsonText);
expect(generatedPackageJson.dependencies).toBeTruthy();
// 里面有的数据源则应该生成对应的 dependencies
expect(generatedPackageJson.dependencies).toMatchObject({
'@alilc/lowcode-datasource-engine': 'latest',
'@alilc/lowcode-datasource-fetch-handler': 'latest',
});
// 里面没有的,则不应该生成对应的 dependencies
expect(generatedPackageJson.dependencies).not.toMatchObject({
'@alilc/lowcode-datasource-url-params-handler': 'latest',
'@alilc/lowcode-datasource-mtop-handler': 'latest',
'@alilc/lowcode-datasource-mopen-handler': 'latest',
});
});
function exportProject(inputPath: string, outputPath: string) {
const schemaJson = fs.readFileSync(inputPath, { encoding: 'utf8' });
const newSchema = schemaJson;
const builder = CodeGenerator.solutions.icejs();
return builder.generateProject(newSchema).then(async (result) => {
// displayResultInConsole(result);
const publisher = CodeGenerator.publishers.disk();
await publisher.publish({
project: result,
outputPath,
projectSlug: 'demo-project',
createProjectFolder: true,
});
return result;
});
}