UNPKG

1.93 kBJavaScriptView Raw
1const ChainedMap = require('./ChainedMap');
2const Orderable = require('./Orderable');
3
4module.exports = Orderable(
5 class extends ChainedMap {
6 constructor(parent, name, type = 'plugin') {
7 super(parent);
8 this.name = name;
9 this.type = type;
10 this.extend(['init']);
11
12 this.init((Plugin, args = []) => {
13 if (typeof Plugin === 'function') {
14 return new Plugin(...args);
15 }
16 return Plugin;
17 });
18 }
19
20 use(plugin, args = []) {
21 return this.set('plugin', plugin).set('args', args);
22 }
23
24 tap(f) {
25 this.set('args', f(this.get('args') || []));
26 return this;
27 }
28
29 merge(obj, omit = []) {
30 if ('plugin' in obj) {
31 this.set('plugin', obj.plugin);
32 }
33
34 if ('args' in obj) {
35 this.set('args', obj.args);
36 }
37
38 return super.merge(obj, [...omit, 'args', 'plugin']);
39 }
40
41 toConfig() {
42 const init = this.get('init');
43 let plugin = this.get('plugin');
44 const args = this.get('args');
45 let pluginPath = null;
46
47 // Support using the path to a plugin rather than the plugin itself,
48 // allowing expensive require()s to be skipped in cases where the plugin
49 // or webpack configuration won't end up being used.
50 if (typeof plugin === 'string') {
51 pluginPath = plugin;
52 // eslint-disable-next-line global-require, import/no-dynamic-require
53 plugin = require(pluginPath);
54 }
55
56 const constructorName = plugin.__expression
57 ? `(${plugin.__expression})`
58 : plugin.name;
59
60 const config = init(plugin, args);
61
62 Object.defineProperties(config, {
63 __pluginName: { value: this.name },
64 __pluginType: { value: this.type },
65 __pluginArgs: { value: args },
66 __pluginConstructorName: { value: constructorName },
67 __pluginPath: { value: pluginPath },
68 });
69
70 return config;
71 }
72 }
73);