Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor!: the minimum supported webpack version is v5.0.0 (#3342)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: webpack-cli no longer supports webpack v4, the minimum supported version is webpack v5.0.0
snitin315 committed Nov 8, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent c7baf34 commit bdb51c0
Showing 7 changed files with 657 additions and 753 deletions.
331 changes: 97 additions & 234 deletions packages/webpack-cli/src/webpack-cli.ts
Original file line number Diff line number Diff line change
@@ -472,6 +472,11 @@ class WebpackCLI implements IWebpackCLI {
makeOption(command: WebpackCLICommand, option: WebpackCLIBuiltInOption) {
let mainOption: WebpackCLIMainOption;
let negativeOption;
const flagsWithAlias = ["devtool", "output-path", "target", "watch"];

if (flagsWithAlias.includes(option.name)) {
option.alias = option.name[0];
}

if (option.configs) {
let needNegativeOption = false;
@@ -856,110 +861,6 @@ class WebpackCLI implements IWebpackCLI {
alias: "j",
description: "Prints result as JSON or store it in a file.",
},

// For webpack@4
{
name: "entry",
configs: [
{
type: "string",
},
],
multiple: true,
description: "The entry point(s) of your application e.g. ./src/main.js.",
},
{
name: "output-path",
alias: "o",
configs: [
{
type: "string",
},
],
description: "Output location of the file generated by webpack e.g. ./dist/.",
},
{
name: "target",
alias: "t",
configs: [
{
type: "string",
},
],
multiple: this.webpack.cli !== undefined,
description: "Sets the build target e.g. node.",
},
{
name: "devtool",
configs: [
{
type: "string",
},
{
type: "enum",
values: [false],
},
],
negative: true,
alias: "d",
description: "Determine source maps to use.",
negatedDescription: "Do not generate source maps.",
},
{
name: "mode",
configs: [
{
type: "string",
},
],
description: "Defines the mode to pass to webpack.",
},
{
name: "name",
configs: [
{
type: "string",
},
],
description: "Name of the configuration. Used when loading multiple configurations.",
},
{
name: "stats",
configs: [
{
type: "string",
},
{
type: "boolean",
},
],
negative: true,
description: "It instructs webpack on how to treat the stats e.g. verbose.",
negatedDescription: "Disable stats output.",
},
{
name: "watch",
configs: [
{
type: "boolean",
},
],
negative: true,
alias: "w",
description: "Watch for files changes.",
negatedDescription: "Do not watch for file changes.",
},
{
name: "watch-options-stdin",
configs: [
{
type: "boolean",
},
],
negative: true,
description: "Stop watching when stdin stream has ended.",
negatedDescription: "Do not stop watching when stdin stream has ended.",
},
{
name: "fail-on-warnings",
configs: [
@@ -974,32 +875,31 @@ class WebpackCLI implements IWebpackCLI {

// Extract all the flags being exported from core.
// A list of cli flags generated by core can be found here https://github.com/webpack/webpack/blob/master/test/__snapshots__/Cli.test.js.snap
const coreFlags = this.webpack.cli
? Object.entries(this.webpack.cli.getArguments()).map(([flag, meta]) => {
const inBuiltIn = builtInFlags.find((builtInFlag) => builtInFlag.name === flag);

if (inBuiltIn) {
return {
...meta,
// @ts-expect-error this might be overwritten
name: flag,
group: "core",
...inBuiltIn,
configs: meta.configs || [],
};
}
const coreArguments = Object.entries(this.webpack.cli.getArguments()).map(([flag, meta]) => {
const inBuiltIn = builtInFlags.find((builtInFlag) => builtInFlag.name === flag);

if (inBuiltIn) {
return {
...meta,
// @ts-expect-error this might be overwritten
name: flag,
group: "core",
...inBuiltIn,
configs: meta.configs || [],
};
}

return { ...meta, name: flag, group: "core" };
})
: [];
return { ...meta, name: flag, group: "core" };
});

const options: WebpackCLIBuiltInOption[] = ([] as WebpackCLIBuiltInFlag[])
.concat(
builtInFlags.filter(
(builtInFlag) => !coreFlags.find((coreFlag) => builtInFlag.name === coreFlag.name),
(builtInFlag) =>
!coreArguments.find((coreArgument) => builtInFlag.name === coreArgument.name),
),
)
.concat(coreFlags)
.concat(coreArguments)
.map((option): WebpackCLIBuiltInOption => {
(option as WebpackCLIBuiltInOption).helpLevel = minimumHelpFlags.includes(option.name)
? "minimum"
@@ -1680,6 +1580,8 @@ class WebpackCLI implements IWebpackCLI {
// Default action
this.program.usage("[options]");
this.program.allowUnknownOption(true);

// Basic command for lazy loading other commands
this.program.action(async (options, program: WebpackCLICommand) => {
if (!isInternalActionCalled) {
isInternalActionCalled = true;
@@ -2090,139 +1992,100 @@ class WebpackCLI implements IWebpackCLI {
}

// Apply options
if (this.webpack.cli) {
const args: Record<string, Argument> = this.getBuiltInOptions()
.filter((flag) => flag.group === "core")
.reduce((accumulator: Record<string, Argument>, flag) => {
accumulator[flag.name] = flag as unknown as Argument;
const args: Record<string, Argument> = this.getBuiltInOptions()
.filter((flag) => flag.group === "core")
.reduce((accumulator: Record<string, Argument>, flag) => {
accumulator[flag.name] = flag as unknown as Argument;
return accumulator;
}, {});

const values: ProcessedArguments = Object.keys(options).reduce(
(accumulator: ProcessedArguments, name) => {
if (name === "argv") {
return accumulator;
}, {});

const values: ProcessedArguments = Object.keys(options).reduce(
(accumulator: ProcessedArguments, name) => {
if (name === "argv") {
return accumulator;
}

const kebabName = this.toKebabCase(name);

if (args[kebabName]) {
accumulator[kebabName] = options[name as keyof typeof options as string];
}

return accumulator;
},
{},
);

const problems: Problem[] | null = this.webpack.cli.processArguments(args, item, values);

if (problems) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const groupBy = (xs: Record<string, any>[], key: string) => {
return xs.reduce((rv, x) => {
(rv[x[key]] = rv[x[key]] || []).push(x);
}

return rv;
}, {});
};
const problemsByPath = groupBy(problems, "path");
const kebabName = this.toKebabCase(name);

for (const path in problemsByPath) {
const problems = problemsByPath[path];
if (args[kebabName]) {
accumulator[kebabName] = options[name as keyof typeof options as string];
}

problems.forEach((problem: Problem) => {
this.logger.error(
`${this.capitalizeFirstLetter(problem.type.replace(/-/g, " "))}${
problem.value ? ` '${problem.value}'` : ""
} for the '--${problem.argument}' option${
problem.index ? ` by index '${problem.index}'` : ""
}`,
);
return accumulator;
},
{},
);

if (problem.expected) {
this.logger.error(`Expected: '${problem.expected}'`);
}
});
}
const problems: Problem[] | null = this.webpack.cli.processArguments(args, item, values);

process.exit(2);
}
if (problems) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const groupBy = (xs: Record<string, any>[], key: string) => {
return xs.reduce((rv, x) => {
(rv[x[key]] = rv[x[key]] || []).push(x);

const isFileSystemCacheOptions = (
config: WebpackConfiguration,
): config is FileSystemCacheOptions => {
return (
Boolean(config.cache) && (config as FileSystemCacheOptions).cache.type === "filesystem"
);
return rv;
}, {});
};
const problemsByPath = groupBy(problems, "path");

// Setup default cache options
if (isFileSystemCacheOptions(item)) {
const configPath = config.path.get(item);
for (const path in problemsByPath) {
const problems = problemsByPath[path];

if (configPath) {
if (!item.cache.buildDependencies) {
item.cache.buildDependencies = {};
}
problems.forEach((problem: Problem) => {
this.logger.error(
`${this.capitalizeFirstLetter(problem.type.replace(/-/g, " "))}${
problem.value ? ` '${problem.value}'` : ""
} for the '--${problem.argument}' option${
problem.index ? ` by index '${problem.index}'` : ""
}`,
);

if (!item.cache.buildDependencies.defaultConfig) {
item.cache.buildDependencies.defaultConfig = [];
if (problem.expected) {
this.logger.error(`Expected: '${problem.expected}'`);
}

if (Array.isArray(configPath)) {
configPath.forEach((oneOfConfigPath) => {
(
item.cache.buildDependencies as NonNullable<
FileSystemCacheOptions["cache"]["buildDependencies"]
>
).defaultConfig.push(oneOfConfigPath);
});
} else {
item.cache.buildDependencies.defaultConfig.push(configPath);
}
}
});
}
}

// Setup legacy logic for webpack@4
// TODO respect `--entry-reset` in th next major release
// TODO drop in the next major release
if (options.entry) {
item.entry = options.entry;
}

if (options.outputPath) {
item.output = { ...item.output, ...{ path: path.resolve(options.outputPath) } };
}

if (options.target) {
item.target = options.target;
process.exit(2);
}

if (typeof options.devtool !== "undefined") {
item.devtool = options.devtool;
}
const isFileSystemCacheOptions = (
config: WebpackConfiguration,
): config is FileSystemCacheOptions => {
return (
Boolean(config.cache) && (config as FileSystemCacheOptions).cache.type === "filesystem"
);
};

if (options.name) {
item.name = options.name;
}
// Setup default cache options
if (isFileSystemCacheOptions(item)) {
const configPath = config.path.get(item);

if (typeof options.stats !== "undefined") {
item.stats = options.stats;
}
if (configPath) {
if (!item.cache.buildDependencies) {
item.cache.buildDependencies = {};
}

if (typeof options.watch !== "undefined") {
item.watch = options.watch;
}
if (!item.cache.buildDependencies.defaultConfig) {
item.cache.buildDependencies.defaultConfig = [];
}

if (typeof options.watchOptionsStdin !== "undefined") {
item.watchOptions = { ...item.watchOptions, ...{ stdin: options.watchOptionsStdin } };
if (Array.isArray(configPath)) {
configPath.forEach((oneOfConfigPath) => {
(
item.cache.buildDependencies as NonNullable<
FileSystemCacheOptions["cache"]["buildDependencies"]
>
).defaultConfig.push(oneOfConfigPath);
});
} else {
item.cache.buildDependencies.defaultConfig.push(configPath);
}
}
}

if (options.mode) {
item.mode = options.mode;
}
// TODO respect `--entry-reset` in th next major release

// Respect `process.env.NODE_ENV`
if (
Loading

0 comments on commit bdb51c0

Please sign in to comment.