From d1414793c6725e23fd631a8130b3c951f42faa82 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Fri, 20 Aug 2021 21:05:56 +0300 Subject: [PATCH 1/8] feat: allow to run commands not requiring webpack without webpack installation --- packages/configtest/src/index.ts | 15 +- packages/generators/src/index.ts | 8 +- packages/info/src/index.ts | 6 +- packages/serve/src/index.ts | 22 +- packages/webpack-cli/bin/cli.js | 23 +- packages/webpack-cli/lib/webpack-cli.js | 307 ++++++++++-------- smoketests/helpers.js | 22 +- smoketests/index.js | 36 +- smoketests/missing-packages/webpack.test.js | 79 ++++- .../help.test.js.snap.devServer3.webpack4 | 4 +- .../help.test.js.snap.devServer3.webpack5 | 4 +- .../help.test.js.snap.devServer4.webpack4 | 4 +- .../help.test.js.snap.devServer4.webpack5 | 4 +- .../version.test.js.snap.webpack4 | 108 +++--- .../version.test.js.snap.webpack5 | 108 +++--- 15 files changed, 415 insertions(+), 335 deletions(-) diff --git a/packages/configtest/src/index.ts b/packages/configtest/src/index.ts index c9bd526716c..997bfdb0186 100644 --- a/packages/configtest/src/index.ts +++ b/packages/configtest/src/index.ts @@ -1,14 +1,13 @@ class ConfigTestCommand { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any async apply(cli: any): Promise { - const { logger, webpack } = cli; - await cli.makeCommand( { name: "configtest [config-path]", alias: "t", description: "Validate a webpack configuration.", pkg: "@webpack-cli/configtest", + dependencies: ["webpack"], }, [], async (configPath: string | undefined): Promise => { @@ -28,12 +27,14 @@ class ConfigTestCommand { } if (configPaths.size === 0) { - logger.error("No configuration found."); + cli.logger.error("No configuration found."); process.exit(2); } - logger.info(`Validate '${Array.from(configPaths).join(" ,")}'.`); + cli.logger.info(`Validate '${Array.from(configPaths).join(" ,")}'.`); + const webpack = await cli.loadWebpack(); + try { // eslint-disable-next-line @typescript-eslint/no-explicit-any const error: any = webpack.validate(config.options); @@ -44,15 +45,15 @@ class ConfigTestCommand { } } catch (error) { if (cli.isValidationError(error)) { - logger.error(error.message); + cli.logger.error(error.message); } else { - logger.error(error); + cli.logger.error(error); } process.exit(2); } - logger.success("There are no validation errors in the given webpack configuration."); + cli.logger.success("There are no validation errors in the given webpack configuration."); }, ); } diff --git a/packages/generators/src/index.ts b/packages/generators/src/index.ts index 3faa3dd0a7f..e248db6ddee 100644 --- a/packages/generators/src/index.ts +++ b/packages/generators/src/index.ts @@ -7,8 +7,6 @@ import initGenerator from "./init-generator"; class GeneratorsCommand { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any async apply(cli: any): Promise { - const { logger } = cli; - await cli.makeCommand( { name: "init [generation-path]", @@ -51,7 +49,7 @@ class GeneratorsCommand { env.registerStub(initGenerator, generatorName); env.run(generatorName, { cli, options }, () => { - logger.success("Project has been initialised with webpack!"); + cli.logger.success("Project has been initialised with webpack!"); }); }, ); @@ -83,7 +81,7 @@ class GeneratorsCommand { env.registerStub(loaderGenerator, generatorName); env.run(generatorName, { cli, options }, () => { - logger.success("Loader template has been successfully scaffolded."); + cli.logger.success("Loader template has been successfully scaffolded."); }); }, ); @@ -115,7 +113,7 @@ class GeneratorsCommand { env.registerStub(pluginGenerator, generatorName); env.run(generatorName, { cli, options }, () => { - logger.success("Plugin template has been successfully scaffolded."); + cli.logger.success("Plugin template has been successfully scaffolded."); }); }, ); diff --git a/packages/info/src/index.ts b/packages/info/src/index.ts index e8658970bfa..c86fd337f12 100644 --- a/packages/info/src/index.ts +++ b/packages/info/src/index.ts @@ -32,8 +32,6 @@ const DEFAULT_DETAILS: Information = { class InfoCommand { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any async apply(cli: any): Promise { - const { logger } = cli; - await cli.makeCommand( { name: "info", @@ -71,7 +69,7 @@ class InfoCommand { envinfoConfig["json"] = true; break; default: - logger.error(`'${output}' is not a valid value for output`); + cli.logger.error(`'${output}' is not a valid value for output`); process.exit(2); } } @@ -81,7 +79,7 @@ class InfoCommand { info = info.replace(/npmPackages/g, "Packages"); info = info.replace(/npmGlobalPackages/g, "Global Packages"); - logger.raw(info); + cli.logger.raw(info); }, ); } diff --git a/packages/serve/src/index.ts b/packages/serve/src/index.ts index a76cf412896..d1db60410e5 100644 --- a/packages/serve/src/index.ts +++ b/packages/serve/src/index.ts @@ -3,9 +3,7 @@ import { devServerOptionsType } from "./types"; class ServeCommand { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any async apply(cli: any): Promise { - const { logger, webpack } = cli; - - const loadDevServerOptions = () => { + const loadDevServerOptions = () => { // TODO simplify this after drop webpack v4 and webpack-dev-server v3 // eslint-disable-next-line @typescript-eslint/no-var-requires, node/no-extraneous-require const devServer = require("webpack-dev-server"); @@ -14,8 +12,8 @@ class ServeCommand { let options = {}; if (isNewDevServerCLIAPI) { - if (webpack.cli && typeof webpack.cli.getArguments === "function") { - options = webpack.cli.getArguments(devServer.schema); + if (cli.webpack.cli && typeof cli.webpack.cli.getArguments === "function") { + options = cli.webpack.cli.getArguments(devServer.schema); } else { options = devServer.cli.getArguments(); } @@ -50,7 +48,7 @@ class ServeCommand { description: "Run the webpack dev server.", usage: "[entries...] [options]", pkg: "@webpack-cli/serve", - dependencies: ["webpack-dev-server"], + dependencies: ["webpack", "webpack-dev-server"], }, () => { let devServerFlags = []; @@ -58,7 +56,7 @@ class ServeCommand { try { devServerFlags = loadDevServerOptions(); } catch (error) { - logger.error( + cli.logger.error( `You need to install 'webpack-dev-server' for running 'webpack serve'.\n${error}`, ); process.exit(2); @@ -169,7 +167,7 @@ class ServeCommand { // eslint-disable-next-line node/no-extraneous-require, @typescript-eslint/no-var-requires devServerVersion = require("webpack-dev-server/package.json").version; } catch (err) { - logger.error( + cli.logger.error( `You need to install 'webpack-dev-server' for running 'webpack serve'.\n${err}`, ); process.exit(2); @@ -200,8 +198,8 @@ class ServeCommand { }, {}); const result = { ...(compilerForDevServer.options.devServer || {}) }; const problems = ( - webpack.cli && typeof webpack.cli.processArguments === "function" - ? webpack.cli + cli.webpack.cli && typeof cli.webpack.cli.processArguments === "function" + ? cli.webpack.cli : DevServer.cli ).processArguments(args, result, values); @@ -335,9 +333,9 @@ class ServeCommand { servers.push(server); } catch (error) { if (cli.isValidationError(error)) { - logger.error(error.message); + cli.logger.error(error.message); } else { - logger.error(error); + cli.logger.error(error); } process.exit(2); diff --git a/packages/webpack-cli/bin/cli.js b/packages/webpack-cli/bin/cli.js index c947b2a9094..91b0cd4b17f 100755 --- a/packages/webpack-cli/bin/cli.js +++ b/packages/webpack-cli/bin/cli.js @@ -10,7 +10,6 @@ require("v8-compile-cache"); const importLocal = require("import-local"); const runCLI = require("../lib/bootstrap"); -const utils = require("../lib/utils"); if (!process.env.WEBPACK_CLI_SKIP_IMPORT_LOCAL) { // Prefer the local installation of `webpack-cli` @@ -21,24 +20,4 @@ if (!process.env.WEBPACK_CLI_SKIP_IMPORT_LOCAL) { process.title = "webpack"; -if (utils.packageExists("webpack")) { - runCLI(process.argv, originalModuleCompile); -} else { - const { promptInstallation, logger, colors } = utils; - - promptInstallation("webpack", () => { - utils.logger.error(`It looks like ${colors.bold("webpack")} is not installed.`); - }) - .then(() => { - logger.success(`${colors.bold("webpack")} was installed successfully.`); - - runCLI(process.argv, originalModuleCompile); - }) - .catch(() => { - logger.error( - `Action Interrupted, Please try once again or install ${colors.bold("webpack")} manually.`, - ); - - process.exit(2); - }); -} +runCLI(process.argv, originalModuleCompile); diff --git a/packages/webpack-cli/lib/webpack-cli.js b/packages/webpack-cli/lib/webpack-cli.js index 76869cd5687..3c96870ce61 100644 --- a/packages/webpack-cli/lib/webpack-cli.js +++ b/packages/webpack-cli/lib/webpack-cli.js @@ -8,8 +8,6 @@ const utils = require("./utils"); class WebpackCLI { constructor() { - // Global - this.webpack = require(process.env.WEBPACK_PACKAGE || "webpack"); this.logger = utils.logger; this.utils = utils; @@ -72,18 +70,26 @@ class WebpackCLI { return result; } + + loadJSONFile(pathToFile, handleError = true) { + let result; - loadJSONFile(pathToFile) { - let result; + try { + result = require(pathToFile); + } catch (error) { + if (handleError) { + this.logger.error(error); + process.exit(2); + } else { + throw error; + } + } - try { - result = require(pathToFile); - } catch (error) { - this.logger.error(error); - process.exit(2); - } + return result; + } - return result; + async loadWebpack(handleError = true) { + return this.tryRequireThenImport(process.env.WEBPACK_PACKAGE || "webpack", handleError); } async makeCommand(commandOptions, options, action) { @@ -141,13 +147,13 @@ class WebpackCLI { const { promptInstallation, colors } = this.utils; - await promptInstallation(dependency, () => { - this.logger.error( - `For using '${colors.green( - commandOptions.name.split(" ")[0], - )}' command you need to install: '${colors.green(dependency)}' package`, - ); - }); + await promptInstallation(dependency, () => { + this.logger.error( + `For using '${colors.green( + commandOptions.name.split(" ")[0], + )}' command you need to install: '${colors.green(dependency)}' package.`, + ); + }); } } @@ -159,11 +165,11 @@ class WebpackCLI { commandOptions.description } To see all available options you need to install ${commandOptions.dependencies .map((dependency) => `'${dependency}'`) - .join(",")}.`, + .join(", ")}.`, ); options = []; } else { - options = options(); + options = await options(); } } @@ -709,69 +715,71 @@ class WebpackCLI { } } - async run(args, parseOptions) { - // Built-in internal commands - const buildCommandOptions = { - name: "build [entries...]", - alias: ["bundle", "b"], - description: "Run webpack (default command, can be omitted).", - usage: "[entries...] [options]", - }; - const watchCommandOptions = { - name: "watch [entries...]", - alias: "w", - description: "Run webpack and watch for files changes.", - usage: "[entries...] [options]", - }; - const versionCommandOptions = { - name: "version [commands...]", - alias: "v", - description: - "Output the version number of 'webpack', 'webpack-cli' and 'webpack-dev-server' and commands.", - }; - const helpCommandOptions = { - name: "help [command] [option]", - alias: "h", - description: "Display help for commands and options.", - }; - // Built-in external commands - const externalBuiltInCommandsInfo = [ - { - name: "serve [entries...]", - alias: ["server", "s"], - pkg: "@webpack-cli/serve", - }, - { - name: "info", - alias: "i", - pkg: "@webpack-cli/info", - }, - { - name: "init", - alias: ["create", "new", "c", "n"], - pkg: "@webpack-cli/generators", - }, - { - name: "loader", - alias: "l", - pkg: "@webpack-cli/generators", - }, - { - name: "plugin", - alias: "p", - pkg: "@webpack-cli/generators", - }, - { - name: "migrate", - alias: "m", - pkg: "@webpack-cli/migrate", - }, - { - name: "configtest [config-path]", - alias: "t", - pkg: "@webpack-cli/configtest", - }, - ]; + async run(args, parseOptions) { + // Built-in internal commands + const buildCommandOptions = { + name: "build [entries...]", + alias: ["bundle", "b"], + description: "Run webpack (default command, can be omitted).", + usage: "[entries...] [options]", + dependencies: ["webpack"], + }; + const watchCommandOptions = { + name: "watch [entries...]", + alias: "w", + description: "Run webpack and watch for files changes.", + usage: "[entries...] [options]", + dependencies: ["webpack"], + }; + const versionCommandOptions = { + name: "version [commands...]", + alias: "v", + description: + "Output the version number of 'webpack', 'webpack-cli' and 'webpack-dev-server' and commands.", + }; + const helpCommandOptions = { + name: "help [command] [option]", + alias: "h", + description: "Display help for commands and options.", + }; + // Built-in external commands + const externalBuiltInCommandsInfo = [ + { + name: "serve [entries...]", + alias: ["server", "s"], + pkg: "@webpack-cli/serve", + }, + { + name: "info", + alias: "i", + pkg: "@webpack-cli/info", + }, + { + name: "init", + alias: ["create", "new", "c", "n"], + pkg: "@webpack-cli/generators", + }, + { + name: "loader", + alias: "l", + pkg: "@webpack-cli/generators", + }, + { + name: "plugin", + alias: "p", + pkg: "@webpack-cli/generators", + }, + { + name: "migrate", + alias: "m", + pkg: "@webpack-cli/migrate", + }, + { + name: "configtest [config-path]", + alias: "t", + pkg: "@webpack-cli/configtest", + }, + ]; const knownCommands = [ buildCommandOptions, @@ -821,34 +829,38 @@ class WebpackCLI { const isBuildCommandUsed = isCommand(commandName, buildCommandOptions); const isWatchCommandUsed = isCommand(commandName, watchCommandOptions); - if (isBuildCommandUsed || isWatchCommandUsed) { - const options = this.getBuiltInOptions(); - - await this.makeCommand( - isBuildCommandUsed ? buildCommandOptions : watchCommandOptions, - isWatchCommandUsed ? options.filter((option) => option.name !== "watch") : options, - async (entries, options) => { - if (entries.length > 0) { - options.entry = [...entries, ...(options.entry || [])]; - } - - await this.runWebpack(options, isWatchCommandUsed); - }, - ); - } else if (isCommand(commandName, helpCommandOptions)) { - // Stub for the `help` command - this.makeCommand(helpCommandOptions, [], () => {}); - } else if (isCommand(commandName, versionCommandOptions)) { - // Stub for the `help` command - this.makeCommand(versionCommandOptions, [], () => {}); - } else { - const builtInExternalCommandInfo = externalBuiltInCommandsInfo.find( - (externalBuiltInCommandInfo) => - getCommandName(externalBuiltInCommandInfo.name) === commandName || - (Array.isArray(externalBuiltInCommandInfo.alias) - ? externalBuiltInCommandInfo.alias.includes(commandName) - : externalBuiltInCommandInfo.alias === commandName), - ); + if (isBuildCommandUsed || isWatchCommandUsed) { + await this.makeCommand( + isBuildCommandUsed ? buildCommandOptions : watchCommandOptions, + async () => { + this.webpack = await this.loadWebpack(); + + return isWatchCommandUsed + ? this.getBuiltInOptions().filter((option) => option.name !== "watch") + : this.getBuiltInOptions(); + }, + async (entries, options) => { + if (entries.length > 0) { + options.entry = [...entries, ...(options.entry || [])]; + } + + await this.runWebpack(options, isWatchCommandUsed); + }, + ); + } else if (isCommand(commandName, helpCommandOptions)) { + // Stub for the `help` command + this.makeCommand(helpCommandOptions, [], () => {}); + } else if (isCommand(commandName, versionCommandOptions)) { + // Stub for the `version` command + this.makeCommand(versionCommandOptions, [], () => {}); + } else { + const builtInExternalCommandInfo = externalBuiltInCommandsInfo.find( + (externalBuiltInCommandInfo) => + getCommandName(externalBuiltInCommandInfo.name) === commandName || + (Array.isArray(externalBuiltInCommandInfo.alias) + ? externalBuiltInCommandInfo.alias.includes(commandName) + : externalBuiltInCommandInfo.alias === commandName), + ); let pkg; @@ -865,12 +877,14 @@ class WebpackCLI { const { promptInstallation, colors } = this.utils; - pkg = await promptInstallation(pkg, () => { - this.logger.error( - `For using this command you need to install: '${colors.green(pkg)}' package`, - ); - }); - } + pkg = await promptInstallation(pkg, () => { + this.logger.error( + `For using this command you need to install: '${colors.green( + pkg, + )}' package.`, + ); + }); + } let loadedCommand; @@ -1021,16 +1035,31 @@ class WebpackCLI { } } - const pkgJSON = this.loadJSONFile("../package.json"); + let webpack; - this.logger.raw(`webpack ${this.webpack.version}`); - this.logger.raw(`webpack-cli ${pkgJSON.version}`); + try { + webpack = await this.loadWebpack(false); + } catch (_error) { + // Nothing + } - if (this.utils.packageExists("webpack-dev-server")) { - const { version } = this.loadJSONFile("webpack-dev-server/package.json"); + this.logger.raw(`webpack: ${webpack ? webpack.version : "not installed"}`); - this.logger.raw(`webpack-dev-server ${version}`); - } + const pkgJSON = this.loadJSONFile("../package.json"); + + this.logger.raw(`webpack-cli: ${pkgJSON.version}`); + + let devServer; + + try { + devServer = await this.loadJSONFile("webpack-dev-server/package.json", false); + } catch (_error) { + // Nothing + } + + this.logger.raw( + `webpack-dev-server ${devServer ? devServer.version : "not installed"}`, + ); process.exit(0); }; @@ -1208,20 +1237,22 @@ class WebpackCLI { const command = findCommandByName(name); - if (!command) { - const builtInCommandUsed = externalBuiltInCommandsInfo.find( - (command) => command.name.includes(name) || name === command.alias, - ); - if (typeof builtInCommandUsed !== "undefined") { - this.logger.error( - `For using '${name}' command you need to install '${builtInCommandUsed.pkg}' package`, - ); - } else { - this.logger.error(`Can't find and load command '${name}'`); - this.logger.error("Run 'webpack --help' to see available commands and options"); - } - process.exit(2); - } + if (!command) { + const builtInCommandUsed = externalBuiltInCommandsInfo.find( + (command) => command.name.includes(name) || name === command.alias, + ); + if (typeof builtInCommandUsed !== "undefined") { + this.logger.error( + `For using '${name}' command you need to install '${builtInCommandUsed.pkg}' package.`, + ); + } else { + this.logger.error(`Can't find and load command '${name}'`); + this.logger.error( + "Run 'webpack --help' to see available commands and options.", + ); + } + process.exit(2); + } this.logger.raw(command.helpInformation()); } diff --git a/smoketests/helpers.js b/smoketests/helpers.js index e67d760a0fb..c8bd6f8873f 100644 --- a/smoketests/helpers.js +++ b/smoketests/helpers.js @@ -11,21 +11,24 @@ const ROOT_PATH = process.env.GITHUB_WORKSPACE const getPkgPath = (pkg, isSubPackage) => { const pkgPath = isSubPackage ? `./node_modules/@webpack-cli/${pkg}` : `./node_modules/${pkg}`; + return path.resolve(ROOT_PATH, pkgPath); }; const swapPkgName = (current, isSubPackage = false) => { // info -> .info and vice-versa const next = current.startsWith(".") ? current.substr(1) : `.${current}`; + console.log(` swapping ${current} with ${next}`); + fs.renameSync(getPkgPath(current, isSubPackage), getPkgPath(next, isSubPackage)); }; const CLI_ENTRY_PATH = path.resolve(ROOT_PATH, "./packages/webpack-cli/bin/cli.js"); -const runTest = (package, cliArgs = [], logMessage, isSubPackage = false) => { +const runTest = (pkg, cliArgs = [], logMessage, isSubPackage = false) => { // Simulate package missing - swapPkgName(package, isSubPackage); + swapPkgName(pkg, isSubPackage); const proc = execa(CLI_ENTRY_PATH, cliArgs, { cwd: __dirname, @@ -50,6 +53,7 @@ const runTest = (package, cliArgs = [], logMessage, isSubPackage = false) => { proc.stderr.on("data", (chunk) => { const data = stripAnsi(chunk.toString()); + console.log(` stderr: ${data}`); if (data.includes(logMessage)) { @@ -67,13 +71,13 @@ const runTest = (package, cliArgs = [], logMessage, isSubPackage = false) => { }); proc.on("exit", () => { - swapPkgName(`.${package}`, isSubPackage); + swapPkgName(`.${pkg}`, isSubPackage); clearTimeout(timeout); resolve(hasPassed); }); proc.on("error", () => { - swapPkgName(`.${package}`, isSubPackage); + swapPkgName(`.${pkg}`, isSubPackage); clearTimeout(timeout); resolve(false); }); @@ -100,6 +104,7 @@ const runTestStdout = ({ packageName, cliArgs, logMessage, isSubPackage } = {}) proc.stdout.on("data", (chunk) => { const data = stripAnsi(chunk.toString()); + console.log(` stdout: ${data}`); if (data.includes(logMessage)) { @@ -186,9 +191,9 @@ const runTestStdoutWithInput = ({ }); }; -const runTestWithHelp = (package, cliArgs = [], logMessage, isSubPackage = false) => { +const runTestWithHelp = (pkg, cliArgs = [], logMessage, isSubPackage = false) => { // Simulate package missing - swapPkgName(package, isSubPackage); + swapPkgName(pkg, isSubPackage); const proc = execa(CLI_ENTRY_PATH, cliArgs, { cwd: __dirname, @@ -214,6 +219,7 @@ const runTestWithHelp = (package, cliArgs = [], logMessage, isSubPackage = false proc.stderr.on("data", (chunk) => { const data = stripAnsi(chunk.toString()); + console.log(` stderr: ${data}`); if (data.includes(logMessage)) { @@ -231,13 +237,13 @@ const runTestWithHelp = (package, cliArgs = [], logMessage, isSubPackage = false }); proc.on("exit", () => { - swapPkgName(`.${package}`, isSubPackage); + swapPkgName(`.${pkg}`, isSubPackage); clearTimeout(timeout); resolve(hasPassed); }); proc.on("error", () => { - swapPkgName(`.${package}`, isSubPackage); + swapPkgName(`.${pkg}`, isSubPackage); clearTimeout(timeout); resolve(false); }); diff --git a/smoketests/index.js b/smoketests/index.js index 04a21b169c2..cb594b2bab5 100644 --- a/smoketests/index.js +++ b/smoketests/index.js @@ -10,24 +10,28 @@ const tests = [ ]; (async () => { - let isAllPassed = true; - for await (const test of tests) { - console.log(`\nRUN ${test.name}`); + let isAllPassed = true; - let isPass = true; - for await (const testCase of test.run) { - isPass = isPass && (await testCase()); + for await (const test of tests) { + console.log(`\nRUN ${test.name}`); + + let isPass = true; + + for await (const testCase of test.run) { + isPass = isPass && (await testCase()); + } + + if (!isPass) { + console.log(`FAIL ${test.name}`); + isAllPassed = false; + } else { + console.log(`PASS ${test.name}`); + } } - if (!isPass) { - console.log(`FAIL ${test.name}`); - isAllPassed = false; - } else { - console.log(`PASS ${test.name}`); + if (!isAllPassed) { + process.exit(2); } - } - if (!isAllPassed) { - process.exit(2); - } - process.exit(0); + + process.exit(0); })(); diff --git a/smoketests/missing-packages/webpack.test.js b/smoketests/missing-packages/webpack.test.js index d940e8f5fcc..e1f9b244a37 100644 --- a/smoketests/missing-packages/webpack.test.js +++ b/smoketests/missing-packages/webpack.test.js @@ -1,14 +1,79 @@ "use strict"; -const { runTest } = require("../helpers"); +const { runTest, runTestStdout } = require("../helpers"); -const webpackTest = () => { - const packageName = "webpack"; - const args = []; - const logMessage = "It looks like webpack is not installed."; +const noCommand = () => { + const packageName = "webpack"; + const args = []; + const logMessage = "For using 'build' command you need to install: 'webpack' package."; - return runTest(packageName, args, logMessage); + return runTest(packageName, args, logMessage); }; -module.exports.run = [webpackTest]; +const buildCommand = () => { + const packageName = "webpack"; + const args = ["build"]; + const logMessage = "For using 'build' command you need to install: 'webpack' package."; + + return runTest(packageName, args, logMessage); +}; + +const watchCommand = () => { + const packageName = "webpack"; + const args = ["watch"]; + const logMessage = "For using 'watch' command you need to install: 'webpack' package."; + + return runTest(packageName, args, logMessage); +}; + +const serveCommand = () => { + const packageName = "webpack"; + const args = ["serve"]; + const logMessage = "For using 'serve' command you need to install: 'webpack' package."; + + return runTest(packageName, args, logMessage); +}; + +const versionCommand = () => { + const packageName = "webpack"; + const args = ["version"]; + const logMessage = "webpack-cli:"; + + return runTestStdout({ packageName, cliArgs: args, logMessage }); +}; + +const helpCommand = () => { + const packageName = "webpack"; + const args = ["help"]; + const logMessage = "The build tool for modern web applications."; + + return runTestStdout({ packageName, cliArgs: args, logMessage }); +}; + +const infoCommand = () => { + const packageName = "webpack"; + const args = ["info"]; + const logMessage = "System:"; + + return runTestStdout({ packageName, cliArgs: args, logMessage }); +}; + +const configtestCommand = () => { + const packageName = "webpack"; + const args = ["configtest"]; + const logMessage = "For using 'configtest' command you need to install: 'webpack' package."; + + return runTest(packageName, args, logMessage); +}; + +module.exports.run = [ + noCommand, + buildCommand, + watchCommand, + serveCommand, + configtestCommand, + versionCommand, + infoCommand, + helpCommand, +]; module.exports.name = "Missing webpack"; diff --git a/test/help/__snapshots__/help.test.js.snap.devServer3.webpack4 b/test/help/__snapshots__/help.test.js.snap.devServer3.webpack4 index c8b13330a95..fe305e2bd43 100644 --- a/test/help/__snapshots__/help.test.js.snap.devServer3.webpack4 +++ b/test/help/__snapshots__/help.test.js.snap.devServer3.webpack4 @@ -52,14 +52,14 @@ exports[`help should log error for invalid flag with the "--help" option: stdout exports[`help should log error for unknown command using command syntax #2: stderr 1`] = ` "[webpack-cli] Can't find and load command 'verbose' -[webpack-cli] Run 'webpack --help' to see available commands and options" +[webpack-cli] Run 'webpack --help' to see available commands and options." `; exports[`help should log error for unknown command using command syntax #2: stdout 1`] = `""`; exports[`help should log error for unknown command using command syntax: stderr 1`] = ` "[webpack-cli] Can't find and load command 'myCommand' -[webpack-cli] Run 'webpack --help' to see available commands and options" +[webpack-cli] Run 'webpack --help' to see available commands and options." `; exports[`help should log error for unknown command using command syntax: stdout 1`] = `""`; diff --git a/test/help/__snapshots__/help.test.js.snap.devServer3.webpack5 b/test/help/__snapshots__/help.test.js.snap.devServer3.webpack5 index 37c30d8aefb..5dd3e3d69c6 100644 --- a/test/help/__snapshots__/help.test.js.snap.devServer3.webpack5 +++ b/test/help/__snapshots__/help.test.js.snap.devServer3.webpack5 @@ -52,14 +52,14 @@ exports[`help should log error for invalid flag with the "--help" option: stdout exports[`help should log error for unknown command using command syntax #2: stderr 1`] = ` "[webpack-cli] Can't find and load command 'verbose' -[webpack-cli] Run 'webpack --help' to see available commands and options" +[webpack-cli] Run 'webpack --help' to see available commands and options." `; exports[`help should log error for unknown command using command syntax #2: stdout 1`] = `""`; exports[`help should log error for unknown command using command syntax: stderr 1`] = ` "[webpack-cli] Can't find and load command 'myCommand' -[webpack-cli] Run 'webpack --help' to see available commands and options" +[webpack-cli] Run 'webpack --help' to see available commands and options." `; exports[`help should log error for unknown command using command syntax: stdout 1`] = `""`; diff --git a/test/help/__snapshots__/help.test.js.snap.devServer4.webpack4 b/test/help/__snapshots__/help.test.js.snap.devServer4.webpack4 index 8e6d3c6e502..0ba6c2bf8d9 100644 --- a/test/help/__snapshots__/help.test.js.snap.devServer4.webpack4 +++ b/test/help/__snapshots__/help.test.js.snap.devServer4.webpack4 @@ -52,14 +52,14 @@ exports[`help should log error for invalid flag with the "--help" option: stdout exports[`help should log error for unknown command using command syntax #2: stderr 1`] = ` "[webpack-cli] Can't find and load command 'verbose' -[webpack-cli] Run 'webpack --help' to see available commands and options" +[webpack-cli] Run 'webpack --help' to see available commands and options." `; exports[`help should log error for unknown command using command syntax #2: stdout 1`] = `""`; exports[`help should log error for unknown command using command syntax: stderr 1`] = ` "[webpack-cli] Can't find and load command 'myCommand' -[webpack-cli] Run 'webpack --help' to see available commands and options" +[webpack-cli] Run 'webpack --help' to see available commands and options." `; exports[`help should log error for unknown command using command syntax: stdout 1`] = `""`; diff --git a/test/help/__snapshots__/help.test.js.snap.devServer4.webpack5 b/test/help/__snapshots__/help.test.js.snap.devServer4.webpack5 index 56259dec98e..710a6ec9751 100644 --- a/test/help/__snapshots__/help.test.js.snap.devServer4.webpack5 +++ b/test/help/__snapshots__/help.test.js.snap.devServer4.webpack5 @@ -52,14 +52,14 @@ exports[`help should log error for invalid flag with the "--help" option: stdout exports[`help should log error for unknown command using command syntax #2: stderr 1`] = ` "[webpack-cli] Can't find and load command 'verbose' -[webpack-cli] Run 'webpack --help' to see available commands and options" +[webpack-cli] Run 'webpack --help' to see available commands and options." `; exports[`help should log error for unknown command using command syntax #2: stdout 1`] = `""`; exports[`help should log error for unknown command using command syntax: stderr 1`] = ` "[webpack-cli] Can't find and load command 'myCommand' -[webpack-cli] Run 'webpack --help' to see available commands and options" +[webpack-cli] Run 'webpack --help' to see available commands and options." `; exports[`help should log error for unknown command using command syntax: stdout 1`] = `""`; diff --git a/test/version/__snapshots__/version.test.js.snap.webpack4 b/test/version/__snapshots__/version.test.js.snap.webpack4 index eb5f5200f1f..7ee6aa6b9f8 100644 --- a/test/version/__snapshots__/version.test.js.snap.webpack4 +++ b/test/version/__snapshots__/version.test.js.snap.webpack4 @@ -3,24 +3,24 @@ exports[`single version flag outputs version with b: stderr 1`] = `""`; exports[`single version flag outputs version with b: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs version with build: stderr 1`] = `""`; exports[`single version flag outputs version with build: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs version with bundle: stderr 1`] = `""`; exports[`single version flag outputs version with bundle: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -28,8 +28,8 @@ exports[`single version flag outputs version with info using command alias: stde exports[`single version flag outputs version with info using command alias: stdout 1`] = ` "@webpack-cli/info x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -37,8 +37,8 @@ exports[`single version flag outputs version with info using command syntax: std exports[`single version flag outputs version with info using command syntax: stdout 1`] = ` "@webpack-cli/info x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -46,8 +46,8 @@ exports[`single version flag outputs version with info using option alias: stder exports[`single version flag outputs version with info using option alias: stdout 1`] = ` "@webpack-cli/info x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -55,8 +55,8 @@ exports[`single version flag outputs version with info: stderr 1`] = `""`; exports[`single version flag outputs version with info: stdout 1`] = ` "@webpack-cli/info x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -64,8 +64,8 @@ exports[`single version flag outputs version with init: stderr 1`] = `""`; exports[`single version flag outputs version with init: stdout 1`] = ` "@webpack-cli/generators x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -73,8 +73,8 @@ exports[`single version flag outputs version with loader: stderr 1`] = `""`; exports[`single version flag outputs version with loader: stdout 1`] = ` "@webpack-cli/generators x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -82,8 +82,8 @@ exports[`single version flag outputs version with migrate: stderr 1`] = `""`; exports[`single version flag outputs version with migrate: stdout 1`] = ` "@webpack-cli/migrate x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -91,8 +91,8 @@ exports[`single version flag outputs version with plugin: stderr 1`] = `""`; exports[`single version flag outputs version with plugin: stdout 1`] = ` "@webpack-cli/generators x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -100,8 +100,8 @@ exports[`single version flag outputs version with serve: stderr 1`] = `""`; exports[`single version flag outputs version with serve: stdout 1`] = ` "@webpack-cli/serve x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -109,80 +109,80 @@ exports[`single version flag outputs version with the alias c for init: stderr 1 exports[`single version flag outputs version with the alias c for init: stdout 1`] = ` "@webpack-cli/generators x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs version with w: stderr 1`] = `""`; exports[`single version flag outputs version with w: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs version with watch: stderr 1`] = `""`; exports[`single version flag outputs version with watch: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with --color using command syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with --color using command syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with --color using option syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with --color using option syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with --no-color using command syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with --no-color using command syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with --no-color using option syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with --no-color using option syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with alias syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with alias syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with command syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with command syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with dashed syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with dashed syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -281,16 +281,16 @@ exports[`single version flag should output versions for multiple commands using exports[`single version flag should output versions for multiple commands using command syntax: stdout 1`] = ` "@webpack-cli/info x.x.x @webpack-cli/serve x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag should output versions with help command using command syntax: stderr 1`] = `""`; exports[`single version flag should output versions with help command using command syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -299,24 +299,24 @@ exports[`single version flag should work for multiple commands: stderr 1`] = `"" exports[`single version flag should work for multiple commands: stdout 1`] = ` "@webpack-cli/info x.x.x @webpack-cli/serve x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag should work using command syntax and the "--version" argument: stderr 1`] = `""`; exports[`single version flag should work using command syntax and the "--version" argument: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag should work using command syntax with the "version" value: stderr 1`] = `""`; exports[`single version flag should work using command syntax with the "version" value: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; diff --git a/test/version/__snapshots__/version.test.js.snap.webpack5 b/test/version/__snapshots__/version.test.js.snap.webpack5 index eb5f5200f1f..7ee6aa6b9f8 100644 --- a/test/version/__snapshots__/version.test.js.snap.webpack5 +++ b/test/version/__snapshots__/version.test.js.snap.webpack5 @@ -3,24 +3,24 @@ exports[`single version flag outputs version with b: stderr 1`] = `""`; exports[`single version flag outputs version with b: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs version with build: stderr 1`] = `""`; exports[`single version flag outputs version with build: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs version with bundle: stderr 1`] = `""`; exports[`single version flag outputs version with bundle: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -28,8 +28,8 @@ exports[`single version flag outputs version with info using command alias: stde exports[`single version flag outputs version with info using command alias: stdout 1`] = ` "@webpack-cli/info x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -37,8 +37,8 @@ exports[`single version flag outputs version with info using command syntax: std exports[`single version flag outputs version with info using command syntax: stdout 1`] = ` "@webpack-cli/info x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -46,8 +46,8 @@ exports[`single version flag outputs version with info using option alias: stder exports[`single version flag outputs version with info using option alias: stdout 1`] = ` "@webpack-cli/info x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -55,8 +55,8 @@ exports[`single version flag outputs version with info: stderr 1`] = `""`; exports[`single version flag outputs version with info: stdout 1`] = ` "@webpack-cli/info x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -64,8 +64,8 @@ exports[`single version flag outputs version with init: stderr 1`] = `""`; exports[`single version flag outputs version with init: stdout 1`] = ` "@webpack-cli/generators x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -73,8 +73,8 @@ exports[`single version flag outputs version with loader: stderr 1`] = `""`; exports[`single version flag outputs version with loader: stdout 1`] = ` "@webpack-cli/generators x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -82,8 +82,8 @@ exports[`single version flag outputs version with migrate: stderr 1`] = `""`; exports[`single version flag outputs version with migrate: stdout 1`] = ` "@webpack-cli/migrate x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -91,8 +91,8 @@ exports[`single version flag outputs version with plugin: stderr 1`] = `""`; exports[`single version flag outputs version with plugin: stdout 1`] = ` "@webpack-cli/generators x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -100,8 +100,8 @@ exports[`single version flag outputs version with serve: stderr 1`] = `""`; exports[`single version flag outputs version with serve: stdout 1`] = ` "@webpack-cli/serve x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -109,80 +109,80 @@ exports[`single version flag outputs version with the alias c for init: stderr 1 exports[`single version flag outputs version with the alias c for init: stdout 1`] = ` "@webpack-cli/generators x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs version with w: stderr 1`] = `""`; exports[`single version flag outputs version with w: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs version with watch: stderr 1`] = `""`; exports[`single version flag outputs version with watch: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with --color using command syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with --color using command syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with --color using option syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with --color using option syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with --no-color using command syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with --no-color using command syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with --no-color using option syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with --no-color using option syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with alias syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with alias syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with command syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with command syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag outputs versions with dashed syntax: stderr 1`] = `""`; exports[`single version flag outputs versions with dashed syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -281,16 +281,16 @@ exports[`single version flag should output versions for multiple commands using exports[`single version flag should output versions for multiple commands using command syntax: stdout 1`] = ` "@webpack-cli/info x.x.x @webpack-cli/serve x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag should output versions with help command using command syntax: stderr 1`] = `""`; exports[`single version flag should output versions with help command using command syntax: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; @@ -299,24 +299,24 @@ exports[`single version flag should work for multiple commands: stderr 1`] = `"" exports[`single version flag should work for multiple commands: stdout 1`] = ` "@webpack-cli/info x.x.x @webpack-cli/serve x.x.x -webpack x.x.x -webpack-cli x.x.x +webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag should work using command syntax and the "--version" argument: stderr 1`] = `""`; exports[`single version flag should work using command syntax and the "--version" argument: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; exports[`single version flag should work using command syntax with the "version" value: stderr 1`] = `""`; exports[`single version flag should work using command syntax with the "version" value: stdout 1`] = ` -"webpack x.x.x -webpack-cli x.x.x +"webpack: x.x.x +webpack-cli: x.x.x webpack-dev-server x.x.x" `; From 41868ba2dbd83f7fc1c0d4e858cb2a6e8c68a71b Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Sat, 21 Aug 2021 19:30:48 +0300 Subject: [PATCH 2/8] fix: configtest logic --- packages/configtest/src/index.ts | 119 ++++++++++++++++--------------- 1 file changed, 61 insertions(+), 58 deletions(-) diff --git a/packages/configtest/src/index.ts b/packages/configtest/src/index.ts index 997bfdb0186..937fa11bb55 100644 --- a/packages/configtest/src/index.ts +++ b/packages/configtest/src/index.ts @@ -1,62 +1,65 @@ class ConfigTestCommand { - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any - async apply(cli: any): Promise { - await cli.makeCommand( - { - name: "configtest [config-path]", - alias: "t", - description: "Validate a webpack configuration.", - pkg: "@webpack-cli/configtest", - dependencies: ["webpack"], - }, - [], - async (configPath: string | undefined): Promise => { - const config = await cli.resolveConfig(configPath ? { config: [configPath] } : {}); - const configPaths = new Set(); - - if (Array.isArray(config.options)) { - config.options.forEach((options) => { - if (config.path.get(options)) { - configPaths.add(config.path.get(options)); - } - }); - } else { - if (config.path.get(config.options)) { - configPaths.add(config.path.get(config.options)); - } - } - - if (configPaths.size === 0) { - cli.logger.error("No configuration found."); - process.exit(2); - } - - cli.logger.info(`Validate '${Array.from(configPaths).join(" ,")}'.`); - - const webpack = await cli.loadWebpack(); - - try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const error: any = webpack.validate(config.options); - - // TODO remove this after drop webpack@4 - if (error && error.length > 0) { - throw new webpack.WebpackOptionsValidationError(error); - } - } catch (error) { - if (cli.isValidationError(error)) { - cli.logger.error(error.message); - } else { - cli.logger.error(error); - } - - process.exit(2); - } - - cli.logger.success("There are no validation errors in the given webpack configuration."); - }, - ); - } + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any + async apply(cli: any): Promise { + await cli.makeCommand( + { + name: "configtest [config-path]", + alias: "t", + description: "Validate a webpack configuration.", + pkg: "@webpack-cli/configtest", + dependencies: ["webpack"], + }, + [], + async (configPath: string | undefined): Promise => { + cli.webpack = await cli.loadWebpack(); + + const config = await cli.resolveConfig(configPath ? { config: [configPath] } : {}); + const configPaths = new Set(); + + if (Array.isArray(config.options)) { + config.options.forEach((options) => { + if (config.path.get(options)) { + configPaths.add(config.path.get(options)); + } + }); + } else { + if (config.path.get(config.options)) { + configPaths.add(config.path.get(config.options)); + } + } + + if (configPaths.size === 0) { + cli.logger.error("No configuration found."); + process.exit(2); + } + + cli.logger.info(`Validate '${Array.from(configPaths).join(" ,")}'.`); + + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const error: any = cli.webpack.validate(config.options); + + // TODO remove this after drop webpack@4 + if (error && error.length > 0) { + throw new cli.webpack.WebpackOptionsValidationError(error); + } + } catch (error) { + if (error instanceof cli.webpack.ValidationError || + error.name === "ValidationError") { + cli.logger.error(error.message); + } else { + cli.logger.error(error); + } + + process.exit(2); + } + + cli.logger.success( + "There are no validation errors in the given webpack configuration.", + ); + }, + ); + } } export default ConfigTestCommand; From 29e532614483ff68073bdd13bf455a2cd50d01d6 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 24 Aug 2021 14:35:27 +0300 Subject: [PATCH 3/8] chore: fix lint after merge --- packages/configtest/src/index.ts | 119 ++++---- packages/serve/src/index.ts | 6 +- packages/webpack-cli/lib/webpack-cli.js | 314 ++++++++++---------- smoketests/helpers.js | 6 +- smoketests/index.js | 34 +-- smoketests/missing-packages/webpack.test.js | 80 ++--- 6 files changed, 275 insertions(+), 284 deletions(-) diff --git a/packages/configtest/src/index.ts b/packages/configtest/src/index.ts index 937fa11bb55..b36ac9cb59a 100644 --- a/packages/configtest/src/index.ts +++ b/packages/configtest/src/index.ts @@ -1,65 +1,62 @@ class ConfigTestCommand { - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any - async apply(cli: any): Promise { - await cli.makeCommand( - { - name: "configtest [config-path]", - alias: "t", - description: "Validate a webpack configuration.", - pkg: "@webpack-cli/configtest", - dependencies: ["webpack"], - }, - [], - async (configPath: string | undefined): Promise => { - cli.webpack = await cli.loadWebpack(); - - const config = await cli.resolveConfig(configPath ? { config: [configPath] } : {}); - const configPaths = new Set(); - - if (Array.isArray(config.options)) { - config.options.forEach((options) => { - if (config.path.get(options)) { - configPaths.add(config.path.get(options)); - } - }); - } else { - if (config.path.get(config.options)) { - configPaths.add(config.path.get(config.options)); - } - } - - if (configPaths.size === 0) { - cli.logger.error("No configuration found."); - process.exit(2); - } - - cli.logger.info(`Validate '${Array.from(configPaths).join(" ,")}'.`); - - try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const error: any = cli.webpack.validate(config.options); - - // TODO remove this after drop webpack@4 - if (error && error.length > 0) { - throw new cli.webpack.WebpackOptionsValidationError(error); - } - } catch (error) { - if (error instanceof cli.webpack.ValidationError || - error.name === "ValidationError") { - cli.logger.error(error.message); - } else { - cli.logger.error(error); - } - - process.exit(2); - } - - cli.logger.success( - "There are no validation errors in the given webpack configuration.", - ); - }, - ); - } + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any + async apply(cli: any): Promise { + await cli.makeCommand( + { + name: "configtest [config-path]", + alias: "t", + description: "Validate a webpack configuration.", + pkg: "@webpack-cli/configtest", + dependencies: ["webpack"], + }, + [], + async (configPath: string | undefined): Promise => { + cli.webpack = await cli.loadWebpack(); + + const config = await cli.resolveConfig(configPath ? { config: [configPath] } : {}); + const configPaths = new Set(); + + if (Array.isArray(config.options)) { + config.options.forEach((options) => { + if (config.path.get(options)) { + configPaths.add(config.path.get(options)); + } + }); + } else { + if (config.path.get(config.options)) { + configPaths.add(config.path.get(config.options)); + } + } + + if (configPaths.size === 0) { + cli.logger.error("No configuration found."); + process.exit(2); + } + + cli.logger.info(`Validate '${Array.from(configPaths).join(" ,")}'.`); + + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const error: any = cli.webpack.validate(config.options); + + // TODO remove this after drop webpack@4 + if (error && error.length > 0) { + throw new cli.webpack.WebpackOptionsValidationError(error); + } + } catch (error) { + if (error instanceof cli.webpack.ValidationError || error.name === "ValidationError") { + cli.logger.error(error.message); + } else { + cli.logger.error(error); + } + + process.exit(2); + } + + cli.logger.success("There are no validation errors in the given webpack configuration."); + }, + ); + } } export default ConfigTestCommand; diff --git a/packages/serve/src/index.ts b/packages/serve/src/index.ts index d1db60410e5..c4209b10388 100644 --- a/packages/serve/src/index.ts +++ b/packages/serve/src/index.ts @@ -3,7 +3,7 @@ import { devServerOptionsType } from "./types"; class ServeCommand { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any async apply(cli: any): Promise { - const loadDevServerOptions = () => { + const loadDevServerOptions = () => { // TODO simplify this after drop webpack v4 and webpack-dev-server v3 // eslint-disable-next-line @typescript-eslint/no-var-requires, node/no-extraneous-require const devServer = require("webpack-dev-server"); @@ -333,9 +333,9 @@ class ServeCommand { servers.push(server); } catch (error) { if (cli.isValidationError(error)) { - cli.logger.error(error.message); + cli.logger.error(error.message); } else { - cli.logger.error(error); + cli.logger.error(error); } process.exit(2); diff --git a/packages/webpack-cli/lib/webpack-cli.js b/packages/webpack-cli/lib/webpack-cli.js index 3c96870ce61..acd0e1e74b3 100644 --- a/packages/webpack-cli/lib/webpack-cli.js +++ b/packages/webpack-cli/lib/webpack-cli.js @@ -70,26 +70,26 @@ class WebpackCLI { return result; } - + loadJSONFile(pathToFile, handleError = true) { - let result; + let result; - try { - result = require(pathToFile); - } catch (error) { - if (handleError) { - this.logger.error(error); - process.exit(2); - } else { - throw error; - } - } + try { + result = require(pathToFile); + } catch (error) { + if (handleError) { + this.logger.error(error); + process.exit(2); + } else { + throw error; + } + } - return result; + return result; } async loadWebpack(handleError = true) { - return this.tryRequireThenImport(process.env.WEBPACK_PACKAGE || "webpack", handleError); + return this.tryRequireThenImport(process.env.WEBPACK_PACKAGE || "webpack", handleError); } async makeCommand(commandOptions, options, action) { @@ -147,13 +147,13 @@ class WebpackCLI { const { promptInstallation, colors } = this.utils; - await promptInstallation(dependency, () => { - this.logger.error( - `For using '${colors.green( - commandOptions.name.split(" ")[0], - )}' command you need to install: '${colors.green(dependency)}' package.`, - ); - }); + await promptInstallation(dependency, () => { + this.logger.error( + `For using '${colors.green( + commandOptions.name.split(" ")[0], + )}' command you need to install: '${colors.green(dependency)}' package.`, + ); + }); } } @@ -715,71 +715,71 @@ class WebpackCLI { } } - async run(args, parseOptions) { - // Built-in internal commands - const buildCommandOptions = { - name: "build [entries...]", - alias: ["bundle", "b"], - description: "Run webpack (default command, can be omitted).", - usage: "[entries...] [options]", - dependencies: ["webpack"], - }; - const watchCommandOptions = { - name: "watch [entries...]", - alias: "w", - description: "Run webpack and watch for files changes.", - usage: "[entries...] [options]", - dependencies: ["webpack"], - }; - const versionCommandOptions = { - name: "version [commands...]", - alias: "v", - description: - "Output the version number of 'webpack', 'webpack-cli' and 'webpack-dev-server' and commands.", - }; - const helpCommandOptions = { - name: "help [command] [option]", - alias: "h", - description: "Display help for commands and options.", - }; - // Built-in external commands - const externalBuiltInCommandsInfo = [ - { - name: "serve [entries...]", - alias: ["server", "s"], - pkg: "@webpack-cli/serve", - }, - { - name: "info", - alias: "i", - pkg: "@webpack-cli/info", - }, - { - name: "init", - alias: ["create", "new", "c", "n"], - pkg: "@webpack-cli/generators", - }, - { - name: "loader", - alias: "l", - pkg: "@webpack-cli/generators", - }, - { - name: "plugin", - alias: "p", - pkg: "@webpack-cli/generators", - }, - { - name: "migrate", - alias: "m", - pkg: "@webpack-cli/migrate", - }, - { - name: "configtest [config-path]", - alias: "t", - pkg: "@webpack-cli/configtest", - }, - ]; + async run(args, parseOptions) { + // Built-in internal commands + const buildCommandOptions = { + name: "build [entries...]", + alias: ["bundle", "b"], + description: "Run webpack (default command, can be omitted).", + usage: "[entries...] [options]", + dependencies: ["webpack"], + }; + const watchCommandOptions = { + name: "watch [entries...]", + alias: "w", + description: "Run webpack and watch for files changes.", + usage: "[entries...] [options]", + dependencies: ["webpack"], + }; + const versionCommandOptions = { + name: "version [commands...]", + alias: "v", + description: + "Output the version number of 'webpack', 'webpack-cli' and 'webpack-dev-server' and commands.", + }; + const helpCommandOptions = { + name: "help [command] [option]", + alias: "h", + description: "Display help for commands and options.", + }; + // Built-in external commands + const externalBuiltInCommandsInfo = [ + { + name: "serve [entries...]", + alias: ["server", "s"], + pkg: "@webpack-cli/serve", + }, + { + name: "info", + alias: "i", + pkg: "@webpack-cli/info", + }, + { + name: "init", + alias: ["create", "new", "c", "n"], + pkg: "@webpack-cli/generators", + }, + { + name: "loader", + alias: "l", + pkg: "@webpack-cli/generators", + }, + { + name: "plugin", + alias: "p", + pkg: "@webpack-cli/generators", + }, + { + name: "migrate", + alias: "m", + pkg: "@webpack-cli/migrate", + }, + { + name: "configtest [config-path]", + alias: "t", + pkg: "@webpack-cli/configtest", + }, + ]; const knownCommands = [ buildCommandOptions, @@ -829,38 +829,38 @@ class WebpackCLI { const isBuildCommandUsed = isCommand(commandName, buildCommandOptions); const isWatchCommandUsed = isCommand(commandName, watchCommandOptions); - if (isBuildCommandUsed || isWatchCommandUsed) { - await this.makeCommand( - isBuildCommandUsed ? buildCommandOptions : watchCommandOptions, - async () => { - this.webpack = await this.loadWebpack(); - - return isWatchCommandUsed - ? this.getBuiltInOptions().filter((option) => option.name !== "watch") - : this.getBuiltInOptions(); - }, - async (entries, options) => { - if (entries.length > 0) { - options.entry = [...entries, ...(options.entry || [])]; - } - - await this.runWebpack(options, isWatchCommandUsed); - }, - ); - } else if (isCommand(commandName, helpCommandOptions)) { - // Stub for the `help` command - this.makeCommand(helpCommandOptions, [], () => {}); - } else if (isCommand(commandName, versionCommandOptions)) { - // Stub for the `version` command - this.makeCommand(versionCommandOptions, [], () => {}); - } else { - const builtInExternalCommandInfo = externalBuiltInCommandsInfo.find( - (externalBuiltInCommandInfo) => - getCommandName(externalBuiltInCommandInfo.name) === commandName || - (Array.isArray(externalBuiltInCommandInfo.alias) - ? externalBuiltInCommandInfo.alias.includes(commandName) - : externalBuiltInCommandInfo.alias === commandName), - ); + if (isBuildCommandUsed || isWatchCommandUsed) { + await this.makeCommand( + isBuildCommandUsed ? buildCommandOptions : watchCommandOptions, + async () => { + this.webpack = await this.loadWebpack(); + + return isWatchCommandUsed + ? this.getBuiltInOptions().filter((option) => option.name !== "watch") + : this.getBuiltInOptions(); + }, + async (entries, options) => { + if (entries.length > 0) { + options.entry = [...entries, ...(options.entry || [])]; + } + + await this.runWebpack(options, isWatchCommandUsed); + }, + ); + } else if (isCommand(commandName, helpCommandOptions)) { + // Stub for the `help` command + this.makeCommand(helpCommandOptions, [], () => {}); + } else if (isCommand(commandName, versionCommandOptions)) { + // Stub for the `version` command + this.makeCommand(versionCommandOptions, [], () => {}); + } else { + const builtInExternalCommandInfo = externalBuiltInCommandsInfo.find( + (externalBuiltInCommandInfo) => + getCommandName(externalBuiltInCommandInfo.name) === commandName || + (Array.isArray(externalBuiltInCommandInfo.alias) + ? externalBuiltInCommandInfo.alias.includes(commandName) + : externalBuiltInCommandInfo.alias === commandName), + ); let pkg; @@ -877,14 +877,12 @@ class WebpackCLI { const { promptInstallation, colors } = this.utils; - pkg = await promptInstallation(pkg, () => { - this.logger.error( - `For using this command you need to install: '${colors.green( - pkg, - )}' package.`, - ); - }); - } + pkg = await promptInstallation(pkg, () => { + this.logger.error( + `For using this command you need to install: '${colors.green(pkg)}' package.`, + ); + }); + } let loadedCommand; @@ -1035,31 +1033,29 @@ class WebpackCLI { } } - let webpack; + let webpack; - try { - webpack = await this.loadWebpack(false); - } catch (_error) { - // Nothing - } + try { + webpack = await this.loadWebpack(false); + } catch (_error) { + // Nothing + } - this.logger.raw(`webpack: ${webpack ? webpack.version : "not installed"}`); + this.logger.raw(`webpack: ${webpack ? webpack.version : "not installed"}`); - const pkgJSON = this.loadJSONFile("../package.json"); + const pkgJSON = this.loadJSONFile("../package.json"); - this.logger.raw(`webpack-cli: ${pkgJSON.version}`); + this.logger.raw(`webpack-cli: ${pkgJSON.version}`); - let devServer; + let devServer; - try { - devServer = await this.loadJSONFile("webpack-dev-server/package.json", false); - } catch (_error) { - // Nothing - } + try { + devServer = await this.loadJSONFile("webpack-dev-server/package.json", false); + } catch (_error) { + // Nothing + } - this.logger.raw( - `webpack-dev-server ${devServer ? devServer.version : "not installed"}`, - ); + this.logger.raw(`webpack-dev-server ${devServer ? devServer.version : "not installed"}`); process.exit(0); }; @@ -1237,22 +1233,20 @@ class WebpackCLI { const command = findCommandByName(name); - if (!command) { - const builtInCommandUsed = externalBuiltInCommandsInfo.find( - (command) => command.name.includes(name) || name === command.alias, - ); - if (typeof builtInCommandUsed !== "undefined") { - this.logger.error( - `For using '${name}' command you need to install '${builtInCommandUsed.pkg}' package.`, - ); - } else { - this.logger.error(`Can't find and load command '${name}'`); - this.logger.error( - "Run 'webpack --help' to see available commands and options.", - ); - } - process.exit(2); - } + if (!command) { + const builtInCommandUsed = externalBuiltInCommandsInfo.find( + (command) => command.name.includes(name) || name === command.alias, + ); + if (typeof builtInCommandUsed !== "undefined") { + this.logger.error( + `For using '${name}' command you need to install '${builtInCommandUsed.pkg}' package.`, + ); + } else { + this.logger.error(`Can't find and load command '${name}'`); + this.logger.error("Run 'webpack --help' to see available commands and options."); + } + process.exit(2); + } this.logger.raw(command.helpInformation()); } diff --git a/smoketests/helpers.js b/smoketests/helpers.js index c8bd6f8873f..255e3fd312e 100644 --- a/smoketests/helpers.js +++ b/smoketests/helpers.js @@ -11,16 +11,16 @@ const ROOT_PATH = process.env.GITHUB_WORKSPACE const getPkgPath = (pkg, isSubPackage) => { const pkgPath = isSubPackage ? `./node_modules/@webpack-cli/${pkg}` : `./node_modules/${pkg}`; - + return path.resolve(ROOT_PATH, pkgPath); }; const swapPkgName = (current, isSubPackage = false) => { // info -> .info and vice-versa const next = current.startsWith(".") ? current.substr(1) : `.${current}`; - + console.log(` swapping ${current} with ${next}`); - + fs.renameSync(getPkgPath(current, isSubPackage), getPkgPath(next, isSubPackage)); }; diff --git a/smoketests/index.js b/smoketests/index.js index cb594b2bab5..8441c4d3ad2 100644 --- a/smoketests/index.js +++ b/smoketests/index.js @@ -10,28 +10,28 @@ const tests = [ ]; (async () => { - let isAllPassed = true; + let isAllPassed = true; - for await (const test of tests) { - console.log(`\nRUN ${test.name}`); + for await (const test of tests) { + console.log(`\nRUN ${test.name}`); - let isPass = true; + let isPass = true; - for await (const testCase of test.run) { - isPass = isPass && (await testCase()); - } - - if (!isPass) { - console.log(`FAIL ${test.name}`); - isAllPassed = false; - } else { - console.log(`PASS ${test.name}`); - } + for await (const testCase of test.run) { + isPass = isPass && (await testCase()); } - if (!isAllPassed) { - process.exit(2); + if (!isPass) { + console.log(`FAIL ${test.name}`); + isAllPassed = false; + } else { + console.log(`PASS ${test.name}`); } + } + + if (!isAllPassed) { + process.exit(2); + } - process.exit(0); + process.exit(0); })(); diff --git a/smoketests/missing-packages/webpack.test.js b/smoketests/missing-packages/webpack.test.js index e1f9b244a37..99ce50e4072 100644 --- a/smoketests/missing-packages/webpack.test.js +++ b/smoketests/missing-packages/webpack.test.js @@ -3,77 +3,77 @@ const { runTest, runTestStdout } = require("../helpers"); const noCommand = () => { - const packageName = "webpack"; - const args = []; - const logMessage = "For using 'build' command you need to install: 'webpack' package."; + const packageName = "webpack"; + const args = []; + const logMessage = "For using 'build' command you need to install: 'webpack' package."; - return runTest(packageName, args, logMessage); + return runTest(packageName, args, logMessage); }; const buildCommand = () => { - const packageName = "webpack"; - const args = ["build"]; - const logMessage = "For using 'build' command you need to install: 'webpack' package."; + const packageName = "webpack"; + const args = ["build"]; + const logMessage = "For using 'build' command you need to install: 'webpack' package."; - return runTest(packageName, args, logMessage); + return runTest(packageName, args, logMessage); }; const watchCommand = () => { - const packageName = "webpack"; - const args = ["watch"]; - const logMessage = "For using 'watch' command you need to install: 'webpack' package."; + const packageName = "webpack"; + const args = ["watch"]; + const logMessage = "For using 'watch' command you need to install: 'webpack' package."; - return runTest(packageName, args, logMessage); + return runTest(packageName, args, logMessage); }; const serveCommand = () => { - const packageName = "webpack"; - const args = ["serve"]; - const logMessage = "For using 'serve' command you need to install: 'webpack' package."; + const packageName = "webpack"; + const args = ["serve"]; + const logMessage = "For using 'serve' command you need to install: 'webpack' package."; - return runTest(packageName, args, logMessage); + return runTest(packageName, args, logMessage); }; const versionCommand = () => { - const packageName = "webpack"; - const args = ["version"]; - const logMessage = "webpack-cli:"; + const packageName = "webpack"; + const args = ["version"]; + const logMessage = "webpack-cli:"; - return runTestStdout({ packageName, cliArgs: args, logMessage }); + return runTestStdout({ packageName, cliArgs: args, logMessage }); }; const helpCommand = () => { - const packageName = "webpack"; - const args = ["help"]; - const logMessage = "The build tool for modern web applications."; + const packageName = "webpack"; + const args = ["help"]; + const logMessage = "The build tool for modern web applications."; - return runTestStdout({ packageName, cliArgs: args, logMessage }); + return runTestStdout({ packageName, cliArgs: args, logMessage }); }; const infoCommand = () => { - const packageName = "webpack"; - const args = ["info"]; - const logMessage = "System:"; + const packageName = "webpack"; + const args = ["info"]; + const logMessage = "System:"; - return runTestStdout({ packageName, cliArgs: args, logMessage }); + return runTestStdout({ packageName, cliArgs: args, logMessage }); }; const configtestCommand = () => { - const packageName = "webpack"; - const args = ["configtest"]; - const logMessage = "For using 'configtest' command you need to install: 'webpack' package."; + const packageName = "webpack"; + const args = ["configtest"]; + const logMessage = "For using 'configtest' command you need to install: 'webpack' package."; - return runTest(packageName, args, logMessage); + return runTest(packageName, args, logMessage); }; module.exports.run = [ - noCommand, - buildCommand, - watchCommand, - serveCommand, - configtestCommand, - versionCommand, - infoCommand, - helpCommand, + noCommand, + buildCommand, + watchCommand, + serveCommand, + configtestCommand, + versionCommand, + infoCommand, + helpCommand, ]; module.exports.name = "Missing webpack"; From 406f222d980b0c065e91cecb42e0a76f21c1b7a7 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 24 Aug 2021 15:10:16 +0300 Subject: [PATCH 4/8] fix: code --- packages/configtest/src/index.ts | 4 ++- packages/serve/src/index.ts | 24 +++++++------ .../lib/utils/prompt-installation.js | 1 + packages/webpack-cli/lib/webpack-cli.js | 8 +++-- yarn.lock | 34 ------------------- 5 files changed, 23 insertions(+), 48 deletions(-) diff --git a/packages/configtest/src/index.ts b/packages/configtest/src/index.ts index b36ac9cb59a..10179693534 100644 --- a/packages/configtest/src/index.ts +++ b/packages/configtest/src/index.ts @@ -1,3 +1,5 @@ +const WEBPACK_PACKAGE = process.env.WEBPACK_PACKAGE || "webpack"; + class ConfigTestCommand { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any async apply(cli: any): Promise { @@ -7,7 +9,7 @@ class ConfigTestCommand { alias: "t", description: "Validate a webpack configuration.", pkg: "@webpack-cli/configtest", - dependencies: ["webpack"], + dependencies: [WEBPACK_PACKAGE], }, [], async (configPath: string | undefined): Promise => { diff --git a/packages/serve/src/index.ts b/packages/serve/src/index.ts index c4209b10388..3f9e0d3d326 100644 --- a/packages/serve/src/index.ts +++ b/packages/serve/src/index.ts @@ -1,12 +1,15 @@ import { devServerOptionsType } from "./types"; +const WEBPACK_PACKAGE = process.env.WEBPACK_PACKAGE || "webpack"; +const WEBPACK_DEV_SERVER_PACKAGE = process.env.WEBPACK_DEV_SERVER_PACKAGE || "webpack-dev-server"; + class ServeCommand { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any async apply(cli: any): Promise { const loadDevServerOptions = () => { // TODO simplify this after drop webpack v4 and webpack-dev-server v3 - // eslint-disable-next-line @typescript-eslint/no-var-requires, node/no-extraneous-require - const devServer = require("webpack-dev-server"); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const devServer = require(WEBPACK_DEV_SERVER_PACKAGE); const isNewDevServerCLIAPI = typeof devServer.schema !== "undefined"; let options = {}; @@ -18,8 +21,7 @@ class ServeCommand { options = devServer.cli.getArguments(); } } else { - // eslint-disable-next-line node/no-extraneous-require - options = require("webpack-dev-server/bin/cli-flags"); + options = require(`${WEBPACK_DEV_SERVER_PACKAGE}/bin/cli-flags`); } // Old options format @@ -48,11 +50,13 @@ class ServeCommand { description: "Run the webpack dev server.", usage: "[entries...] [options]", pkg: "@webpack-cli/serve", - dependencies: ["webpack", "webpack-dev-server"], + dependencies: [WEBPACK_PACKAGE, WEBPACK_DEV_SERVER_PACKAGE], }, - () => { + async () => { let devServerFlags = []; + cli.webpack = await cli.loadWebpack(); + try { devServerFlags = loadDevServerOptions(); } catch (error) { @@ -157,15 +161,15 @@ class ServeCommand { process.stdin.resume(); } - // eslint-disable-next-line @typescript-eslint/no-var-requires, node/no-extraneous-require - const DevServer = require("webpack-dev-server"); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const DevServer = require(WEBPACK_DEV_SERVER_PACKAGE); const isNewDevServerCLIAPI = typeof DevServer.schema !== "undefined"; let devServerVersion; try { - // eslint-disable-next-line node/no-extraneous-require, @typescript-eslint/no-var-requires - devServerVersion = require("webpack-dev-server/package.json").version; + // eslint-disable-next-line @typescript-eslint/no-var-requires + devServerVersion = require(`${WEBPACK_DEV_SERVER_PACKAGE}/package.json`).version; } catch (err) { cli.logger.error( `You need to install 'webpack-dev-server' for running 'webpack serve'.\n${err}`, diff --git a/packages/webpack-cli/lib/utils/prompt-installation.js b/packages/webpack-cli/lib/utils/prompt-installation.js index d4d078d42a0..f67b1bed81b 100644 --- a/packages/webpack-cli/lib/utils/prompt-installation.js +++ b/packages/webpack-cli/lib/utils/prompt-installation.js @@ -23,6 +23,7 @@ async function promptInstallation(packageName, preMessage) { packageManager === "yarn" ? "add" : "install", "-D", packageName, + "--ignore-workspace-root-check", ].join(" ")}`; const { colors } = utils; diff --git a/packages/webpack-cli/lib/webpack-cli.js b/packages/webpack-cli/lib/webpack-cli.js index acd0e1e74b3..c2efa26ae0f 100644 --- a/packages/webpack-cli/lib/webpack-cli.js +++ b/packages/webpack-cli/lib/webpack-cli.js @@ -6,6 +6,8 @@ const Module = require("module"); const { program, Option } = require("commander"); const utils = require("./utils"); +const WEBPACK_PACKAGE = process.env.WEBPACK_PACKAGE || "webpack"; + class WebpackCLI { constructor() { this.logger = utils.logger; @@ -89,7 +91,7 @@ class WebpackCLI { } async loadWebpack(handleError = true) { - return this.tryRequireThenImport(process.env.WEBPACK_PACKAGE || "webpack", handleError); + return this.tryRequireThenImport(WEBPACK_PACKAGE, handleError); } async makeCommand(commandOptions, options, action) { @@ -722,14 +724,14 @@ class WebpackCLI { alias: ["bundle", "b"], description: "Run webpack (default command, can be omitted).", usage: "[entries...] [options]", - dependencies: ["webpack"], + dependencies: [WEBPACK_PACKAGE], }; const watchCommandOptions = { name: "watch [entries...]", alias: "w", description: "Run webpack and watch for files changes.", usage: "[entries...] [options]", - dependencies: ["webpack"], + dependencies: [WEBPACK_PACKAGE], }; const versionCommandOptions = { name: "version [commands...]", diff --git a/yarn.lock b/yarn.lock index 159e695ff6e..a05297ac031 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2074,14 +2074,6 @@ "@typescript-eslint/typescript-estree" "4.29.3" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz#442b0f029d981fa402942715b1718ac7fcd5aa1b" - integrity sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA== - dependencies: - "@typescript-eslint/types" "4.29.2" - "@typescript-eslint/visitor-keys" "4.29.2" - "@typescript-eslint/scope-manager@4.29.3": version "4.29.3" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.3.tgz#497dec66f3a22e459f6e306cf14021e40ec86e19" @@ -2090,29 +2082,11 @@ "@typescript-eslint/types" "4.29.3" "@typescript-eslint/visitor-keys" "4.29.3" -"@typescript-eslint/types@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.2.tgz#fc0489c6b89773f99109fb0aa0aaddff21f52fcd" - integrity sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ== - "@typescript-eslint/types@4.29.3": version "4.29.3" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.3.tgz#d7980c49aef643d0af8954c9f14f656b7fd16017" integrity sha512-s1eV1lKNgoIYLAl1JUba8NhULmf+jOmmeFO1G5MN/RBCyyzg4TIOfIOICVNC06lor+Xmy4FypIIhFiJXOknhIg== -"@typescript-eslint/typescript-estree@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz#a0ea8b98b274adbb2577100ba545ddf8bf7dc219" - integrity sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg== - dependencies: - "@typescript-eslint/types" "4.29.2" - "@typescript-eslint/visitor-keys" "4.29.2" - debug "^4.3.1" - globby "^11.0.3" - is-glob "^4.0.1" - semver "^7.3.5" - tsutils "^3.21.0" - "@typescript-eslint/typescript-estree@4.29.3": version "4.29.3" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.3.tgz#1bafad610015c4ded35c85a70b6222faad598b40" @@ -2126,14 +2100,6 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz#d2da7341f3519486f50655159f4e5ecdcb2cd1df" - integrity sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag== - dependencies: - "@typescript-eslint/types" "4.29.2" - eslint-visitor-keys "^2.0.0" - "@typescript-eslint/visitor-keys@4.29.3": version "4.29.3" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.3.tgz#c691760a00bd86bf8320d2a90a93d86d322f1abf" From 551f61db8f7b09f7398754d6ffb20b4f6ab832be Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 24 Aug 2021 15:22:30 +0300 Subject: [PATCH 5/8] fix: code --- packages/webpack-cli/lib/utils/prompt-installation.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/webpack-cli/lib/utils/prompt-installation.js b/packages/webpack-cli/lib/utils/prompt-installation.js index f67b1bed81b..d4d078d42a0 100644 --- a/packages/webpack-cli/lib/utils/prompt-installation.js +++ b/packages/webpack-cli/lib/utils/prompt-installation.js @@ -23,7 +23,6 @@ async function promptInstallation(packageName, preMessage) { packageManager === "yarn" ? "add" : "install", "-D", packageName, - "--ignore-workspace-root-check", ].join(" ")}`; const { colors } = utils; From 29fe963aebf3f66ea3aab9b80d9f3fc9abad1657 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 24 Aug 2021 16:18:51 +0300 Subject: [PATCH 6/8] test: fix smoke test --- smoketests/missing-packages/webpack-dev-server.test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/smoketests/missing-packages/webpack-dev-server.test.js b/smoketests/missing-packages/webpack-dev-server.test.js index c463ff985c0..7a95153889c 100644 --- a/smoketests/missing-packages/webpack-dev-server.test.js +++ b/smoketests/missing-packages/webpack-dev-server.test.js @@ -5,7 +5,7 @@ const { runTest, runTestStdout } = require("../helpers"); const webpackDevServerTest = () => { const packageName = "webpack-dev-server"; const args = ["serve"]; - const logMessage = "For using 'serve' command you need to install: 'webpack-dev-server' package"; + const logMessage = "For using 'serve' command you need to install: 'webpack-dev-server' package."; return runTest(packageName, args, logMessage); }; @@ -13,7 +13,8 @@ const webpackDevServerTest = () => { const webpackDevServerWithHelpTest = () => { const packageName = "webpack-dev-server"; const cliArgs = ["help", "serve"]; - const logMessage = "To see all available options you need to install 'webpack-dev-server'"; + const logMessage = + "To see all available options you need to install 'webpack', 'webpack-dev-server'."; return runTestStdout({ packageName, cliArgs, logMessage }); }; From 9e0681ca7d579ebbc81c8b0ee44bb3af8dd4936c Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Tue, 24 Aug 2021 17:21:26 +0300 Subject: [PATCH 7/8] fix: code --- packages/webpack-cli/lib/webpack-cli.js | 23 +++++++++++++++---- .../custom-webpack/custom-webpack.test.js | 16 ++++++------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/packages/webpack-cli/lib/webpack-cli.js b/packages/webpack-cli/lib/webpack-cli.js index c2efa26ae0f..c3d9052e7fa 100644 --- a/packages/webpack-cli/lib/webpack-cli.js +++ b/packages/webpack-cli/lib/webpack-cli.js @@ -7,6 +7,7 @@ const { program, Option } = require("commander"); const utils = require("./utils"); const WEBPACK_PACKAGE = process.env.WEBPACK_PACKAGE || "webpack"; +const WEBPACK_DEV_SERVER_PACKAGE = process.env.WEBPACK_DEV_SERVER_PACKAGE || "webpack-dev-server"; class WebpackCLI { constructor() { @@ -147,13 +148,27 @@ class WebpackCLI { continue; } - const { promptInstallation, colors } = this.utils; + let skipInstallation = false; + + // Allow to use `./path/to/webpack.js` outside `node_modules` + if (dependency === WEBPACK_PACKAGE && fs.existsSync(WEBPACK_PACKAGE)) { + skipInstallation = true; + } + + // Allow to use `./path/to/webpack-dev-server.js` outside `node_modules` + if (dependency === WEBPACK_DEV_SERVER_PACKAGE && fs.existsSync(WEBPACK_PACKAGE)) { + skipInstallation = true; + } + + if (skipInstallation) { + continue; + } - await promptInstallation(dependency, () => { + await this.utils.promptInstallation(dependency, () => { this.logger.error( - `For using '${colors.green( + `For using '${this.utils.colors.green( commandOptions.name.split(" ")[0], - )}' command you need to install: '${colors.green(dependency)}' package.`, + )}' command you need to install: '${this.utils.colors.green(dependency)}' package.`, ); }); } diff --git a/test/build/custom-webpack/custom-webpack.test.js b/test/build/custom-webpack/custom-webpack.test.js index 34aed49d46c..35a2d7002b3 100644 --- a/test/build/custom-webpack/custom-webpack.test.js +++ b/test/build/custom-webpack/custom-webpack.test.js @@ -4,9 +4,9 @@ const { resolve } = require("path"); const { run } = require("../../utils/test-utils"); describe("custom-webpack", () => { - it("should use custom-webpack.js", async () => { + it("should use package from 'node_modules'", async () => { const { exitCode, stderr, stdout } = await run(__dirname, [], { - env: { WEBPACK_PACKAGE: resolve(__dirname, "./custom-webpack.js") }, + env: { WEBPACK_PACKAGE: "webpack" }, }); expect(exitCode).toBe(0); @@ -14,15 +14,13 @@ describe("custom-webpack", () => { expect(stdout).toContain("main.js"); }); - it("should throw an error for invalid-webpack.js", async () => { + it("should use custom-webpack.js", async () => { const { exitCode, stderr, stdout } = await run(__dirname, [], { - env: { - WEBPACK_PACKAGE: resolve(__dirname, "./invalid-webpack.js"), - }, + env: { WEBPACK_PACKAGE: resolve(__dirname, "./custom-webpack.js") }, }); - expect(exitCode).toBe(2); - expect(stderr).toContain(`Error: Cannot find module`); - expect(stdout).toBeFalsy(); + expect(exitCode).toBe(0); + expect(stderr).toBeFalsy(); + expect(stdout).toContain("main.js"); }); }); From 5d7c08534e49d69836e933d195cca43d1e101196 Mon Sep 17 00:00:00 2001 From: evilebottnawi Date: Wed, 25 Aug 2021 13:45:31 +0300 Subject: [PATCH 8/8] fix: compatibility with webpack v4 --- packages/configtest/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/configtest/src/index.ts b/packages/configtest/src/index.ts index 10179693534..f71eec6db98 100644 --- a/packages/configtest/src/index.ts +++ b/packages/configtest/src/index.ts @@ -46,7 +46,7 @@ class ConfigTestCommand { throw new cli.webpack.WebpackOptionsValidationError(error); } } catch (error) { - if (error instanceof cli.webpack.ValidationError || error.name === "ValidationError") { + if (cli.isValidationError(error)) { cli.logger.error(error.message); } else { cli.logger.error(error);