Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added config command #4126

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,7 @@ Global options:

Commands:
build|bundle|b [entries...] [options] Run webpack (default command, can be omitted).
config|c [command] [options] Get the configuration of a particular project.
configtest|t [config-path] Validate a webpack configuration.
help|h [command] [option] Display help for commands and options.
info|i [options] Outputs information about your system.
Expand Down
1 change: 1 addition & 0 deletions packages/webpack-cli/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ interface IWebpackCLI {
options: WebpackCLICommandOptions,
action: CommandAction,
): Promise<WebpackCLICommand | undefined>;
getConfigOutput(options: WebpackDevServerOptions): Promise<void>;
makeOption(command: WebpackCLICommand, option: WebpackCLIBuiltInOption): void;
run(
args: Parameters<WebpackCLICommand["parseOptions"]>[0],
Expand Down
126 changes: 98 additions & 28 deletions packages/webpack-cli/src/webpack-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import type {
} from "./types";

import type webpackMerge from "webpack-merge";
import type webpack from "webpack";
import webpack, { web } from "webpack";
import {
type Compiler,
type MultiCompiler,
Expand Down Expand Up @@ -459,6 +459,49 @@ class WebpackCLI implements IWebpackCLI {
];
}

getConfigOptions(): WebpackCLIBuiltInOption[] {
return [
{
name: "file",
alias: "f",
configs: [
{
type: "path",
},
],
description: "Provide path to one or more webpack configuration files to process.",
helpLevel: "minimum",
},
{
name: "name",
alias: "n",
configs: [
{
type: "string",
values: [],
},
],
multiple: true,
description:
"Name(s) of particular configuration(s) to use if configuration file exports an array of multiple configurations.",
helpLevel: "minimum",
},
{
name: "include",
alias: "i",
configs: [
{
type: "string",
values: [],
},
],
multiple: true,
description: "To include the options of webpack-dev-server.",
helpLevel: "minimum",
},
];
}

async getInfoOutput(options: { output: string; additionalPackage: string[] }): Promise<string> {
let { output } = options;
const envinfoConfig: { [key: string]: boolean } = {};
Expand Down Expand Up @@ -517,6 +560,49 @@ class WebpackCLI implements IWebpackCLI {
return info;
}

async getConfigOutput(options: WebpackDevServerOptions): Promise<void> {
const config = await this.loadConfig({
config: [options.file ? options.file : "webpack.config.js"],
name: options.name,
configName: options.name ? (options.name as unknown as string[]) : undefined,
});
if (options.name) {
config.options = Array.isArray(config.options)
? config.options.filter((option: any) => options.name?.includes(option.name))
: [];
}

if (options.include) {
const includeOptions = webpack.config.getNormalizedWebpackOptions({});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I think we need to apply defaults, so you will see how webpack sees your configuration

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually we need to comment the default values beside them which is getting very complex so shall I apply the defaults?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can get default value applyWebpackOptionsBaseDefaults and applyWebpackOptionsDefaults from:

const {
	applyWebpackOptionsDefaults,
	applyWebpackOptionsBaseDefaults
} = require("webpack/config/defaults");

How I see this logic, you load config file/files, normalize and them apply default.

Also we have two possible commands:

  • webpack config just print full resolved configuration, i.e. after apply normalization and default
  • webpack config --diff show only options which are different after normalize and default, so you can undestand which options you don't need because they are default

Array.isArray(config.options)
? config.options.forEach((option) => {
Object.keys(option || {}).forEach((key) => {
if (options.include.includes(key) && options.name?.includes(option.name || "")) {
let finalOption: any = includeOptions[key as keyof WebpackOptionsNormalized];
if (typeof option[key as keyof typeof option] === "string") {
finalOption = option[key as keyof typeof option] as string;
} else {
Object.keys(option[key as keyof typeof option] || {}).forEach((subkey) => {
finalOption[subkey] = (option[key as keyof typeof option] as any)?.[subkey];
});
}
console.log(`\n${key}:`, finalOption);
}
});
})
: [];
}

const compiler = webpack(config.options as webpack.Configuration[]);
compiler.run((err, stats) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to run this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's running only in case of --file and --name for --inckude I will remove it

if (err) {
console.error(err);
process.exit(1);
}
this.logger.raw(stats?.toString({ colors: this.colors.isColorSupported }));
process.exit(0);
});
}
async makeCommand(
commandOptions: WebpackCLIOptions,
options: WebpackCLICommandOptions,
Expand Down Expand Up @@ -863,33 +949,6 @@ class WebpackCLI implements IWebpackCLI {

const builtInFlags: WebpackCLIBuiltInFlag[] = [
// For configs
{
name: "config",
alias: "c",
configs: [
{
type: "string",
},
],
multiple: true,
valueName: "pathToConfigFile",
description:
'Provide path to one or more webpack configuration files to process, e.g. "./webpack.config.js".',
helpLevel: "minimum",
},
{
name: "config-name",
configs: [
{
type: "string",
},
],
multiple: true,
valueName: "name",
description:
"Name(s) of particular configuration(s) to use if configuration file exports an array of multiple configurations.",
helpLevel: "minimum",
},
{
name: "merge",
alias: "m",
Expand Down Expand Up @@ -1123,6 +1182,12 @@ class WebpackCLI implements IWebpackCLI {
alias: "h",
description: "Display help for commands and options.",
};
const configCommandOptions = {
name: "config [command]",
alias: "c",
description: "Get the configuration of a command.",
usage: "[options]",
};
// Built-in external commands
const externalBuiltInCommandsInfo: WebpackCLIExternalCommandInfo[] = [
{
Expand Down Expand Up @@ -1162,6 +1227,7 @@ class WebpackCLI implements IWebpackCLI {
watchCommandOptions,
versionCommandOptions,
helpCommandOptions,
configCommandOptions,
...externalBuiltInCommandsInfo,
];
const getCommandName = (name: string) => name.split(" ")[0];
Expand Down Expand Up @@ -1239,6 +1305,10 @@ class WebpackCLI implements IWebpackCLI {
cli.logger.raw(info);
},
);
} else if (isCommand(commandName, configCommandOptions)) {
this.makeCommand(configCommandOptions, this.getConfigOptions(), async (_, options) => {
await this.getConfigOutput(options);
});
} else {
const builtInExternalCommandInfo = externalBuiltInCommandsInfo.find(
(externalBuiltInCommandInfo) =>
Expand Down
1 change: 0 additions & 1 deletion test/build/config/absent/a.js

This file was deleted.

21 changes: 0 additions & 21 deletions test/build/config/absent/config-absent.test.js

This file was deleted.

1 change: 0 additions & 1 deletion test/build/config/basic/a.js

This file was deleted.

18 changes: 0 additions & 18 deletions test/build/config/basic/basic-config.test.js

This file was deleted.

9 changes: 0 additions & 9 deletions test/build/config/basic/webpack.config.js

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion test/build/config/defaults/basic-config/src/index.js

This file was deleted.

6 changes: 0 additions & 6 deletions test/build/config/defaults/basic-config/webpack.config.js

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion test/build/config/defaults/cjs-config/src/index.js

This file was deleted.

6 changes: 0 additions & 6 deletions test/build/config/defaults/cjs-config/webpack.config.cjs

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion test/build/config/defaults/mjs-config/src/index.js

This file was deleted.

6 changes: 0 additions & 6 deletions test/build/config/defaults/mjs-config/webpack.config.mjs

This file was deleted.

Loading