-
-
Notifications
You must be signed in to change notification settings - Fork 203
/
custom-webpack-builder.ts
75 lines (64 loc) · 2.49 KB
/
custom-webpack-builder.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { getSystemPath, Path } from '@angular-devkit/core';
import { Configuration } from 'webpack';
import { mergeConfigs } from './webpack-config-merger';
import { CustomWebpackBuilderConfig } from './custom-webpack-builder-config';
export const defaultWebpackConfigPath = 'webpack.config.js';
type CustomWebpackConfig =
| Configuration
| Promise<Configuration>
| ((baseWebpackConfig: Configuration, buildOptions: any) => Configuration)
| ((baseWebpackConfig: Configuration, buildOptions: any) => Promise<Configuration>);
export class CustomWebpackBuilder {
static async buildWebpackConfig(
root: Path,
config: CustomWebpackBuilderConfig,
baseWebpackConfig: Configuration,
buildOptions: any
): Promise<Configuration> {
if (!config) {
return baseWebpackConfig;
}
const webpackConfigPath = config.path || defaultWebpackConfigPath;
const path = `${getSystemPath(root)}/${webpackConfigPath}`;
const configOrFactoryOrPromise = resolveCustomWebpackConfig(path);
if (typeof configOrFactoryOrPromise === 'function') {
// That exported function can be synchronous either
// asynchronous. Given the following example:
// `module.exports = async (config) => { ... }`
return configOrFactoryOrPromise(baseWebpackConfig, buildOptions);
}
// The user can also export a `Promise` that resolves `Configuration`
// object. Given the following example:
// `module.exports = new Promise(resolve => resolve({ ... }))`
// If the user has exported a plain object, like:
// `module.exports = { ... }`
// then it will promisified and awaited
const resolvedConfig = await configOrFactoryOrPromise;
return mergeConfigs(
baseWebpackConfig,
resolvedConfig,
config.mergeStrategies,
config.replaceDuplicatePlugins
);
}
}
function resolveCustomWebpackConfig(path: string): CustomWebpackConfig {
if (path.endsWith('.ts')) {
// Register TS compiler lazily
require('ts-node').register({
compilerOptions: {
module: 'commonjs',
},
});
}
const customWebpackConfig = require(path);
// If the user provides a configuration in TS file
// then there are 2 cases for exporing an object. The first one is:
// `module.exports = { ... }`. And the second one is:
// `export default { ... }`. The ESM format is compiled into:
// `{ default: { ... } }`
if (typeof customWebpackConfig.default === 'object') {
return customWebpackConfig.default;
}
return customWebpackConfig;
}