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}('${value.__pluginName}') */\n`;
|
57 | const constructorExpression = value.__pluginPath
|
58 | ?
|
59 |
|
60 | `(require(${stringify(value.__pluginPath)}))`
|
61 | : value.__pluginConstructorName;
|
62 |
|
63 | if (constructorExpression) {
|
64 |
|
65 |
|
66 | const args = stringify(value.__pluginArgs).slice(1, -1);
|
67 | return `${prefix}new ${constructorExpression}(${args})`;
|
68 | }
|
69 | return (
|
70 | prefix +
|
71 | stringify(
|
72 | value.__pluginArgs && value.__pluginArgs.length
|
73 | ? { args: value.__pluginArgs }
|
74 | : {},
|
75 | )
|
76 | );
|
77 | }
|
78 |
|
79 |
|
80 | if (value && value.__ruleNames) {
|
81 | const prefix = `/* ${configPrefix}.module.rule('${
|
82 | value.__ruleNames[0]
|
83 | }')${value.__ruleNames
|
84 | .slice(1)
|
85 | .map(r => `.oneOf('${r}')`)
|
86 | .join('')}${
|
87 | value.__useName ? `.use('${value.__useName}')` : ``
|
88 | } */\n`;
|
89 | return prefix + stringify(value);
|
90 | }
|
91 |
|
92 | if (value && value.__expression) {
|
93 | return value.__expression;
|
94 | }
|
95 |
|
96 |
|
97 | if (typeof value === 'function') {
|
98 | if (!verbose && value.toString().length > 100) {
|
99 | return `function () { /* omitted long function */ }`;
|
100 | }
|
101 | }
|
102 |
|
103 | return stringify(value);
|
104 | },
|
105 | 2,
|
106 | );
|
107 | }
|
108 |
|
109 | entry(name) {
|
110 | return this.entryPoints.getOrCompute(name, () => new ChainedSet(this));
|
111 | }
|
112 |
|
113 | plugin(name) {
|
114 | return this.plugins.getOrCompute(name, () => new Plugin(this, name));
|
115 | }
|
116 |
|
117 | toConfig() {
|
118 | const entryPoints = this.entryPoints.entries() || {};
|
119 |
|
120 | return this.clean(
|
121 | Object.assign(this.entries() || {}, {
|
122 | node: this.node.entries(),
|
123 | output: this.output.entries(),
|
124 | resolve: this.resolve.toConfig(),
|
125 | resolveLoader: this.resolveLoader.toConfig(),
|
126 | devServer: this.devServer.toConfig(),
|
127 | module: this.module.toConfig(),
|
128 | optimization: this.optimization.toConfig(),
|
129 | plugins: this.plugins.values().map(plugin => plugin.toConfig()),
|
130 | performance: this.performance.entries(),
|
131 | entry: Object.keys(entryPoints).reduce(
|
132 | (acc, key) =>
|
133 | Object.assign(acc, { [key]: entryPoints[key].values() }),
|
134 | {},
|
135 | ),
|
136 | }),
|
137 | );
|
138 | }
|
139 |
|
140 | toString(options) {
|
141 | return module.exports.toString(this.toConfig(), options);
|
142 | }
|
143 |
|
144 | merge(obj = {}, omit = []) {
|
145 | const omissions = [
|
146 | 'node',
|
147 | 'output',
|
148 | 'resolve',
|
149 | 'resolveLoader',
|
150 | 'devServer',
|
151 | 'optimization',
|
152 | 'performance',
|
153 | 'module',
|
154 | ];
|
155 |
|
156 | if (!omit.includes('entry') && 'entry' in obj) {
|
157 | Object.keys(obj.entry).forEach(name =>
|
158 | this.entry(name).merge([].concat(obj.entry[name])),
|
159 | );
|
160 | }
|
161 |
|
162 | if (!omit.includes('plugin') && 'plugin' in obj) {
|
163 | Object.keys(obj.plugin).forEach(name =>
|
164 | this.plugin(name).merge(obj.plugin[name]),
|
165 | );
|
166 | }
|
167 |
|
168 | omissions.forEach(key => {
|
169 | if (!omit.includes(key) && key in obj) {
|
170 | this[key].merge(obj[key]);
|
171 | }
|
172 | });
|
173 |
|
174 | return super.merge(obj, [...omit, ...omissions, 'entry', 'plugin']);
|
175 | }
|
176 | };
|