Skip to content

Commit a4908c6

Browse files
authored
feat: scan framework dependencies as optional module (#184)
<!-- Thank you for your pull request. Please review below requirements. Bug fixes and new features should include tests and possibly benchmarks. Contributors guide: https://github.com/eggjs/egg/blob/master/CONTRIBUTING.md 感谢您贡献代码。请确认下列 checklist 的完成情况。 Bug 修复和新功能必须包含测试,必要时请附上性能测试。 Contributors guide: https://github.com/eggjs/egg/blob/master/CONTRIBUTING.md --> ##### Checklist <!-- Remove items that do not apply. For completed items, change [ ] to [x]. --> - [x] `npm test` passes - [x] tests and/or benchmarks are included - [ ] documentation is changed or added - [x] commit message follows commit guidelines ##### Affected core subsystem(s) <!-- Provide affected core subsystem(s). --> ##### Description of change <!-- Provide a description of the change below this comment. --> <!-- - any feature? - close https://github.com/eggjs/egg/ISSUE_URL -->
1 parent 3379384 commit a4908c6

27 files changed

Lines changed: 289 additions & 156 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ plugin/tegg/test/fixtures/apps/**/*.js
4040
!benchmark/**/*.js
4141
!standalone/standalone/test/fixtures/**/node_modules
4242
!standalone/standalone/test/fixtures/**/node_modules/**/*.js
43+
!plugin/tegg/test/fixtures/**/node_modules

core/common-util/src/Graph.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface GraphNodeObj {
77
export class GraphNode<T extends GraphNodeObj> {
88
val: T;
99
toNodeMap: Map<string, GraphNode<T>> = new Map();
10+
fromNodeMap: Map<string, GraphNode<T>> = new Map();
1011

1112
constructor(val: T) {
1213
this.val = val;
@@ -24,6 +25,14 @@ export class GraphNode<T extends GraphNodeObj> {
2425
return true;
2526
}
2627

28+
addFromVertex(node: GraphNode<T>) {
29+
if (this.fromNodeMap.has(node.id)) {
30+
return false;
31+
}
32+
this.fromNodeMap.set(node.id, node);
33+
return true;
34+
}
35+
2736
[inspect]() {
2837
return this.toJSON();
2938
}
@@ -32,6 +41,7 @@ export class GraphNode<T extends GraphNodeObj> {
3241
return {
3342
val: this.val,
3443
toNodes: Array.from(this.toNodeMap.values()),
44+
fromNodes: Array.from(this.fromNodeMap.values()),
3545
};
3646
}
3747

@@ -84,6 +94,7 @@ export class Graph<T extends GraphNodeObj> {
8494
}
8595

8696
addEdge(from: GraphNode<T>, to: GraphNode<T>): boolean {
97+
to.addFromVertex(from);
8798
return from.addToVertex(to);
8899
}
89100

core/common-util/src/ModuleConfig.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@ import extend from 'extend2';
99
export interface ModuleReference {
1010
name: string;
1111
path: string;
12+
optional?: boolean;
1213
}
1314

1415
export interface InlineModuleReferenceConfig {
1516
path: string;
17+
optional?: boolean;
1618
}
1719

1820
export interface NpmModuleReferenceConfig {
1921
package: string;
22+
optional?: boolean;
2023
}
2124

2225
export type ModuleReferenceConfig = InlineModuleReferenceConfig | NpmModuleReferenceConfig;

core/metadata/src/model/AppGraph.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ export class AppGraph {
249249
throw new Error('module has recursive deps: ' + loopPath);
250250
}
251251
this.moduleConfigList = this.graph.sort()
252+
.filter(t => {
253+
return t.val.moduleConfig.optional !== true || t.fromNodeMap.size > 0;
254+
})
252255
.map(t => t.val.moduleConfig);
253256
}
254257
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import assert from 'assert';
2+
import path from 'path';
3+
import { AppGraph, ModuleNode } from '../src/model/AppGraph';
4+
import { RootProto } from './fixtures/modules/app-graph-modules/root/Root';
5+
import { UsedProto } from './fixtures/modules/app-graph-modules/used/Used';
6+
import { UnusedProto } from './fixtures/modules/app-graph-modules/unused/Unused';
7+
8+
describe('test/LoadUnit/AppGraph.test.ts', () => {
9+
it('optional module dep should work', () => {
10+
const graph = new AppGraph();
11+
const rootModuleNode = new ModuleNode({
12+
name: 'foo',
13+
path: path.join(__dirname, './fixtures/modules/app-graph-modules/root'),
14+
});
15+
rootModuleNode.addClazz(RootProto);
16+
graph.addNode(rootModuleNode);
17+
const usedOptionalModuleNode = new ModuleNode({
18+
name: 'usedOptionalModuleNode',
19+
path: path.join(__dirname, './fixtures/modules/app-graph-modules/used'),
20+
optional: true,
21+
});
22+
usedOptionalModuleNode.addClazz(UsedProto);
23+
graph.addNode(usedOptionalModuleNode);
24+
const unusedOptionalModuleNode = new ModuleNode({
25+
name: 'unusedOptionalModuleNode',
26+
path: path.join(__dirname, './fixtures/modules/app-graph-modules/unused'),
27+
optional: true,
28+
});
29+
unusedOptionalModuleNode.addClazz(UnusedProto);
30+
graph.addNode(unusedOptionalModuleNode);
31+
graph.build();
32+
graph.sort();
33+
assert(graph.moduleConfigList.length === 2);
34+
});
35+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { SingletonProto, Inject } from '@eggjs/core-decorator';
2+
import { UsedProto } from '../used/Used';
3+
4+
@SingletonProto()
5+
export class RootProto {
6+
@Inject() usedProto: UsedProto;
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "root",
3+
"eggModule": {
4+
"name": "root"
5+
}
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { SingletonProto } from '@eggjs/core-decorator';
2+
3+
@SingletonProto()
4+
export class UnusedProto {
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "unused",
3+
"eggModule": {
4+
"name": "unused"
5+
}
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { AccessLevel, SingletonProto } from '@eggjs/core-decorator';
2+
3+
@SingletonProto({
4+
accessLevel: AccessLevel.PUBLIC,
5+
})
6+
export class UsedProto {
7+
}

0 commit comments

Comments
 (0)