/
startDevServer.ts
112 lines (90 loc) · 4.03 KB
/
startDevServer.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { devServerOptionsType } from './types';
/**
*
* Starts the devServer
*
* @param {Object} compiler - a webpack compiler
* @param {Object} cliOptions - devServer args
* @param {Object} logger - logger
*
* @returns {Object[]} array of resulting servers
*/
export default async function startDevServer(compiler, cliOptions, logger): Promise<object[]> {
let devServerVersion, Server, findPort;
try {
// eslint-disable-next-line node/no-extraneous-require
devServerVersion = require('webpack-dev-server/package.json').version;
// eslint-disable-next-line node/no-extraneous-require
Server = require('webpack-dev-server/lib/Server');
// eslint-disable-next-line node/no-extraneous-require
findPort = require('webpack-dev-server/lib/utils/findPort');
} catch (err) {
logger.error(`You need to install 'webpack-dev-server' for running 'webpack serve'.\n${err}`);
process.exit(2);
}
const mergeOptions = (cliOptions: devServerOptionsType, devServerOptions: devServerOptionsType): devServerOptionsType => {
// CLI options should take precedence over devServer options,
// and CLI options should have no default values included
const options = { ...devServerOptions, ...cliOptions };
if (devServerOptions.client && cliOptions.client) {
// the user could set some client options in their devServer config,
// then also specify client options on the CLI
options.client = { ...devServerOptions.client, ...cliOptions.client };
}
return options;
};
const isMultiCompiler = Boolean(compiler.compilers);
let compilersWithDevServerOption;
if (isMultiCompiler) {
compilersWithDevServerOption = compiler.compilers.filter((compiler) => compiler.options.devServer);
// No compilers found with the `devServer` option, let's use first compiler
if (compilersWithDevServerOption.length === 0) {
compilersWithDevServerOption = [compiler.compilers[0]];
}
} else {
compilersWithDevServerOption = [compiler];
}
const isDevServer4 = devServerVersion.startsWith('4');
const usedPorts = [];
const devServersOptions = [];
for (const compilerWithDevServerOption of compilersWithDevServerOption) {
const options = mergeOptions(cliOptions, compilerWithDevServerOption.options.devServer || {});
if (isDevServer4) {
options.port = await findPort(options.port);
options.client = options.client || {};
options.client.port = options.client.port || options.port;
} else {
if (!options.publicPath) {
options.publicPath =
typeof compilerWithDevServerOption.options.output.publicPath === 'undefined' ||
compilerWithDevServerOption.options.output.publicPath === 'auto'
? '/'
: compilerWithDevServerOption.options.output.publicPath;
}
options.host = options.host || 'localhost';
options.port = options.port || 8080;
}
if (options.port) {
const portNumber = Number(options.port);
if (usedPorts.find((port) => portNumber === port)) {
throw new Error(
'Unique ports must be specified for each devServer option in your webpack configuration. Alternatively, run only 1 devServer config using the --config-name flag to specify your desired config.',
);
}
usedPorts.push(portNumber);
}
devServersOptions.push({ compiler, options });
}
const servers = [];
for (const devServerOptions of devServersOptions) {
const { compiler, options } = devServerOptions;
const server = new Server(compiler, options);
server.listen(options.port, options.host, (error): void => {
if (error) {
throw error;
}
});
servers.push(server);
}
return servers;
}