1 | const ChainedMap = require('./ChainedMap');
|
2 | const ChainedSet = require('./ChainedSet');
|
3 | const Resolve = require('./Resolve');
|
4 | const ResolveLoader = require('./ResolveLoader');
|
5 | const Output = require('./Output');
|
6 | const DevServer = require('./DevServer');
|
7 | const Plugin = require('./Plugin');
|
8 | const Module = require('./Module');
|
9 | const Optimization = require('./Optimization');
|
10 | const Performance = require('./Performance');
|
11 |
|
12 | module.exports = class extends ChainedMap {
|
13 | constructor() {
|
14 | super();
|
15 | this.devServer = new DevServer(this);
|
16 | this.entryPoints = new ChainedMap(this);
|
17 | this.module = new Module(this);
|
18 | this.node = new ChainedMap(this);
|
19 | this.optimization = new Optimization(this);
|
20 | this.output = new Output(this);
|
21 | this.performance = new Performance(this);
|
22 | this.plugins = new ChainedMap(this);
|
23 | this.resolve = new Resolve(this);
|
24 | this.resolveLoader = new ResolveLoader(this);
|
25 | this.extend([
|
26 | 'amd',
|
27 | 'bail',
|
28 | 'cache',
|
29 | 'context',
|
30 | 'devtool',
|
31 | 'externals',
|
32 | 'loader',
|
33 | 'mode',
|
34 | 'name',
|
35 | 'parallelism',
|
36 | 'profile',
|
37 | 'recordsInputPath',
|
38 | 'recordsPath',
|
39 | 'recordsOutputPath',
|
40 | 'stats',
|
41 | 'target',
|
42 | 'watch',
|
43 | 'watchOptions',
|
44 | ]);
|
45 | }
|
46 |
|
47 | static toString(config, { verbose = false, configPrefix = 'config' } = {}) {
|
48 |
|
49 | const stringify = require('javascript-stringify');
|
50 |
|
51 | return stringify(
|
52 | config,
|
53 | (value, indent, stringify) => {
|
54 |
|
55 | if (value && value.__pluginName) {
|
56 | const prefix = `/* ${configPrefix}.${value.__pluginType}('${
|
57 | value.__pluginName
|
58 | }') */\n`;
|
59 | const constructorExpression = value.__pluginPath
|
60 | ?
|
61 |
|
62 | `(require(${stringify(value.__pluginPath)}))`
|
63 | : value.__pluginConstructorName;
|
64 |
|
65 | if (constructorExpression) {
|
66 |
|
67 |
|
68 | const args = stringify(value.__pluginArgs).slice(1, -1);
|
69 | return `${prefix}new ${constructorExpression}(${args})`;
|
70 | }
|
71 | return (
|
72 | prefix +
|
73 | stringify(
|
74 | value.__pluginArgs && value.__pluginArgs.length
|
75 | ? { args: value.__pluginArgs }
|
76 | : {}
|
77 | )
|
78 | );
|
79 | }
|
80 |
|
81 |
|
82 | if (value && value.__ruleNames) {
|
83 | const prefix = `/* ${configPrefix}.module.rule('${
|
84 | value.__ruleNames[0]
|
85 | }')${value.__ruleNames
|
86 | .slice(1)
|
87 | .map(r => `.oneOf('${r}')`)
|
88 | .join('')}${
|
89 | value.__useName ? `.use('${value.__useName}')` : ``
|
90 | } */\n`;
|
91 | return prefix + stringify(value);
|
92 | }
|
93 |
|
94 |
|
95 | if (typeof value === 'function') {
|
96 | if (value.__expression) {
|
97 | return value.__expression;
|
98 | }
|
99 | if (!verbose && value.toString().length > 100) {
|
100 | return `function () { /* omitted long function */ }`;
|
101 | }
|
102 | }
|
103 |
|
104 | return stringify(value);
|
105 | },
|
106 | 2
|
107 | );
|
108 | }
|
109 |
|
110 | entry(name) {
|
111 | return this.entryPoints.getOrCompute(name, () => new ChainedSet(this));
|
112 | }
|
113 |
|
114 | plugin(name) {
|
115 | return this.plugins.getOrCompute(name, () => new Plugin(this, name));
|
116 | }
|
117 |
|
118 | toConfig() {
|
119 | const entryPoints = this.entryPoints.entries() || {};
|
120 |
|
121 | return this.clean(
|
122 | Object.assign(this.entries() || {}, {
|
123 | node: this.node.entries(),
|
124 | output: this.output.entries(),
|
125 | resolve: this.resolve.toConfig(),
|
126 | resolveLoader: this.resolveLoader.toConfig(),
|
127 | devServer: this.devServer.toConfig(),
|
128 | module: this.module.toConfig(),
|
129 | optimization: this.optimization.toConfig(),
|
130 | plugins: this.plugins.values().map(plugin => plugin.toConfig()),
|
131 | performance: this.performance.entries(),
|
132 | entry: Object.keys(entryPoints).reduce(
|
133 | (acc, key) =>
|
134 | Object.assign(acc, { [key]: entryPoints[key].values() }),
|
135 | {}
|
136 | ),
|
137 | })
|
138 | );
|
139 | }
|
140 |
|
141 | toString(options) {
|
142 | return module.exports.toString(this.toConfig(), options);
|
143 | }
|
144 |
|
145 | merge(obj = {}, omit = []) {
|
146 | const omissions = [
|
147 | 'node',
|
148 | 'output',
|
149 | 'resolve',
|
150 | 'resolveLoader',
|
151 | 'devServer',
|
152 | 'optimization',
|
153 | 'performance',
|
154 | 'module',
|
155 | ];
|
156 |
|
157 | if (!omit.includes('entry') && 'entry' in obj) {
|
158 | Object.keys(obj.entry).forEach(name =>
|
159 | this.entry(name).merge([].concat(obj.entry[name]))
|
160 | );
|
161 | }
|
162 |
|
163 | if (!omit.includes('plugin') && 'plugin' in obj) {
|
164 | Object.keys(obj.plugin).forEach(name =>
|
165 | this.plugin(name).merge(obj.plugin[name])
|
166 | );
|
167 | }
|
168 |
|
169 | omissions.forEach(key => {
|
170 | if (!omit.includes(key) && key in obj) {
|
171 | this[key].merge(obj[key]);
|
172 | }
|
173 | });
|
174 |
|
175 | return super.merge(obj, [...omit, ...omissions, 'entry', 'plugin']);
|
176 | }
|
177 | };
|