Skip to content

Commit a89ebef

Browse files
refactor(cli): implement ui-render without touching CLI logic nor its lifecycle
1 parent f51a3da commit a89ebef

File tree

1 file changed

+19
-81
lines changed

1 file changed

+19
-81
lines changed

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

Lines changed: 19 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@ import { type Configuration as DevServerConfiguration } from "webpack-dev-server
3434
import {
3535
CommandHelpData,
3636
HelpOption,
37+
MAX_WIDTH,
3738
RenderOptions,
3839
renderAliasHelp,
39-
renderCommandFooter,
40-
renderCommandHeader,
4140
renderCommandHelp,
4241
renderError,
4342
renderFooter,
@@ -104,12 +103,6 @@ interface Command extends CommanderCommand {
104103
context: Context;
105104
}
106105

107-
interface CommandUIOptions {
108-
description?: string;
109-
footer?: "global" | "command";
110-
skipIf?: (opts: RecordAny) => boolean;
111-
}
112-
113106
interface CommandOptions<
114107
A = void,
115108
O extends CommanderArgs = CommanderArgs,
@@ -123,7 +116,6 @@ interface CommandOptions<
123116
dependencies?: string[];
124117
pkg?: string;
125118
preload?: () => Promise<C>;
126-
ui?: CommandUIOptions;
127119
options?:
128120
| CommandOption[]
129121
| ((command: Command & { context: C }) => CommandOption[])
@@ -680,33 +672,6 @@ class WebpackCLI {
680672

681673
command.action(options.action);
682674

683-
if (options.ui) {
684-
const { ui } = options;
685-
686-
command.hook("preAction", (_thisCmd, actionCmd) => {
687-
if (ui.skipIf?.(actionCmd.opts())) return;
688-
689-
renderCommandHeader(
690-
{
691-
name: command.name(),
692-
description: ui.description ?? command.description(),
693-
},
694-
this.#renderOptions(),
695-
);
696-
});
697-
698-
command.hook("postAction", (_thisCmd, actionCmd) => {
699-
if (ui.skipIf?.(actionCmd.opts())) return;
700-
701-
const renderOpts = this.#renderOptions();
702-
if (ui.footer === "command") {
703-
renderCommandFooter(renderOpts);
704-
} else {
705-
renderFooter(renderOpts);
706-
}
707-
});
708-
}
709-
710675
return command;
711676
}
712677

@@ -1044,9 +1009,7 @@ class WebpackCLI {
10441009
return {
10451010
colors: this.colors,
10461011
log: (line) => this.logger.raw(line),
1047-
// process.stdout.columns can be undefined in non-TTY environments
1048-
// (CI, test runners, pipes). Fall back to 80 which fits most terminals.
1049-
columns: process.stdout.columns ?? 80,
1012+
columns: process.stdout.columns ?? MAX_WIDTH, // import MAX_WIDTH from ui-renderer
10501013
};
10511014
}
10521015

@@ -1056,23 +1019,18 @@ class WebpackCLI {
10561019
if ((opt as Option & { internal?: boolean }).internal) return false;
10571020
return isVerbose || !opt.hidden;
10581021
})
1059-
.map((opt) => ({
1060-
flags: opt.flags,
1061-
description: opt.description ?? "",
1062-
}));
1022+
.map((opt) => ({ flags: opt.flags, description: opt.description ?? "" }));
10631023

10641024
const globalOptions: HelpOption[] = program.options.map((opt) => ({
10651025
flags: opt.flags,
10661026
description: opt.description ?? "",
10671027
}));
10681028

1069-
const aliases = command.aliases();
1070-
const usageParts = [command.name(), ...aliases].join("|");
1071-
const usage = `webpack ${usageParts} ${command.usage()}`;
1029+
const usageParts = [command.name(), ...command.aliases()].join("|");
10721030

10731031
return {
10741032
name: command.name(),
1075-
usage,
1033+
usage: `webpack ${usageParts} ${command.usage()}`,
10761034
description: command.description(),
10771035
options: visibleOptions,
10781036
globalOptions,
@@ -1864,25 +1822,18 @@ class WebpackCLI {
18641822
hidden: false,
18651823
},
18661824
],
1867-
ui: {
1868-
description: "Installed package versions.",
1869-
footer: "global",
1870-
skipIf: (opts) => Boolean(opts.output),
1871-
},
18721825
action: async (options: { output?: string }) => {
1873-
if (options.output) {
1874-
// Machine-readable output requested, bypass the visual renderer entirely.
1875-
const info = await this.#renderVersion(options);
1876-
this.logger.raw(info);
1877-
return;
1878-
}
1879-
18801826
const rawInfo = await this.#getInfoOutput({
18811827
information: {
18821828
npmPackages: `{${DEFAULT_WEBPACK_PACKAGES.map((item) => `*${item}*`).join(",")}}`,
18831829
},
18841830
});
18851831

1832+
if (options.output) {
1833+
this.logger.raw(await this.#renderVersion(options));
1834+
return;
1835+
}
1836+
18861837
renderVersionOutput(rawInfo, this.#renderOptions());
18871838
},
18881839
},
@@ -1913,18 +1864,15 @@ class WebpackCLI {
19131864
hidden: false,
19141865
},
19151866
],
1916-
ui: {
1917-
description: "System and environment information.",
1918-
footer: "global",
1919-
skipIf: (opts) => Boolean(opts.output),
1920-
},
19211867
action: async (options: { output?: string; additionalPackage?: string[] }) => {
1868+
const info = await this.#getInfoOutput(options);
1869+
19221870
if (options.output) {
1923-
this.logger.raw(await this.#getInfoOutput(options));
1871+
this.logger.raw(info);
19241872
return;
19251873
}
19261874

1927-
renderInfoOutput(await this.#getInfoOutput(options), this.#renderOptions());
1875+
renderInfoOutput(info, this.#renderOptions());
19281876
},
19291877
},
19301878
configtest: {
@@ -1938,10 +1886,6 @@ class WebpackCLI {
19381886
const webpack = await this.loadWebpack();
19391887
return { webpack };
19401888
},
1941-
ui: {
1942-
description: "Validating your webpack configuration.",
1943-
footer: "command",
1944-
},
19451889
action: async (configPath: string | undefined, _options: CommanderArgs, cmd) => {
19461890
const { webpack } = cmd.context;
19471891
const env: Env = {};
@@ -1972,22 +1916,16 @@ class WebpackCLI {
19721916
renderError("No configuration found.", renderOpts);
19731917
process.exit(2);
19741918
}
1975-
1976-
const pathList = [...configPaths].join(", ");
1977-
renderWarning(`Validating: ${pathList}`, renderOpts);
1978-
1919+
renderWarning(`Validating: ${[...configPaths].join(", ")}`, renderOpts);
19791920
try {
19801921
cmd.context.webpack.validate(config.options);
19811922
} catch (error) {
1982-
if (this.isValidationError(error as Error)) {
1983-
renderError((error as Error).message, renderOpts);
1984-
} else {
1985-
renderError(String(error), renderOpts);
1986-
}
1987-
1923+
renderError(
1924+
this.isValidationError(error as Error) ? (error as Error).message : String(error),
1925+
renderOpts,
1926+
);
19881927
process.exit(2);
19891928
}
1990-
19911929
renderSuccess("No validation errors found.", renderOpts);
19921930
},
19931931
},

0 commit comments

Comments
 (0)