Skip to content

Commit 708889b

Browse files
authored
fix(plugin): optional plugin also need to calc order (#256)
* fix(plugin): optional plugin also need to calc order * test: update snapshot
1 parent b3bf9ca commit 708889b

File tree

5 files changed

+98
-6
lines changed

5 files changed

+98
-6
lines changed

src/plugin/impl.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,29 @@ export class Plugin implements PluginType {
5151
}
5252

5353
public checkDepExisted(pluginMap: PluginMap) {
54-
for (const { name: pluginName, optional } of this.metadata.dependencies ?? []) {
54+
if (!this.metadata.dependencies) {
55+
return;
56+
}
57+
58+
for (let i = 0; i < this.metadata.dependencies.length; i++) {
59+
const { name: pluginName, optional } = this.metadata.dependencies[i];
5560
const instance = pluginMap.get(pluginName);
5661
if (!instance || !instance.enable) {
5762
if (optional) {
5863
this.logger?.warn(`Plugin ${this.name} need have optional dependency: ${pluginName}.`);
5964
} else {
6065
throw new Error(`Plugin ${this.name} need have dependency: ${pluginName}.`);
6166
}
67+
} else {
68+
// Plugin exist and enabled, need calc edge
69+
this.metadata.dependencies[i]._enabled = true;
6270
}
6371
}
6472
}
6573

6674
public getDepEdgeList(): [string, string][] {
6775
return this.metadata.dependencies
68-
?.filter(({ optional }) => !optional)
76+
?.filter(({ optional, _enabled }) => !optional || _enabled)
6977
?.map(({ name: depPluginName }) => [this.name, depPluginName]) ?? [];
7078
}
7179

src/plugin/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ export interface PluginMetadata {
1515
export interface PluginDependencyItem {
1616
name: string;
1717
optional?: boolean;
18+
19+
// Only exist on runtime, cannot config in meta.json
20+
_enabled?: boolean;
1821
}
1922

2023
export interface PluginConfigItem {

test/__snapshots__/scanner.test.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ Object {
278278
"pluginMetadata": Object {
279279
"dependencies": Array [
280280
Object {
281-
"name": "plugin-e",
281+
"name": "plugin-c",
282282
"optional": true,
283283
},
284284
],
@@ -508,7 +508,7 @@ Object {
508508
"pluginMetadata": Object {
509509
"dependencies": Array [
510510
Object {
511-
"name": "plugin-e",
511+
"name": "plugin-c",
512512
"optional": true,
513513
},
514514
],

test/fixtures/plugins/plugin_d/meta.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "plugin-d",
33
"dependencies": [
44
{
5-
"name": "plugin-e",
5+
"name": "plugin-c",
66
"optional": true
77
}
88
]

test/plugin.test.ts

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,91 @@ describe('test/app.test.ts', () => {
201201
expect(plugin).toBeInstanceOf(Plugin);
202202
expect(plugin.enable).toBeTruthy();
203203
});
204-
expect(mockWarnFn).toBeCalledWith(`Plugin plugin-d need have optional dependency: plugin-e.`);
204+
expect(mockWarnFn).toBeCalledWith(`Plugin plugin-d need have optional dependency: plugin-c.`);
205205

206206
// restore warn
207207
console.warn = originWarn;
208208
});
209+
210+
it('should not throw if optional dependence disabled', async () => {
211+
const mockPluginConfig = {
212+
'plugin-c': {
213+
enable: false,
214+
path: path.resolve(__dirname, `${pluginPrefix}/plugin_c`),
215+
manifest: {
216+
pluginMeta: {
217+
path: path.resolve(__dirname, `${pluginPrefix}/plugin_c/meta.js`),
218+
extname: '.js',
219+
filename: 'meta.js',
220+
},
221+
},
222+
},
223+
'plugin-d': {
224+
enable: true,
225+
path: path.resolve(__dirname, `${pluginPrefix}/plugin_d`),
226+
manifest: {
227+
pluginMeta: {
228+
path: path.resolve(__dirname, `${pluginPrefix}/plugin_d/meta.js`),
229+
extname: '.js',
230+
filename: 'meta.js',
231+
},
232+
},
233+
},
234+
};
235+
236+
// mock warn
237+
const originWarn = console.warn;
238+
const mockWarnFn = jest.fn();
239+
console.warn = mockWarnFn;
240+
const pluginList = await PluginFactory.createFromConfig(mockPluginConfig, {
241+
logger: new Logger(),
242+
});
243+
expect(pluginList.length).toEqual(1);
244+
pluginList.forEach(plugin => {
245+
expect(plugin).toBeInstanceOf(Plugin);
246+
expect(plugin.enable).toBeTruthy();
247+
});
248+
expect(mockWarnFn).toBeCalledWith(`Plugin plugin-d need have optional dependency: plugin-c.`);
249+
250+
// restore warn
251+
console.warn = originWarn;
252+
});
253+
254+
it('should calc order if optional dependence enabled', async () => {
255+
const mockPluginConfig = {
256+
'plugin-d': {
257+
enable: true,
258+
path: path.resolve(__dirname, `${pluginPrefix}/plugin_d`),
259+
manifest: {
260+
pluginMeta: {
261+
path: path.resolve(__dirname, `${pluginPrefix}/plugin_d/meta.js`),
262+
extname: '.js',
263+
filename: 'meta.js',
264+
},
265+
},
266+
},
267+
'plugin-c': {
268+
enable: true,
269+
path: path.resolve(__dirname, `${pluginPrefix}/plugin_c`),
270+
manifest: {
271+
pluginMeta: {
272+
path: path.resolve(__dirname, `${pluginPrefix}/plugin_c/meta.js`),
273+
extname: '.js',
274+
filename: 'meta.js',
275+
},
276+
},
277+
},
278+
};
279+
280+
const pluginList = await PluginFactory.createFromConfig(mockPluginConfig, {
281+
logger: new Logger(),
282+
});
283+
expect(pluginList.length).toEqual(2);
284+
pluginList.forEach(plugin => {
285+
expect(plugin).toBeInstanceOf(Plugin);
286+
expect(plugin.enable).toBeTruthy();
287+
});
288+
expect(pluginList.map(plugin => plugin.name)).toStrictEqual(['plugin-c', 'plugin-d']);
289+
});
209290
});
210291
});

0 commit comments

Comments
 (0)