Skip to content

Commit 98a6fd0

Browse files
authored
refactor!: the minimun supported webpack-dev-server version is v4.0.0 (#3353)
* refactor!: the minimun supported webpack-dev-server version in v4.0.0 * refactor: remove unused type
1 parent 36a59d8 commit 98a6fd0

File tree

2 files changed

+54
-178
lines changed

2 files changed

+54
-178
lines changed

packages/serve/src/index.ts

Lines changed: 53 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,15 @@ const WEBPACK_PACKAGE = process.env.WEBPACK_PACKAGE || "webpack";
55
const WEBPACK_DEV_SERVER_PACKAGE = process.env.WEBPACK_DEV_SERVER_PACKAGE || "webpack-dev-server";
66

77
type Problem = NonNullable<ReturnType<typeof cli["processArguments"]>>[0];
8-
type PublicPath = WebpackDevServerOptions["output"]["publicPath"];
8+
99
class ServeCommand {
1010
async apply(cli: IWebpackCLI): Promise<void> {
1111
const loadDevServerOptions = () => {
12-
// TODO simplify this after drop webpack v4 and webpack-dev-server v3
1312
// eslint-disable-next-line @typescript-eslint/no-var-requires
1413
const devServer = require(WEBPACK_DEV_SERVER_PACKAGE);
15-
const isNewDevServerCLIAPI = typeof devServer.schema !== "undefined";
1614

1715
// eslint-disable-next-line @typescript-eslint/no-explicit-any
18-
let options: Record<string, any> = {};
19-
20-
if (isNewDevServerCLIAPI) {
21-
if (cli.webpack.cli && typeof cli.webpack.cli.getArguments === "function") {
22-
options = cli.webpack.cli.getArguments(devServer.schema);
23-
} else {
24-
options = devServer.cli.getArguments();
25-
}
26-
} else {
27-
options = require(`${WEBPACK_DEV_SERVER_PACKAGE}/bin/cli-flags`);
28-
}
29-
30-
// Old options format
31-
// { devServer: [{...}, {}...] }
32-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
33-
// @ts-ignore
34-
if (options.devServer) {
35-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
36-
// @ts-ignore
37-
return options.devServer;
38-
}
16+
const options: Record<string, any> = cli.webpack.cli.getArguments(devServer.schema);
3917

4018
// New options format
4119
// { flag1: {}, flag2: {} }
@@ -151,16 +129,7 @@ class ServeCommand {
151129
process.stdin.on("end", () => {
152130
Promise.all(
153131
servers.map((server) => {
154-
if (typeof server.stop === "function") {
155-
return server.stop();
156-
}
157-
158-
// TODO remove in the next major release
159-
return new Promise<void>((resolve) => {
160-
server.close(() => {
161-
resolve();
162-
});
163-
});
132+
return server.stop();
164133
}),
165134
).then(() => {
166135
process.exit(0);
@@ -171,13 +140,10 @@ class ServeCommand {
171140

172141
// eslint-disable-next-line @typescript-eslint/no-var-requires
173142
const DevServer = require(WEBPACK_DEV_SERVER_PACKAGE);
174-
const isNewDevServerCLIAPI = typeof DevServer.schema !== "undefined";
175-
176-
let devServerVersion;
177143

178144
try {
179145
// eslint-disable-next-line @typescript-eslint/no-var-requires
180-
devServerVersion = require(`${WEBPACK_DEV_SERVER_PACKAGE}/package.json`).version;
146+
require(`${WEBPACK_DEV_SERVER_PACKAGE}/package.json`).version;
181147
} catch (err) {
182148
cli.logger.error(
183149
`You need to install 'webpack-dev-server' for running 'webpack serve'.\n${err}`,
@@ -191,142 +157,69 @@ class ServeCommand {
191157
);
192158
const compilersForDevServer =
193159
possibleCompilers.length > 0 ? possibleCompilers : [compilers[0]];
194-
const isDevServer4 = devServerVersion.startsWith("4");
195160
const usedPorts: number[] = [];
196161

197162
for (const compilerForDevServer of compilersForDevServer) {
198-
let devServerOptions: WebpackDevServerOptions;
163+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
164+
const args = devServerFlags.reduce((accumulator: Record<string, any>, flag: any) => {
165+
accumulator[flag.name] = flag;
199166

200-
if (isNewDevServerCLIAPI) {
167+
return accumulator;
168+
}, {});
169+
const values = Object.keys(devServerCLIOptions).reduce(
201170
// eslint-disable-next-line @typescript-eslint/no-explicit-any
202-
const args = devServerFlags.reduce((accumulator: Record<string, any>, flag: any) => {
203-
accumulator[flag.name] = flag;
204-
205-
return accumulator;
206-
}, {});
207-
const values = Object.keys(devServerCLIOptions).reduce(
208-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
209-
(accumulator: Record<string, any>, name: string) => {
210-
const kebabName = cli.toKebabCase(name);
211-
212-
if (args[kebabName]) {
213-
accumulator[kebabName] = options[name];
214-
}
171+
(accumulator: Record<string, any>, name: string) => {
172+
const kebabName = cli.toKebabCase(name);
215173

216-
return accumulator;
217-
},
218-
{},
219-
);
220-
const result = { ...(compilerForDevServer.options.devServer || {}) };
221-
const problems = (
222-
cli.webpack.cli && typeof cli.webpack.cli.processArguments === "function"
223-
? cli.webpack.cli
224-
: DevServer.cli
225-
).processArguments(args, result, values);
226-
227-
if (problems) {
228-
const groupBy = (xs: Problem[], key: keyof Problem) => {
229-
return xs.reduce((rv: { [key: string]: Problem[] }, x: Problem) => {
230-
(rv[x[key]] = rv[x[key]] || []).push(x);
231-
232-
return rv;
233-
}, {});
234-
};
235-
236-
const problemsByPath = groupBy(problems, "path");
237-
238-
for (const path in problemsByPath) {
239-
const problems = problemsByPath[path];
240-
241-
problems.forEach((problem: Problem) => {
242-
cli.logger.error(
243-
`${cli.capitalizeFirstLetter(problem.type.replace(/-/g, " "))}${
244-
problem.value ? ` '${problem.value}'` : ""
245-
} for the '--${problem.argument}' option${
246-
problem.index ? ` by index '${problem.index}'` : ""
247-
}`,
248-
);
249-
250-
if (problem.expected) {
251-
cli.logger.error(`Expected: '${problem.expected}'`);
252-
}
253-
});
174+
if (args[kebabName]) {
175+
accumulator[kebabName] = options[name];
254176
}
255177

256-
process.exit(2);
257-
}
258-
259-
devServerOptions = result as WebpackDevServerOptions;
260-
} else {
261-
// TODO remove in the next major release
262-
const mergeOptions = (
263-
devServerOptions: Partial<WebpackDevServerOptions>,
264-
devServerCliOptions: Partial<WebpackDevServerOptions>,
265-
): WebpackDevServerOptions => {
266-
// CLI options should take precedence over devServer options,
267-
// and CLI options should have no default values included
268-
const options = { ...devServerOptions, ...devServerCliOptions };
269-
270-
if (
271-
devServerOptions.client &&
272-
devServerCliOptions.client &&
273-
typeof devServerOptions.client === "object" &&
274-
typeof devServerCliOptions.client === "object"
275-
) {
276-
// the user could set some client options in their devServer config,
277-
// then also specify client options on the CLI
278-
options.client = {
279-
...devServerOptions.client,
280-
...devServerCliOptions.client,
281-
};
282-
}
283-
284-
return options as WebpackDevServerOptions;
178+
return accumulator;
179+
},
180+
{},
181+
);
182+
const result = { ...(compilerForDevServer.options.devServer || {}) };
183+
const problems = (
184+
cli.webpack.cli && typeof cli.webpack.cli.processArguments === "function"
185+
? cli.webpack.cli
186+
: DevServer.cli
187+
).processArguments(args, result, values);
188+
189+
if (problems) {
190+
const groupBy = (xs: Problem[], key: keyof Problem) => {
191+
return xs.reduce((rv: { [key: string]: Problem[] }, x: Problem) => {
192+
(rv[x[key]] = rv[x[key]] || []).push(x);
193+
194+
return rv;
195+
}, {});
285196
};
286197

287-
devServerOptions = mergeOptions(
288-
compilerForDevServer.options.devServer || {},
289-
devServerCLIOptions,
290-
);
291-
}
292-
293-
// TODO remove in the next major release
294-
if (!isDevServer4) {
295-
const getPublicPathOption = (): PublicPath => {
296-
const normalizePublicPath = (publicPath: PublicPath): PublicPath =>
297-
typeof publicPath === "undefined" || publicPath === "auto" ? "/" : publicPath;
198+
const problemsByPath = groupBy(problems, "path");
298199

299-
if (options.outputPublicPath) {
300-
return normalizePublicPath(compilerForDevServer.options.output.publicPath);
301-
}
200+
for (const path in problemsByPath) {
201+
const problems = problemsByPath[path];
302202

303-
if (devServerOptions.publicPath) {
304-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
305-
// @ts-ignore
306-
return normalizePublicPath(devServerOptions.publicPath);
307-
}
203+
problems.forEach((problem: Problem) => {
204+
cli.logger.error(
205+
`${cli.capitalizeFirstLetter(problem.type.replace(/-/g, " "))}${
206+
problem.value ? ` '${problem.value}'` : ""
207+
} for the '--${problem.argument}' option${
208+
problem.index ? ` by index '${problem.index}'` : ""
209+
}`,
210+
);
308211

309-
return normalizePublicPath(compilerForDevServer.options.output.publicPath);
310-
};
311-
const getStatsOption = (): WebpackDevServerOptions["stats"] => {
312-
if (options.stats) {
313-
return options.stats;
314-
}
315-
316-
if (devServerOptions.stats) {
317-
return devServerOptions.stats;
318-
}
319-
320-
return compilerForDevServer.options.stats;
321-
};
212+
if (problem.expected) {
213+
cli.logger.error(`Expected: '${problem.expected}'`);
214+
}
215+
});
216+
}
322217

323-
devServerOptions.host = devServerOptions.host || "localhost";
324-
devServerOptions.port =
325-
typeof devServerOptions.port !== "undefined" ? devServerOptions.port : 8080;
326-
devServerOptions.stats = getStatsOption();
327-
devServerOptions.publicPath = getPublicPathOption();
218+
process.exit(2);
328219
}
329220

221+
const devServerOptions: WebpackDevServerOptions = result as WebpackDevServerOptions;
222+
330223
if (devServerOptions.port) {
331224
const portNumber = Number(devServerOptions.port);
332225

@@ -340,25 +233,9 @@ class ServeCommand {
340233
}
341234

342235
try {
343-
let server;
236+
const server = new DevServer(devServerOptions, compiler);
344237

345-
// TODO: remove after dropping webpack-dev-server@v3
346-
if (isDevServer4) {
347-
server = new DevServer(devServerOptions, compiler);
348-
} else {
349-
server = new DevServer(compiler, devServerOptions);
350-
}
351-
352-
if (typeof server.start === "function") {
353-
await server.start();
354-
} else {
355-
// TODO remove in the next major release
356-
server.listen(devServerOptions.port, devServerOptions.host, (error: Error): void => {
357-
if (error) {
358-
throw error;
359-
}
360-
});
361-
}
238+
await server.start();
362239

363240
servers.push(server);
364241
} catch (error) {

packages/webpack-cli/src/webpack-cli.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,8 +554,7 @@ class WebpackCLI implements IWebpackCLI {
554554
} else {
555555
mainOption = {
556556
flags: option.alias ? `-${option.alias}, --${option.name}` : `--${option.name}`,
557-
// TODO `describe` used by `webpack-dev-server@3`
558-
description: option.description || option.describe || "",
557+
description: option.description || "",
559558
type: option.type
560559
? new Set(Array.isArray(option.type) ? option.type : [option.type])
561560
: new Set([Boolean]),

0 commit comments

Comments
 (0)