From 76341c8456b227192bb65537dc3d16033db0b3a1 Mon Sep 17 00:00:00 2001 From: Clarence-pan Date: Tue, 8 Mar 2022 14:25:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20package.json=20?= =?UTF-8?q?=E4=B8=AD=E8=AF=AF=E6=B7=BB=E5=8A=A0=E4=BA=86=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E7=94=A8=E5=88=B0=E7=9A=84=E6=95=B0=E6=8D=AE=E6=BA=90=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=20handler=20=E7=9A=84=E5=8C=85=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../code-generator/src/parser/SchemaParser.ts | 22 +++++++ .../framework/icejs/plugins/packageJSON.ts | 40 ++++++++++--- .../framework/rax/plugins/packageJSON.ts | 17 +----- .../code-generator/src/types/intermediate.ts | 1 + .../code-generator/src/utils/dataSource.ts | 43 ++++++++++++++ ...cejs-package-json-dependencies.schema.json | 57 +++++++++++++++++++ .../icejs-package-json-dependencies.test.ts | 49 ++++++++++++++++ 7 files changed, 206 insertions(+), 23 deletions(-) create mode 100644 modules/code-generator/src/utils/dataSource.ts create mode 100644 modules/code-generator/tests/bugfix/icejs-package-json-dependencies.schema.json create mode 100644 modules/code-generator/tests/bugfix/icejs-package-json-dependencies.test.ts diff --git a/modules/code-generator/src/parser/SchemaParser.ts b/modules/code-generator/src/parser/SchemaParser.ts index a8510e9b5..b7b9f2b0f 100644 --- a/modules/code-generator/src/parser/SchemaParser.ts +++ b/modules/code-generator/src/parser/SchemaParser.ts @@ -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(); + + // 数据源的默认类型为 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; diff --git a/modules/code-generator/src/plugins/project/framework/icejs/plugins/packageJSON.ts b/modules/code-generator/src/plugins/project/framework/icejs/plugins/packageJSON.ts index e76b423e0..f7adf6a7b 100644 --- a/modules/code-generator/src/plugins/project/framework/icejs/plugins/packageJSON.ts +++ b/modules/code-generator/src/plugins/project/framework/icejs/plugins/packageJSON.ts @@ -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 = () => { +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 = (cfg) => { const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => { const next: ICodeStruct = { ...pre, @@ -31,21 +56,18 @@ const pluginFactory: BuilderComponentPluginFactory = () => { 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', diff --git a/modules/code-generator/src/plugins/project/framework/rax/plugins/packageJSON.ts b/modules/code-generator/src/plugins/project/framework/rax/plugins/packageJSON.ts index 8363f8fae..e95a3dc0b 100644 --- a/modules/code-generator/src/plugins/project/framework/rax/plugins/packageJSON.ts +++ b/modules/code-generator/src/plugins/project/framework/rax/plugins/packageJSON.ts @@ -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 = (cfg) => { const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => { @@ -26,7 +26,7 @@ const pluginFactory: BuilderComponentPluginFactory = (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 = (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', diff --git a/modules/code-generator/src/types/intermediate.ts b/modules/code-generator/src/types/intermediate.ts index beecb7c53..43d8f0e84 100644 --- a/modules/code-generator/src/types/intermediate.ts +++ b/modules/code-generator/src/types/intermediate.ts @@ -42,6 +42,7 @@ export interface IProjectInfo { packages: INpmPackage[]; meta?: { name?: string; title?: string } | Record; config?: Record; + dataSourcesTypes?: string[]; } export interface IPageMeta { diff --git a/modules/code-generator/src/utils/dataSource.ts b/modules/code-generator/src/utils/dataSource.ts new file mode 100644 index 000000000..610f39934 --- /dev/null +++ b/modules/code-generator/src/utils/dataSource.ts @@ -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 { + 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` + ); + } +} diff --git a/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.schema.json b/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.schema.json new file mode 100644 index 000000000..52e954816 --- /dev/null +++ b/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.schema.json @@ -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": {} +} diff --git a/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.test.ts b/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.test.ts new file mode 100644 index 000000000..3aaff3ae4 --- /dev/null +++ b/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.test.ts @@ -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; + }); +}