mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-03-03 16:07:24 +00:00
feat: 🎸 搞定 Rax 出码的时候的 package.json 中的 dependencies
This commit is contained in:
parent
4572b53f47
commit
eba172ce51
@ -26,6 +26,7 @@
|
|||||||
"change-case": "^3.1.0",
|
"change-case": "^3.1.0",
|
||||||
"jszip": "^3.5.0",
|
"jszip": "^3.5.0",
|
||||||
"prettier": "^2.0.2",
|
"prettier": "^2.0.2",
|
||||||
|
"semver": "^7.3.2",
|
||||||
"short-uuid": "^3.1.1"
|
"short-uuid": "^3.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -40,7 +41,7 @@
|
|||||||
"compileEnhancements": false,
|
"compileEnhancements": false,
|
||||||
"snapshotDir": "test/fixtures/__snapshots__",
|
"snapshotDir": "test/fixtures/__snapshots__",
|
||||||
"files": [
|
"files": [
|
||||||
"test/*.test.ts"
|
"test/**/*.test.ts"
|
||||||
],
|
],
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"ts"
|
"ts"
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import {
|
|||||||
IComponentNodeItem,
|
IComponentNodeItem,
|
||||||
IContainerInfo,
|
IContainerInfo,
|
||||||
IContainerNodeItem,
|
IContainerNodeItem,
|
||||||
|
IDependency,
|
||||||
IExternalDependency,
|
IExternalDependency,
|
||||||
IInternalDependency,
|
IInternalDependency,
|
||||||
InternalDependencyType,
|
InternalDependencyType,
|
||||||
@ -138,6 +139,8 @@ class SchemaParser implements ISchemaParser {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const containersDeps = ([] as IDependency[]).concat(...containers.map(c => c.deps || []));
|
||||||
|
|
||||||
// 分析路由配置
|
// 分析路由配置
|
||||||
const routes = containers
|
const routes = containers
|
||||||
.filter(container => container.containerType === 'Page')
|
.filter(container => container.containerType === 'Page')
|
||||||
@ -187,6 +190,8 @@ class SchemaParser implements ISchemaParser {
|
|||||||
css: schema.css,
|
css: schema.css,
|
||||||
constants: schema.constants,
|
constants: schema.constants,
|
||||||
i18n: schema.i18n,
|
i18n: schema.i18n,
|
||||||
|
containersDeps,
|
||||||
|
utilsDeps,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { NpmInfo } from '@ali/lowcode-types';
|
||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -9,6 +10,8 @@ import {
|
|||||||
IPackageJSON,
|
IPackageJSON,
|
||||||
IProjectInfo,
|
IProjectInfo,
|
||||||
} from '../../../../../types';
|
} from '../../../../../types';
|
||||||
|
import { isNpmInfo } from '../../../../../utils/schema';
|
||||||
|
import { calcCompatibleVersion } from '../../../../../utils/version';
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||||
@ -18,6 +21,8 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
const ir = next.ir as IProjectInfo;
|
||||||
|
|
||||||
|
const npmDeps = getNpmDependencies(ir);
|
||||||
|
|
||||||
const packageJson: IPackageJSON = {
|
const packageJson: IPackageJSON = {
|
||||||
name: '@ali/rax-app-demo',
|
name: '@ali/rax-app-demo',
|
||||||
private: true,
|
private: true,
|
||||||
@ -34,8 +39,13 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
rax: '^1.1.0',
|
rax: '^1.1.0',
|
||||||
'rax-app': '^2.0.0',
|
'rax-app': '^2.0.0',
|
||||||
'rax-document': '^0.1.0',
|
'rax-document': '^0.1.0',
|
||||||
'rax-text': '^1.0.0',
|
...npmDeps.reduce(
|
||||||
'rax-view': '^1.0.0',
|
(acc, npm) => ({
|
||||||
|
...acc,
|
||||||
|
[npm.package]: npm.version || '*',
|
||||||
|
}),
|
||||||
|
{} as Record<string, string>,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
devDependencies: {
|
devDependencies: {
|
||||||
'build-plugin-rax-app': '^5.0.0',
|
'build-plugin-rax-app': '^5.0.0',
|
||||||
@ -66,3 +76,36 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default pluginFactory;
|
export default pluginFactory;
|
||||||
|
|
||||||
|
function getNpmDependencies(project: IProjectInfo): NpmInfo[] {
|
||||||
|
const npmDeps: NpmInfo[] = [];
|
||||||
|
const npmNameToPkgMap = new Map<string, NpmInfo>();
|
||||||
|
|
||||||
|
const allDeps = [...(project.containersDeps || []), ...(project.utilsDeps || [])];
|
||||||
|
|
||||||
|
allDeps.forEach((dep) => {
|
||||||
|
if (!isNpmInfo(dep)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const existing = npmNameToPkgMap.get(dep.package);
|
||||||
|
if (!existing) {
|
||||||
|
npmNameToPkgMap.set(dep.package, dep);
|
||||||
|
npmDeps.push(dep);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existing.version !== dep.version) {
|
||||||
|
try {
|
||||||
|
npmNameToPkgMap.set(dep.package, {
|
||||||
|
...existing,
|
||||||
|
version: calcCompatibleVersion(existing.version, dep.version),
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Cannot find compatible version for ${dep.package}. Detail: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return npmDeps;
|
||||||
|
}
|
||||||
|
|||||||
@ -42,6 +42,8 @@ export interface IProjectInfo {
|
|||||||
css?: string;
|
css?: string;
|
||||||
constants?: Record<string, string>;
|
constants?: Record<string, string>;
|
||||||
i18n?: II18nMap;
|
i18n?: II18nMap;
|
||||||
|
containersDeps?: IDependency[];
|
||||||
|
utilsDeps?: IDependency[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
import { ContainerSchema } from '@ali/lowcode-types';
|
import { ContainerSchema, NpmInfo } from '@ali/lowcode-types';
|
||||||
|
|
||||||
export function isContainerSchema(x: any): x is ContainerSchema {
|
export function isContainerSchema(x: any): x is ContainerSchema {
|
||||||
return typeof x === 'object' && x && typeof x.componentName === 'string' && typeof x.fileName === 'string';
|
return typeof x === 'object' && x && typeof x.componentName === 'string' && typeof x.fileName === 'string';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isNpmInfo(x: any): x is NpmInfo {
|
||||||
|
return typeof x === 'object' && x && typeof x.package === 'string';
|
||||||
|
}
|
||||||
|
|||||||
29
packages/code-generator/src/utils/version.ts
Normal file
29
packages/code-generator/src/utils/version.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import semver from 'semver';
|
||||||
|
|
||||||
|
export function calcCompatibleVersion(v1: string | undefined | null, v2: string | undefined | null): string {
|
||||||
|
if (!v1 && !v2) {
|
||||||
|
return '*';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v1 || v1 === '*') {
|
||||||
|
return v2 || '*';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v2 || v2 === '*') {
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v1 === v2) {
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!semver.intersects(v1, v2, { loose: true })) {
|
||||||
|
throw new Error(`no compatible versions for "${v1}" and "${v2}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (semver.subset(v1, v2, { loose: true })) {
|
||||||
|
return v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v2;
|
||||||
|
}
|
||||||
@ -13,8 +13,8 @@
|
|||||||
"rax": "^1.1.0",
|
"rax": "^1.1.0",
|
||||||
"rax-app": "^2.0.0",
|
"rax-app": "^2.0.0",
|
||||||
"rax-document": "^0.1.0",
|
"rax-document": "^0.1.0",
|
||||||
"rax-text": "^1.0.0",
|
"rax-view": "^1.0.0",
|
||||||
"rax-view": "^1.0.0"
|
"rax-text": "^1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"build-plugin-rax-app": "^5.0.0",
|
"build-plugin-rax-app": "^5.0.0",
|
||||||
|
|||||||
@ -85,7 +85,11 @@ function ensureShellExec(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (res.status !== 0) {
|
if (res.status !== 0) {
|
||||||
throw new Error(`Shell command "${shellCmd} ${args.slice(0,2).join(' ')}..." failed with status: ${res.status} (Full command: "${shellCmd} ${args.join(' ')}" )`);
|
throw new Error(
|
||||||
|
`Shell command "${shellCmd} ${args.slice(0, 2).join(' ')}..." failed with status: ${
|
||||||
|
res.status
|
||||||
|
} (Full command: "${shellCmd} ${args.join(' ')}" )`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
50
packages/code-generator/test/utils/version.test.ts
Normal file
50
packages/code-generator/test/utils/version.test.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import test from 'ava';
|
||||||
|
import type { ExecutionContext, Macro } from 'ava';
|
||||||
|
import { calcCompatibleVersion } from '../../src/utils/version';
|
||||||
|
|
||||||
|
const NO_COMPATIBLE_VERSIONS = /no compatible versions/;
|
||||||
|
|
||||||
|
const testCalcCompatibleVersion: Macro<any[]> = (
|
||||||
|
t: ExecutionContext<{}>,
|
||||||
|
input: [string | null | undefined, string | null | undefined],
|
||||||
|
expected: string,
|
||||||
|
error?: { message: RegExp },
|
||||||
|
) => {
|
||||||
|
if (!error) {
|
||||||
|
t.is(calcCompatibleVersion(input[0], input[1]), expected);
|
||||||
|
t.is(calcCompatibleVersion(input[1], input[0]), expected); // 应该满足交换律
|
||||||
|
} else {
|
||||||
|
t.throws(() => {
|
||||||
|
calcCompatibleVersion(input[0], input[1]);
|
||||||
|
}, error.message);
|
||||||
|
t.throws(() => {
|
||||||
|
calcCompatibleVersion(input[1], input[0]); // 应该满足交换律
|
||||||
|
}, error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
testCalcCompatibleVersion.title = (providedTitle: string | undefined, ...args: any[]): string => {
|
||||||
|
const [input, expected] = args;
|
||||||
|
return `calc compatible versions "${input[0]}" & "${input[1]}" should be "${expected}"`;
|
||||||
|
};
|
||||||
|
|
||||||
|
test(testCalcCompatibleVersion, ['*', '*'], '*');
|
||||||
|
test(testCalcCompatibleVersion, ['1.0.0', '1.0.0'], '1.0.0');
|
||||||
|
test(testCalcCompatibleVersion, ['^1.0.0', '^1.0.0'], '^1.0.0');
|
||||||
|
|
||||||
|
test(testCalcCompatibleVersion, ['*', undefined], '*');
|
||||||
|
|
||||||
|
test(testCalcCompatibleVersion, [undefined, undefined], '*');
|
||||||
|
|
||||||
|
test(testCalcCompatibleVersion, ['^1.0.0', undefined], '^1.0.0');
|
||||||
|
|
||||||
|
test(testCalcCompatibleVersion, ['*', '^1.0.0'], '^1.0.0');
|
||||||
|
test(testCalcCompatibleVersion, ['^1.0.0', '^1.0.2'], '^1.0.2');
|
||||||
|
test(testCalcCompatibleVersion, ['^1.2.0', '^1.1.2'], '^1.2.0');
|
||||||
|
test(testCalcCompatibleVersion, ['^1.0.0', '1.0.2'], '1.0.2');
|
||||||
|
|
||||||
|
test(testCalcCompatibleVersion, ['^0.2.0', '^0.1.2'], 'error', { message: NO_COMPATIBLE_VERSIONS });
|
||||||
|
|
||||||
|
test(testCalcCompatibleVersion, ['>0.2.0', '^0.1.2'], 'error', { message: NO_COMPATIBLE_VERSIONS });
|
||||||
|
|
||||||
|
test(testCalcCompatibleVersion, ['1.0.1', '1.0.2'], 'error', { message: NO_COMPATIBLE_VERSIONS });
|
||||||
Loading…
x
Reference in New Issue
Block a user