From 03df8572f81aad055c0c0ba3f136e35a5431fdeb Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Sat, 23 Mar 2019 20:49:17 +0530 Subject: [PATCH 01/50] chore(cli): move constants to a separate file (#798) * chore(cli): move constants to a separate file moved all constants to a separate file for CLI scopre and imported from there. ISSUES CLOSED: #772 * chore(cli): lint files, rm console.log Format all code using prettier, remove console.log ISSUES CLOSED: #772 * chore(cli): codacy fix codacy fix * chore(cli): split destructuring into multiple lines split constants destructuring to multiple lines in config-yargs * chore(cli): update var name, revert oc update var name, revert oc * chore(cli): moved constants to utils moved constants to utils directory --- bin/cli.js | 16 +++------------- bin/config/config-yargs.js | 22 +++++++++++++--------- bin/utils/constants.js | 37 +++++++++++++++++++++++++++++++++++++ bin/utils/errorHelpers.js | 4 ++-- 4 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 bin/utils/constants.js diff --git a/bin/cli.js b/bin/cli.js index 9a34f7e6f7f..aa7df4c2d9c 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -5,6 +5,8 @@ Author Tobias Koppers @sokra */ +const { NON_COMPILATION_ARGS } = require("./utils/constants"); + (function() { // wrap in IIFE to be able to use return @@ -18,17 +20,6 @@ const ErrorHelpers = require("./utils/errorHelpers"); - const NON_COMPILATION_ARGS = [ - "init", - "migrate", - "add", - "remove", - "serve", - "generate-loader", - "generate-plugin", - "info" - ]; - const NON_COMPILATION_CMD = process.argv.find(arg => { if (arg === "serve") { global.process.argv = global.process.argv.filter(a => a !== "serve"); @@ -52,7 +43,6 @@ For more information, see https://webpack.js.org/api/cli/.`); require("./config/config-yargs")(yargs); - // yargs will terminate the process early when the user uses help or version. // This causes large help outputs to be cut short (https://github.com/nodejs/node/wiki/API-changes-between-v0.10-and-v4#process). // To prevent this we use the yargs.parse API and exit the process normally @@ -104,7 +94,7 @@ For more information, see https://webpack.js.org/api/cli/.`); const stdout = argv.silent ? { write: () => {} - } // eslint-disable-line + } // eslint-disable-line : process.stdout; function ifArg(name, fn, init) { diff --git a/bin/config/config-yargs.js b/bin/config/config-yargs.js index 19a3c489e68..105358875a7 100644 --- a/bin/config/config-yargs.js +++ b/bin/config/config-yargs.js @@ -1,5 +1,18 @@ const optionsSchema = require("../config/optionsSchema.json"); +const { GROUPS } = require("../utils/constants"); + +const { + CONFIG_GROUP, + BASIC_GROUP, + MODULE_GROUP, + OUTPUT_GROUP, + ADVANCED_GROUP, + RESOLVE_GROUP, + OPTIMIZE_GROUP, + DISPLAY_GROUP +} = GROUPS; + const nestedProperties = ["anyOf", "oneOf", "allOf"]; const resolveSchema = schema => { @@ -52,15 +65,6 @@ const getSchemaInfo = (path, property, subProperty) => { return findPropertyInSchema(current, property, subProperty); }; -const CONFIG_GROUP = "Config options:"; -const BASIC_GROUP = "Basic options:"; -const MODULE_GROUP = "Module options:"; -const OUTPUT_GROUP = "Output options:"; -const ADVANCED_GROUP = "Advanced options:"; -const RESOLVE_GROUP = "Resolving options:"; -const OPTIMIZE_GROUP = "Optimizing options:"; -const DISPLAY_GROUP = "Stats options:"; - module.exports = function(yargs) { yargs .help("help") diff --git a/bin/utils/constants.js b/bin/utils/constants.js new file mode 100644 index 00000000000..28a36c88a74 --- /dev/null +++ b/bin/utils/constants.js @@ -0,0 +1,37 @@ +const NON_COMPILATION_ARGS = [ + "init", + "migrate", + "add", + "remove", + "serve", + "generate-loader", + "generate-plugin", + "info" +]; + +const CONFIG_GROUP = "Config options:"; +const BASIC_GROUP = "Basic options:"; +const MODULE_GROUP = "Module options:"; +const OUTPUT_GROUP = "Output options:"; +const ADVANCED_GROUP = "Advanced options:"; +const RESOLVE_GROUP = "Resolving options:"; +const OPTIMIZE_GROUP = "Optimizing options:"; +const DISPLAY_GROUP = "Stats options:"; +const GROUPS = { + CONFIG_GROUP, + BASIC_GROUP, + MODULE_GROUP, + OUTPUT_GROUP, + ADVANCED_GROUP, + RESOLVE_GROUP, + OPTIMIZE_GROUP, + DISPLAY_GROUP +}; + +const WEBPACK_OPTIONS_FLAG = "WEBPACK_OPTIONS"; + +module.exports = { + NON_COMPILATION_ARGS, + GROUPS, + WEBPACK_OPTIONS_FLAG +}; diff --git a/bin/utils/errorHelpers.js b/bin/utils/errorHelpers.js index 5098f4ca14d..96fe950f34d 100644 --- a/bin/utils/errorHelpers.js +++ b/bin/utils/errorHelpers.js @@ -4,7 +4,7 @@ */ "use strict"; -const webpackOptionsFlag = "WEBPACK_OPTIONS"; +const { WEBPACK_OPTIONS_FLAG } = require("./constants"); exports.cutOffByFlag = (stack, flag) => { stack = stack.split("\n"); @@ -12,7 +12,7 @@ exports.cutOffByFlag = (stack, flag) => { return stack.join("\n"); }; -exports.cutOffWebpackOptions = stack => exports.cutOffByFlag(stack, webpackOptionsFlag); +exports.cutOffWebpackOptions = stack => exports.cutOffByFlag(stack, WEBPACK_OPTIONS_FLAG); exports.cutOffMultilineMessage = (stack, message) => { stack = stack.split("\n"); From fe9c289cd54ac2f26d7c9690abc3d572e40feedf Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Wed, 27 Mar 2019 18:59:20 +0530 Subject: [PATCH 02/50] chore(cli): remove findup-sync from package dir and move to utils remove findup-sync from package dir and move to utils cli(utils): added path-util to be used after next release added path-util to be used after next release ISSUES CLOSED: #805 --- bin/utils/convert-argv.js | 2 + .../utils/__tests__/is-local-path.test.ts | 2 +- packages/utils/find-root.ts | 14 ------ packages/utils/is-local-path.ts | 17 -------- packages/utils/npm-packages-exists.ts | 2 +- packages/utils/path-utils.ts | 43 +++++++++++++++++++ packages/utils/resolve-packages.ts | 2 +- packages/utils/scaffold.ts | 2 +- 8 files changed, 49 insertions(+), 35 deletions(-) delete mode 100644 packages/utils/find-root.ts delete mode 100644 packages/utils/is-local-path.ts create mode 100644 packages/utils/path-utils.ts diff --git a/bin/utils/convert-argv.js b/bin/utils/convert-argv.js index d1c8d8d2f43..7f45aff70f3 100644 --- a/bin/utils/convert-argv.js +++ b/bin/utils/convert-argv.js @@ -7,6 +7,7 @@ const webpackConfigurationSchema = require("../config/webpackConfigurationSchema const validateSchema = require("webpack").validateSchema; const WebpackOptionsValidationError = require("webpack").WebpackOptionsValidationError; const findup = require("findup-sync"); +// const { webpackConfigPath } = require("@webpack-cli/utils/path-utils"); module.exports = function(...args) { const argv = args[1] || args[0]; @@ -72,6 +73,7 @@ module.exports = function(...args) { const defaultConfigFileNames = ["webpack.config", "webpackfile"].join("|"); const webpackConfigFileRegExp = `(${defaultConfigFileNames})(${extensions.join("|")})`; const pathToWebpackConfig = findup(webpackConfigFileRegExp); + // const pathToWebpackConfig = webpackConfigPath(extensions); if (pathToWebpackConfig) { const resolvedPath = path.resolve(pathToWebpackConfig); diff --git a/packages/utils/__tests__/is-local-path.test.ts b/packages/utils/__tests__/is-local-path.test.ts index ca34c0e7b66..654884b9e1a 100644 --- a/packages/utils/__tests__/is-local-path.test.ts +++ b/packages/utils/__tests__/is-local-path.test.ts @@ -1,7 +1,7 @@ "use strict"; import * as path from "path"; -import isLocalPath from "../is-local-path"; +import { isLocalPath } from "../path-utils"; describe("is-local-path", () => { it("returns true for paths beginning in the current directory", () => { diff --git a/packages/utils/find-root.ts b/packages/utils/find-root.ts deleted file mode 100644 index 0345da2db62..00000000000 --- a/packages/utils/find-root.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as findup from "findup-sync"; -import * as path from "path"; - -/** - * Returns the absolute path of the project directory - * Finds the package.json, by using findup-sync - * @returns {String} path of project directory - */ - -export function findProjectRoot(): string { - const rootFilePath = findup(`package.json`); - const projectRoot = path.dirname(rootFilePath); - return projectRoot; -} diff --git a/packages/utils/is-local-path.ts b/packages/utils/is-local-path.ts deleted file mode 100644 index 0efb8c6fc2c..00000000000 --- a/packages/utils/is-local-path.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; - -/** - * Attempts to detect whether the string is a local path regardless of its - * existence by checking its format. The point is to distinguish between - * paths and modules on the npm registry. This will fail for non-existent - * local Windows paths that begin with a drive letter, e.g. C:..\generator.js, - * but will succeed for any existing files and any absolute paths. - * - * @param {String} str - string to check - * @returns {Boolean} whether the string could be a path to a local file or directory - */ - -export default function(str: string): boolean { - return path.isAbsolute(str) || /^\./.test(str) || fs.existsSync(str); -} diff --git a/packages/utils/npm-packages-exists.ts b/packages/utils/npm-packages-exists.ts index a1987c3332d..2ad1d797510 100644 --- a/packages/utils/npm-packages-exists.ts +++ b/packages/utils/npm-packages-exists.ts @@ -1,7 +1,7 @@ import chalk from "chalk"; -import isLocalPath from "./is-local-path"; import npmExists from "./npm-exists"; +import { isLocalPath } from "./path-utils"; import { resolvePackages } from "./resolve-packages"; const WEBPACK_SCAFFOLD_PREFIX = "webpack-scaffold"; diff --git a/packages/utils/path-utils.ts b/packages/utils/path-utils.ts new file mode 100644 index 00000000000..468572a59b9 --- /dev/null +++ b/packages/utils/path-utils.ts @@ -0,0 +1,43 @@ +import * as findup from "findup-sync"; +import * as fs from "fs"; +import * as path from "path"; + +/** + * Attempts to detect whether the string is a local path regardless of its + * existence by checking its format. The point is to distinguish between + * paths and modules on the npm registry. This will fail for non-existent + * local Windows paths that begin with a drive letter, e.g. C:..\generator.js, + * but will succeed for any existing files and any absolute paths. + * + * @param {String} str - string to check + * @returns {Boolean} whether the string could be a path to a local file or directory + */ + +export function isLocalPath(str: string): boolean { + return path.isAbsolute(str) || /^\./.test(str) || fs.existsSync(str); +} + +/** + * Get absolute path of a webpack config in a project. + * + * @param {String[]} str - array of extensions to look for. + * @returns {String} Absolute path of the config. + */ + +export function webpackConfigPath(extensions: string[]): string { + const defaultConfigFileNames = ["webpack.config", "webpackfile"].join("|"); + const webpackConfigFileRegExp = `(${defaultConfigFileNames})(${extensions.join("|")})`; + return findup(webpackConfigFileRegExp); +} + +/** + * Find the root directory path of a project. + * + * @returns {String} Absolute path of the project root. + */ + +export function findProjectRoot(): string { + const rootFilePath = findup(`package.json`); + const projectRoot = path.dirname(rootFilePath); + return projectRoot; +} diff --git a/packages/utils/resolve-packages.ts b/packages/utils/resolve-packages.ts index b16823509a9..9cfbc21fa32 100644 --- a/packages/utils/resolve-packages.ts +++ b/packages/utils/resolve-packages.ts @@ -1,10 +1,10 @@ import chalk from "chalk"; import * as path from "path"; -import isLocalPath from "./is-local-path"; import modifyConfigHelper from "./modify-config-helper"; import { getPathToGlobalPackages } from "./package-manager"; import { spawnChild } from "./package-manager"; +import { isLocalPath } from "./path-utils"; interface IChildProcess { status: number; diff --git a/packages/utils/scaffold.ts b/packages/utils/scaffold.ts index a3add9ee769..637fdc5b83f 100644 --- a/packages/utils/scaffold.ts +++ b/packages/utils/scaffold.ts @@ -2,7 +2,7 @@ import chalk from "chalk"; import * as j from "jscodeshift"; import pEachSeries = require("p-each-series"); import * as path from "path"; -import { findProjectRoot } from "./find-root"; +import { findProjectRoot } from "./path-utils"; import { IError } from "../init/types"; import { IConfig, ITransformConfig } from "./modify-config-helper"; From ed4095f5098599903b3bd3a64e2ffee94816a1e5 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Sat, 20 Apr 2019 23:36:21 +0530 Subject: [PATCH 03/50] chore(cli): cleanup cleanup --- bin/utils/convert-argv.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/bin/utils/convert-argv.js b/bin/utils/convert-argv.js index 7f45aff70f3..d1c8d8d2f43 100644 --- a/bin/utils/convert-argv.js +++ b/bin/utils/convert-argv.js @@ -7,7 +7,6 @@ const webpackConfigurationSchema = require("../config/webpackConfigurationSchema const validateSchema = require("webpack").validateSchema; const WebpackOptionsValidationError = require("webpack").WebpackOptionsValidationError; const findup = require("findup-sync"); -// const { webpackConfigPath } = require("@webpack-cli/utils/path-utils"); module.exports = function(...args) { const argv = args[1] || args[0]; @@ -73,7 +72,6 @@ module.exports = function(...args) { const defaultConfigFileNames = ["webpack.config", "webpackfile"].join("|"); const webpackConfigFileRegExp = `(${defaultConfigFileNames})(${extensions.join("|")})`; const pathToWebpackConfig = findup(webpackConfigFileRegExp); - // const pathToWebpackConfig = webpackConfigPath(extensions); if (pathToWebpackConfig) { const resolvedPath = path.resolve(pathToWebpackConfig); From 00a63482bd5cebfb7d0c7e32ab8e4b5fa05677d0 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Tue, 23 Apr 2019 10:38:31 +0530 Subject: [PATCH 04/50] chore(utils): use absolute path use absolute path --- packages/utils/__tests__/is-local-path.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/utils/__tests__/is-local-path.test.ts b/packages/utils/__tests__/is-local-path.test.ts index 654884b9e1a..e8016a91a3d 100644 --- a/packages/utils/__tests__/is-local-path.test.ts +++ b/packages/utils/__tests__/is-local-path.test.ts @@ -1,7 +1,7 @@ "use strict"; +import { isLocalPath } from "@webpack-cli/utils/path-utils"; import * as path from "path"; -import { isLocalPath } from "../path-utils"; describe("is-local-path", () => { it("returns true for paths beginning in the current directory", () => { From 5a0952e1386caeee7fb42c1e60b53c6d9ed16945 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Tue, 23 Apr 2019 11:48:46 +0530 Subject: [PATCH 05/50] chore(util): use relative for now use relative path for now --- packages/utils/__tests__/is-local-path.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/utils/__tests__/is-local-path.test.ts b/packages/utils/__tests__/is-local-path.test.ts index e8016a91a3d..654884b9e1a 100644 --- a/packages/utils/__tests__/is-local-path.test.ts +++ b/packages/utils/__tests__/is-local-path.test.ts @@ -1,7 +1,7 @@ "use strict"; -import { isLocalPath } from "@webpack-cli/utils/path-utils"; import * as path from "path"; +import { isLocalPath } from "../path-utils"; describe("is-local-path", () => { it("returns true for paths beginning in the current directory", () => { From 7fbc3a4b57c81bd7bff2c09c13adca56d7ec081a Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Fri, 24 May 2019 11:23:43 +0530 Subject: [PATCH 06/50] chore(add-generator): changed the naming of the plugin in config file Changed the naming of the plugin to better and standard and bug free name in add-generator in plugin question --- packages/generators/add-generator.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/generators/add-generator.ts b/packages/generators/add-generator.ts index bef3c32afd3..a911b75e6ce 100644 --- a/packages/generators/add-generator.ts +++ b/packages/generators/add-generator.ts @@ -395,15 +395,11 @@ export default class AddGenerator extends Generator { (p: boolean): void => { if (p) { this.dependencies.push(answerToAction.actionAnswer); - const normalizePluginName = answerToAction.actionAnswer.replace( - "-webpack-plugin", - "Plugin" - ); - const pluginName = replaceAt( - normalizePluginName, - 0, - normalizePluginName.charAt(0).toUpperCase() - ); + let myPluginNameArray = answerToAction.actionAnswer.split("-") + for (let i = 0; i < myPluginNameArray.length; i++) { + myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); + } + const pluginName = myPluginNameArray.join("") this.configuration.config.topScope.push( `const ${pluginName} = require("${answerToAction.actionAnswer}")` ); From 7d83453434171800d63b925f9470b68cc84ce0db Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Mon, 27 May 2019 22:45:40 +0530 Subject: [PATCH 07/50] chore: added a generatePluginName method in generators utils Added generatePluginName in generators/utils/plugins.ts and also moved the replaceAt method from add-generator.ts to generators/utils/plugins.ts. Added tests for the plugin name method --- .../__tests__/add-generator.test.ts | 14 +++++++ packages/generators/add-generator.ts | 23 +---------- packages/generators/utils/plugins.ts | 41 ++++++++++++++++++- 3 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 packages/generators/__tests__/add-generator.test.ts diff --git a/packages/generators/__tests__/add-generator.test.ts b/packages/generators/__tests__/add-generator.test.ts new file mode 100644 index 00000000000..d8a657f527d --- /dev/null +++ b/packages/generators/__tests__/add-generator.test.ts @@ -0,0 +1,14 @@ +import { generatePluginName } from "../utils/plugins" + +describe("generatePluginName", () => { + it("should return webpack Standard Plugin Name for Name : extract-text-webpack-plugin", () => { + const pluginName = generatePluginName("extract-text-webpack-plugin"); + expect(pluginName).toEqual("ExtractTextWebpackPlugin"); + }); + + it("should return webpack Standard Plugin Name for Name : webpack.DefinePlugin", () => { + const pluginName = generatePluginName("webpack.DefinePlugin"); + expect(pluginName).toEqual("Webpack.DefinePlugin"); + }); +}); + diff --git a/packages/generators/add-generator.ts b/packages/generators/add-generator.ts index a911b75e6ce..03d8619c895 100644 --- a/packages/generators/add-generator.ts +++ b/packages/generators/add-generator.ts @@ -11,26 +11,11 @@ import { AutoComplete, Confirm, Input, List } from "@webpack-cli/webpack-scaffol import { SchemaProperties, WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; - +import { generatePluginName } from "./utils/plugins"; import webpackDevServerSchema from "webpack-dev-server/lib/options.json"; import webpackSchema from "./utils/optionsSchema.json"; const PROPS: string[] = Array.from(PROP_TYPES.keys()); -/** - * - * Replaces the string with a substring at the given index - * https://gist.github.com/efenacigiray/9367920 - * - * @param {String} str - string to be modified - * @param {Number} index - index to replace from - * @param {String} replace - string to replace starting from index - * - * @returns {String} string - The newly mutated string - * - */ -function replaceAt(str: string, index: number, replace: string): string { - return str.substring(0, index) + replace + str.substring(index + 1); -} /** * @@ -395,11 +380,7 @@ export default class AddGenerator extends Generator { (p: boolean): void => { if (p) { this.dependencies.push(answerToAction.actionAnswer); - let myPluginNameArray = answerToAction.actionAnswer.split("-") - for (let i = 0; i < myPluginNameArray.length; i++) { - myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); - } - const pluginName = myPluginNameArray.join("") + const pluginName = generatePluginName(answerToAction.actionAnswer) this.configuration.config.topScope.push( `const ${pluginName} = require("${answerToAction.actionAnswer}")` ); diff --git a/packages/generators/utils/plugins.ts b/packages/generators/utils/plugins.ts index 6dedb1fab9e..3982df796f2 100644 --- a/packages/generators/utils/plugins.ts +++ b/packages/generators/utils/plugins.ts @@ -1,3 +1,4 @@ + /** * * Callable function with the initial plugins @@ -6,6 +7,44 @@ * that consists of terser-webpack-plugin */ -export default function(): string[] { +export default function (): string[] { return ["new TerserPlugin()"]; } + +/** + * + * Replaces the string with a substring at the given index + * https://gist.github.com/efenacigiray/9367920 + * + * @param {String} str - string to be modified + * @param {Number} index - index to replace from + * @param {String} replace - string to replace starting from index + * + * @returns {String} string - The newly mutated string + * + */ + +export const replaceAt = (str: string, index: number, replace: string) : string => { + return str.substring(0, index) + replace + str.substring(index + 1); +} + + +/** + * + * Generate a webpack standard webpack plugin name from the plugin name from the Answer + * + * @param {String} rawPluginName - plugin name from answer + * + * @returns {String} string - the webpack standard plugin name + * + */ + + +export const generatePluginName = (rawPluginName: string): string => { + let myPluginNameArray : string[]; + myPluginNameArray = rawPluginName.split("-"); + for (let i = 0; i < myPluginNameArray.length; i++) { + myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); + } + return myPluginNameArray.join("") +} From fc9e2592d9e99692c6073ac028512ce58a9bf9a2 Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Mon, 27 May 2019 23:11:04 +0530 Subject: [PATCH 08/50] chore(plugins.ts): added if-stmt for native plugins Added if stmt for not doing anything when native plugins comes-in Also Changed the test --- packages/generators/__tests__/add-generator.test.ts | 2 +- packages/generators/utils/plugins.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/generators/__tests__/add-generator.test.ts b/packages/generators/__tests__/add-generator.test.ts index d8a657f527d..7906123cb4e 100644 --- a/packages/generators/__tests__/add-generator.test.ts +++ b/packages/generators/__tests__/add-generator.test.ts @@ -8,7 +8,7 @@ describe("generatePluginName", () => { it("should return webpack Standard Plugin Name for Name : webpack.DefinePlugin", () => { const pluginName = generatePluginName("webpack.DefinePlugin"); - expect(pluginName).toEqual("Webpack.DefinePlugin"); + expect(pluginName).toEqual("webpack.DefinePlugin"); }); }); diff --git a/packages/generators/utils/plugins.ts b/packages/generators/utils/plugins.ts index 3982df796f2..f2c571e7cda 100644 --- a/packages/generators/utils/plugins.ts +++ b/packages/generators/utils/plugins.ts @@ -43,8 +43,11 @@ export const replaceAt = (str: string, index: number, replace: string) : string export const generatePluginName = (rawPluginName: string): string => { let myPluginNameArray : string[]; myPluginNameArray = rawPluginName.split("-"); - for (let i = 0; i < myPluginNameArray.length; i++) { - myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); + if( myPluginNameArray.length <= 1 ){} + else{ + for (let i = 0; i < myPluginNameArray.length; i++) { + myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); + } } return myPluginNameArray.join("") } From e583aabd51442f427a3f92816153b01ac43288af Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Tue, 28 May 2019 11:52:04 +0530 Subject: [PATCH 09/50] chore(style): fixed the indentation fix the indentation --- packages/generators/utils/plugins.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/generators/utils/plugins.ts b/packages/generators/utils/plugins.ts index f2c571e7cda..ab3d3698a45 100644 --- a/packages/generators/utils/plugins.ts +++ b/packages/generators/utils/plugins.ts @@ -43,7 +43,7 @@ export const replaceAt = (str: string, index: number, replace: string) : string export const generatePluginName = (rawPluginName: string): string => { let myPluginNameArray : string[]; myPluginNameArray = rawPluginName.split("-"); - if( myPluginNameArray.length <= 1 ){} + if(myPluginNameArray.length <= 1){} else{ for (let i = 0; i < myPluginNameArray.length; i++) { myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); From 5e33f8a76bc9662df5ee2311b4a2155e48058ccf Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Mon, 27 May 2019 03:28:23 +0200 Subject: [PATCH 10/50] chore: add sec & versioning policy --- SECURITY.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..ef1676b50d2 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,21 @@ +# Security Policy + +This document explains the security policy of webpack-cli and how we intend to support webpack and webpack-cli. + +## Supported Versions + +webpack CLI is currently supporting webpack v4 and webpack v5. Security fixes are released in patches. + +| webpack version | webpack-cli version | Supported | +| --------------- | ----------------------------- | ------------------ | +| 4.x.0 | ^3.1.2 | :white_check_mark: | +| 4.0.x | ^3.1.2 | :white_check_mark: | +| 5.x.0 | ^3.1.2 | :white_check_mark: | +| 5.0.x | ^3.1.2 | :white_check_mark: | +| < 4.x.x | (CLI included in webpack < 4) | :x: | + +**Note: Using webpack < 4 with webpack CLI is not required as CLI was [included](https://github.com/webpack/webpack/commit/4b0332d3909eea8115d84f9a03da2d52478daa70#diff-b9cfc7f2cdf78a7f4b91a753d10865a2) in webpack.** + +## Reporting a Vulnerability + +To report a vulnerability, please contact one of webpack maintainers through the email provided from either npm, GitHub or reach out at other social media platforms. For third party security vulnerabilities, submitting an issue or Pull Request to fix the security vulerability is much appreciated. From 818e43e54a7e7288d39a1d5811213054417ab926 Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Tue, 28 May 2019 14:37:41 +0530 Subject: [PATCH 11/50] chore: loop change changed the loop --- packages/generators/utils/plugins.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/generators/utils/plugins.ts b/packages/generators/utils/plugins.ts index ab3d3698a45..560eaa35b50 100644 --- a/packages/generators/utils/plugins.ts +++ b/packages/generators/utils/plugins.ts @@ -43,11 +43,8 @@ export const replaceAt = (str: string, index: number, replace: string) : string export const generatePluginName = (rawPluginName: string): string => { let myPluginNameArray : string[]; myPluginNameArray = rawPluginName.split("-"); - if(myPluginNameArray.length <= 1){} - else{ - for (let i = 0; i < myPluginNameArray.length; i++) { - myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); - } + for (let i = 0; i < myPluginNameArray.length && myPluginNameArray.length > 1 ; i++) { + myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); } return myPluginNameArray.join("") } From 99304c41e7d1f30f0f44cc5eb4c646c47deb19bb Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 19 Apr 2019 15:09:21 +0200 Subject: [PATCH 12/50] chore(utils): fix deprecated babylon --- packages/utils/package-lock.json | 6 +++--- packages/utils/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/utils/package-lock.json b/packages/utils/package-lock.json index 30e688d29c6..313aec15a47 100644 --- a/packages/utils/package-lock.json +++ b/packages/utils/package-lock.json @@ -121,9 +121,9 @@ "dev": true }, "@types/prettier": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.15.2.tgz", - "integrity": "sha512-XIB0ZCaFZmWUHAa9dBqP5UKXXHwuukmVlP+XcyU94dui2k+l2lG+CHAbt2ffenHPUqoIs5Beh8Pdf2YEq/CZ7A==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.16.1.tgz", + "integrity": "sha512-db6pZL5QY3JrlCHBhYQzYDci0xnoDuxfseUuguLRr3JNk+bnCfpkK6p8quiUDyO8A0vbpBKkk59Fw125etrNeA==", "dev": true }, "@types/through": { diff --git a/packages/utils/package.json b/packages/utils/package.json index 3a243bbb1ad..fc26be79aa3 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -31,7 +31,7 @@ "@types/log-symbols": "^2.0.0", "@types/node": "^10.12.9", "@types/p-each-series": "^1.0.0", - "@types/prettier": "^1.15.0", + "@types/prettier": "^1.16.1", "@types/yeoman-generator": "^3.1.2", "typescript": "^3.1.6" }, From 0a648f7d461a659c81971f0af6428a63614e0aa6 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 19 Apr 2019 15:11:11 +0200 Subject: [PATCH 13/50] feat(webpack-scaffold): adds Input defaults, doc & tests --- packages/webpack-scaffold/README.md | 51 ++++++++++--------- .../__snapshots__/index.test.ts.snap | 11 ++++ .../webpack-scaffold/__tests__/index.test.ts | 14 +++++ packages/webpack-scaffold/index.ts | 12 ++++- 4 files changed, 63 insertions(+), 25 deletions(-) diff --git a/packages/webpack-scaffold/README.md b/packages/webpack-scaffold/README.md index a0a92441b40..33282ca8cf9 100755 --- a/packages/webpack-scaffold/README.md +++ b/packages/webpack-scaffold/README.md @@ -11,15 +11,20 @@ npm i -D webpack-cli @webpack-cli/webpack-scaffold ``` # API - -- [parseValue](#parsevalue) -- [createArrowFunction](#createarrowfunction) -- [createRegularFunction](#createregularfunction) -- [createDynamicPromise](#createdynamicpromise) -- [createAssetFilterFunction](#createassetfilterfunction) -- [createExternalFunction](#createexternalfunction) -- [createRequire](#createrequire) -- [Inquirer](#inquirer) - [List](#list) - [RawList](#rawlist) - [CheckList](#checklist) - [Input](#input) - [InputValidate](#inputvalidate) - [Confirm](#confirm) +- [parseValue](#parsevalue) +- [createArrowFunction](#createarrowfunction) +- [createRegularFunction](#createregularfunction) +- [createDynamicPromise](#createdynamicpromise) +- [createAssetFilterFunction](#createassetfilterfunction) +- [createExternalFunction](#createexternalfunction) +- [createRequire](#createrequire) +- [Inquirer](#inquirer) + - [List](#list) + - [RawList](#rawlist) + - [CheckList](#checklist) + - [Input](#input) + - [InputValidate](#inputvalidate) + - [Confirm](#confirm) ## parseValue @@ -163,38 +168,38 @@ CheckList("entry", "what kind of entry do you want?", ["Array", "Function"]); ### Input -Param: `name, message` +Param: `name, message, [default]` Creates an Input from Inquirer ```js const Input = require("@webpack-cli/webpack-scaffold").Input; -Input("entry", "what is your entry point?"); +Input('entry', 'what is your entry point?', 'src/index') ``` ### InputValidate -Param: `name, message, validate` +Param: `name, message, [validate, default]` Creates an Input from Inquirer ```js -const InputValidate = require("@webpack-cli/webpack-scaffold").InputValidate; - -const validation = value => { - if (value.length > 4) { - return true; - } else { - return "Wow, that was short!"; - } -}; -InputValidate("entry", "what is your entry point?", validation); +const InputValidate = require('@webpack-cli/webpack-scaffold').InputValidate; + +const validation = (value) => { + if(value.length > 4) { + return true; + } else { + return 'Wow, that was short!' + } +} +InputValidate('entry', 'what is your entry point?', validation, 'src/index') ``` ### Confirm -Param: `name, message, default` +Param: `name, message, [default]` Creates an Input from Inquirer diff --git a/packages/webpack-scaffold/__tests__/__snapshots__/index.test.ts.snap b/packages/webpack-scaffold/__tests__/__snapshots__/index.test.ts.snap index 0304203ef64..0e06b120337 100755 --- a/packages/webpack-scaffold/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/webpack-scaffold/__tests__/__snapshots__/index.test.ts.snap @@ -2,6 +2,17 @@ exports[`utils Inquirer should make an Input object with validation 1`] = ` Object { + "default": undefined, + "message": "what is your plugin?", + "name": "plugins", + "type": "input", + "validate": [Function], +} +`; + +exports[`utils Inquirer should make an Input object with validation and default value 1`] = ` +Object { + "default": "my-plugin", "message": "what is your plugin?", "name": "plugins", "type": "input", diff --git a/packages/webpack-scaffold/__tests__/index.test.ts b/packages/webpack-scaffold/__tests__/index.test.ts index 0db475e179a..586bbcd9a58 100755 --- a/packages/webpack-scaffold/__tests__/index.test.ts +++ b/packages/webpack-scaffold/__tests__/index.test.ts @@ -76,6 +76,15 @@ describe("utils", () => { }); it("should make an Input object", () => { expect(utils.Input("plugins", "what is your plugin?")).toEqual({ + default: undefined, + message: "what is your plugin?", + name: "plugins", + type: "input", + }); + }); + it("should make an Input object", () => { + expect(utils.Input("plugins", "what is your plugin?", "my-plugin")).toEqual({ + default: "my-plugin", message: "what is your plugin?", name: "plugins", type: "input", @@ -102,5 +111,10 @@ describe("utils", () => { utils.InputValidate("plugins", "what is your plugin?", () => true), ).toMatchSnapshot(); }); + it("should make an Input object with validation and default value", () => { + expect( + utils.InputValidate("plugins", "what is your plugin?", () => true, "my-plugin"), + ).toMatchSnapshot(); + }); }); }); diff --git a/packages/webpack-scaffold/index.ts b/packages/webpack-scaffold/index.ts index 0a4ceb38d5c..6477030c331 100755 --- a/packages/webpack-scaffold/index.ts +++ b/packages/webpack-scaffold/index.ts @@ -76,16 +76,24 @@ export function CheckList(name: string, message: string, choices: string[]): Gen }; } -export function Input(name: string, message: string): Generator.Question { +export function Input(name: string, message: string, defaultChoice?: string): Generator.Question { return { + default: defaultChoice, message, name, type: "input" }; } -export function InputValidate(name: string, message: string, cb?: (input: string) => string | boolean): Generator.Question { +export function InputValidate( + name: string, + message: string, + cb?: (input: string) => string | boolean, + defaultChoice?: string, + ): Generator.Question { + return { + default: defaultChoice, message, name, type: "input", From 17e45119c77c75fe8e299c7f07647864559e83d3 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 19 Apr 2019 15:16:24 +0200 Subject: [PATCH 14/50] misc(generators): refactor utils --- packages/generators/utils/entry.ts | 77 ++++++++---- packages/generators/utils/plugins.ts | 11 -- packages/generators/utils/style.ts | 172 +++++++++++++++++++++++++++ packages/utils/run-prettier.ts | 2 +- packages/utils/scaffold.ts | 42 +++---- 5 files changed, 246 insertions(+), 58 deletions(-) delete mode 100644 packages/generators/utils/plugins.ts create mode 100644 packages/generators/utils/style.ts diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts index 47762928337..5f136e0b940 100644 --- a/packages/generators/utils/entry.ts +++ b/packages/generators/utils/entry.ts @@ -1,5 +1,5 @@ import * as Generator from "yeoman-generator"; -import { InputValidate } from "@webpack-cli/webpack-scaffold"; +import { Input, InputValidate } from "@webpack-cli/webpack-scaffold"; import validate from "./validate"; @@ -16,22 +16,18 @@ interface CustomGenerator extends Generator { * @returns {Object} An Object that holds the answers given by the user, later used to scaffold */ -export default function entry( - self: CustomGenerator, - answer: { - entryType: boolean; - } -): Promise { +export default function entry(self: CustomGenerator, multiEntries: boolean): Promise<{}> { let entryIdentifiers: string[]; - let result: Promise; - if (answer.entryType) { + let result: Promise<{}>; + if (multiEntries) { result = self .prompt([ InputValidate( "multipleEntries", - "Type the names you want for your modules (entry files), separated by comma [example: app,vendor]", - validate - ) + "Type the names you want for your modules (entry files) separated by comma", + validate, + "pageOne, pageTwo", + ), ]) .then( (multipleEntriesAnswer: { multipleEntries: string }): Promise => { @@ -91,27 +87,56 @@ export default function entry( !entryPropAnswer[val].includes("path") && !entryPropAnswer[val].includes("process") ) { - entryPropAnswer[val] = `\'${entryPropAnswer[val].replace(/"|'/g, "")}\'`; + n[val] = `\'./${n[val].replace(/"|'/g, "").concat(".js")}\'`; } - webpackEntryPoint[val] = entryPropAnswer[val]; - } - ); - return webpackEntryPoint; + webpackEntryPoint[val] = n[val]; + }); + } else { + n = {}; + } + return fn(trimmedProp); + }); + }, Promise.resolve()); + } + return forEachPromise(entryIdentifiers, (entryProp: string): Promise<{} | void> => + self.prompt([ + InputValidate( + `${entryProp}`, + `What is the location of "${entryProp}"?`, + validate, + `./src/${entryProp}`, + ), + ]), + ).then((entryPropAnswer: object): object => { + Object.keys(entryPropAnswer).forEach((val: string): void => { + if ( + entryPropAnswer[val].charAt(0) !== "(" && + entryPropAnswer[val].charAt(0) !== "[" && + !entryPropAnswer[val].includes("function") && + !entryPropAnswer[val].includes("path") && + !entryPropAnswer[val].includes("process") + ) { + entryPropAnswer[val] = `\'./${entryPropAnswer[val].replace(/"|'/g, "").concat(".js")}\'`; } ); } ); } else { result = self - .prompt([InputValidate("singularEntry", "Which will be your application entry point? (src/index)")]) - .then( - (singularEntryAnswer: { singularEntry: string }): string => { - let { singularEntry } = singularEntryAnswer; - singularEntry = `\'${singularEntry.replace(/"|'/g, "")}\'`; - if (singularEntry.length <= 0) { - self.usingDefaults = true; - } - return singularEntry; + .prompt([ + Input( + "singularEntry", + "Which will be your application entry point?", + "src/index", + ), + ]) + .then((singularEntryAnswer: { + singularEntry: string, + }): string => { + let { singularEntry } = singularEntryAnswer; + singularEntry = `\'./${singularEntry.replace(/"|'/g, "").concat(".js")}\'`; + if (singularEntry.length <= 0) { + self.usingDefaults = true; } ); } diff --git a/packages/generators/utils/plugins.ts b/packages/generators/utils/plugins.ts deleted file mode 100644 index 6dedb1fab9e..00000000000 --- a/packages/generators/utils/plugins.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * - * Callable function with the initial plugins - * - * @returns {Function} An function that returns an array - * that consists of terser-webpack-plugin - */ - -export default function(): string[] { - return ["new TerserPlugin()"]; -} diff --git a/packages/generators/utils/style.ts b/packages/generators/utils/style.ts new file mode 100644 index 00000000000..9d4d428ace8 --- /dev/null +++ b/packages/generators/utils/style.ts @@ -0,0 +1,172 @@ +import tooltip from "./tooltip"; + +export default function style(self, stylingType) { + const ExtractUseProps = []; + let regExpForStyles = null; + switch (stylingType) { + case "SASS": + self.dependencies.push( + "sass-loader", + "node-sass", + "style-loader", + "css-loader", + ); + regExpForStyles = `${new RegExp(/\.(scss|css)$/)}`; + if (self.isProd) { + ExtractUseProps.push( + { + loader: "'css-loader'", + options: { + sourceMap: true, + }, + }, + { + loader: "'sass-loader'", + options: { + sourceMap: true, + }, + }, + ); + } else { + ExtractUseProps.push( + { + loader: "'style-loader'", + }, + { + loader: "'css-loader'", + }, + { + loader: "'sass-loader'", + }, + ); + } + break; + case "LESS": + regExpForStyles = `${new RegExp(/\.(less|css)$/)}`; + self.dependencies.push( + "less-loader", + "less", + "style-loader", + "css-loader", + ); + if (self.isProd) { + ExtractUseProps.push( + { + loader: "'css-loader'", + options: { + sourceMap: true, + }, + }, + { + loader: "'less-loader'", + options: { + sourceMap: true, + }, + }, + ); + } else { + ExtractUseProps.push( + { + loader: "'css-loader'", + options: { + sourceMap: true, + }, + }, + { + loader: "'less-loader'", + options: { + sourceMap: true, + }, + }, + ); + } + break; + case "PostCSS": + self.configuration.config.topScope.push( + tooltip.postcss(), + "const autoprefixer = require('autoprefixer');", + "const precss = require('precss');", + "\n", + ); + self.dependencies.push( + "style-loader", + "css-loader", + "postcss-loader", + "precss", + "autoprefixer", + ); + regExpForStyles = `${new RegExp(/\.css$/)}`; + if (self.isProd) { + ExtractUseProps.push( + { + loader: "'css-loader'", + options: { + importLoaders: 1, + sourceMap: true, + }, + }, + { + loader: "'postcss-loader'", + options: { + plugins: `function () { + return [ + precss, + autoprefixer + ]; + }`, + }, + }, + ); + } else { + ExtractUseProps.push( + { + loader: "'style-loader'", + }, + { + loader: "'css-loader'", + options: { + importLoaders: 1, + sourceMap: true, + }, + }, + { + loader: "'postcss-loader'", + options: { + plugins: `function () { + return [ + precss, + autoprefixer + ]; + }`, + }, + }, + ); + } + break; + case "CSS": + self.dependencies.push("style-loader", "css-loader"); + regExpForStyles = `${new RegExp(/\.css$/)}`; + if (self.isProd) { + ExtractUseProps.push({ + loader: "'css-loader'", + options: { + sourceMap: true, + }, + }); + } else { + ExtractUseProps.push( + { + loader: "'style-loader'", + options: { + sourceMap: true, + }, + }, + { + loader: "'css-loader'", + }, + ); + } + break; + } + return { ExtractUseProps, regExpForStyles }; +} diff --git a/packages/utils/run-prettier.ts b/packages/utils/run-prettier.ts index 794f86923b8..254f94029d7 100644 --- a/packages/utils/run-prettier.ts +++ b/packages/utils/run-prettier.ts @@ -19,7 +19,7 @@ export default function runPrettier(outputPath: string, source: string, cb?: Fun try { prettySource = prettier.format(source, { filepath: outputPath, - parser: "babylon", + parser: "babel", singleQuote: true, tabWidth: 1, useTabs: true, diff --git a/packages/utils/scaffold.ts b/packages/utils/scaffold.ts index 2d2ece8a390..3fc8bf20c0f 100644 --- a/packages/utils/scaffold.ts +++ b/packages/utils/scaffold.ts @@ -81,26 +81,28 @@ export default function runTransform(transformConfig: TransformConfig, action: s configurationName = "webpack." + config.configName + ".js"; } - const projectRoot = findProjectRoot(); - const outputPath: string = initActionNotDefined - ? transformConfig.configPath - : path.join(projectRoot || process.cwd(), configurationName); - const source: string = ast.toSource({ - quote: "single" - }); - runPrettier(outputPath, source); - } - ) - .catch( - (err: Error): void => { - console.error(err.message ? err.message : err); - } - ); - } - ); - let successMessage: string = `Congratulations! Your new webpack configuration file has been created!\n`; + const projectRoot = findProjectRoot(); + const outputPath: string = initActionNotDefined + ? transformConfig.configPath + : path.join(projectRoot || process.cwd(), configurationName); + const source: string = ast.toSource({ + quote: "single", + }); + runPrettier(outputPath, source); + + }) + .catch((err: IError) => { + console.error(err.message ? err.message : err); + }); + }); + let successMessage: string = + chalk.green(`Congratulations! Your new webpack configuration file has been created!\n\n`) + + `You can now run ${chalk.green("npm run start")} to run your project!\n\n`; + if (initActionNotDefined && transformConfig.config.item) { - successMessage = `Congratulations! ${transformConfig.config.item} has been ${action}ed!\n`; + successMessage = chalk.green(`Congratulations! ${ + transformConfig.config.item + } has been ${action}ed!\n`); } - process.stdout.write("\n" + chalk.green(successMessage)); + process.stdout.write(`\n${successMessage}`); } From d5748461fe8b298b918bab00b681d3d4388c8fd0 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 19 Apr 2019 15:17:18 +0200 Subject: [PATCH 15/50] misc(generators): refactor init-generator --- packages/generators/add-generator.ts | 2 +- packages/generators/init-generator.ts | 574 +++++++++++--------------- 2 files changed, 235 insertions(+), 341 deletions(-) diff --git a/packages/generators/add-generator.ts b/packages/generators/add-generator.ts index bef3c32afd3..d9d7ec7d79f 100644 --- a/packages/generators/add-generator.ts +++ b/packages/generators/add-generator.ts @@ -140,7 +140,7 @@ export default class AddGenerator extends Generator { .then( (entryTypeAnswer: { entryType: boolean }): Promise => { // Ask different questions for entry points - return entryQuestions(self, entryTypeAnswer); + return entryQuestions(self, entryTypeAnswer.entryType); } ) .then( diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 715b44e8797..d3a458307bb 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -1,7 +1,9 @@ + import chalk from "chalk"; import * as logSymbols from "log-symbols"; import * as Generator from "yeoman-generator"; import * as Inquirer from "inquirer"; +import * as path from "path"; import { getPackageManager } from "@webpack-cli/utils/package-manager"; import { Confirm, Input, List } from "@webpack-cli/webpack-scaffold"; @@ -9,7 +11,7 @@ import { Confirm, Input, List } from "@webpack-cli/webpack-scaffold"; import { WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; import getBabelPlugin from "./utils/module"; -import getDefaultPlugins from "./utils/plugins"; +import styleQuestionHandler from "./utils/style"; import tooltip from "./utils/tooltip"; /** @@ -35,20 +37,98 @@ export default class InitGenerator extends Generator { public constructor(args, opts) { super(args, opts); - this.isProd = false; - (this.usingDefaults = false), - (this.dependencies = [ - "webpack", - "webpack-cli", - "terser-webpack-plugin", - "babel-plugin-syntax-dynamic-import" - ]); + this.usingDefaults = false, + this.isProd = this.usingDefaults ? true : false; + + this.dependencies = [ + "webpack", + "webpack-cli", + "babel-plugin-syntax-dynamic-import", + ]; + if (this.isProd) { + this.dependencies.push("terser-webpack-plugin"); + } else { + this.dependencies.push("webpack-dev-server"); + } + this.configuration = { config: { + configName: this.isProd ? "prod" : "config", topScope: [], - webpackOptions: {} - } + // tslint:disable: object-literal-sort-keys + webpackOptions: { + mode: this.isProd ? "'production'" : "'development'", + entry: undefined, + output: undefined, + plugins: [], + module: { + rules: [], + }, + }, + // tslint:enable: object-literal-sort-keys + }, }; + + // add splitChunks options for transparency + // defaults coming from: https://webpack.js.org/plugins/split-chunks-plugin/#optimization-splitchunks + this.configuration.config.topScope.push( + "const path = require('path');", + "const webpack = require('webpack');", + "\n", + tooltip.splitChunks(), + ); + + if (this.isProd) { + this.configuration.config.topScope.push( + tooltip.terser(), + "const TerserPlugin = require('terser-webpack-plugin');", + "\n", + ); + } + + this.configuration.config.webpackOptions.plugins.push( + "new webpack.ProgressPlugin()", + ); + + if (this.isProd) { + this.configuration.config.webpackOptions.plugins.push( + "new TerserPlugin()", + ); + } + + let optimizationObj; + + if (!this.isProd) { + optimizationObj = { + splitChunks: { + chunks: "'all'", + }, + }; + } else { + optimizationObj = { + splitChunks: { + cacheGroups: { + vendors: { + priority: -10, + test: "/[\\\\/]node_modules[\\\\/]/", + }, + }, + chunks: "'async'", + minChunks: 1, + minSize: 30000, + // for production name is recommended to be off + name: !this.isProd, + }, + }; + } + + this.configuration.config.webpackOptions.optimization = optimizationObj; + + if (!this.isProd) { + this.configuration.config.webpackOptions.devServer = { + open: true, + }; + } } // eslint-disable-next-line @@ -59,363 +139,177 @@ export default class InitGenerator extends Generator { let ExtractUseProps: object[]; process.stdout.write( - "\n" + - logSymbols.info + - chalk.blue(" INFO ") + - "For more information and a detailed description of each question, have a look at " + - chalk.bold.green("https://github.com/webpack/webpack-cli/blob/master/INIT.md") + - "\n" + `\n${logSymbols.info}${chalk.blue(" INFO ")} ` + + `For more information and a detailed description of each question, have a look at: ` + + `${chalk.bold.green("https://github.com/webpack/webpack-cli/blob/master/INIT.md")}\n`, ); process.stdout.write( - logSymbols.info + - chalk.blue(" INFO ") + - "Alternatively, run `webpack(-cli) --help` for usage info." + - "\n\n" + `${logSymbols.info}${chalk.blue(" INFO ")} ` + + `Alternatively, run "webpack(-cli) --help" for usage info\n\n`, ); - this.configuration.config.webpackOptions.module = { - rules: [] - }; - this.configuration.config.topScope.push( - "const webpack = require('webpack')", - "const path = require('path')", - "\n" - ); - - return this.prompt([Confirm("entryType", "Will your application have multiple bundles?", false)]) - .then( - (entryTypeAnswer: { entryType: boolean }): Promise => { - // Ask different questions for entry points - return entryQuestions(self, entryTypeAnswer); - } + return this.prompt([ + Confirm("multiEntries", "Will your application have multiple bundles?", false), + ]) + .then((multiEntriesAnswer: any) => + entryQuestions(self, multiEntriesAnswer.multiEntries), ) - .then( - (entryOptions: object | string): Promise<{}> => { - if (typeof entryOptions === "string" && entryOptions.length > 0) { - if (entryOptions !== "\"\"" && entryOptions !== "\'\'") { - this.configuration.config.webpackOptions.entry = entryOptions; - } - } - - return this.prompt([ - Input("outputType", "In which folder do you want to store your generated bundles? (dist):") - ]); + .then((entryOption: object | string) => { + if (typeof entryOption === "string" && entryOption.length > 0) { + this.configuration.config.webpackOptions.entry = `${entryOption}`; } + }) + .then((_: void) => + this.prompt([ + Input( + "outputDir", + "In which folder do you want to store your generated bundles?", + "dist", + ), + ]), ) - .then( - (outputTypeAnswer: { outputType: string }): void => { - // As entry is not required anymore and we dont set it to be an empty string or """"" - // it can be undefined so falsy check is enough (vs entry.length); - if (!this.configuration.config.webpackOptions.entry && !this.usingDefaults) { - this.configuration.config.webpackOptions.output = { - chunkFilename: "'[name].[chunkhash].js'", - filename: "'[name].[chunkhash].js'" - }; - } else if (!this.usingDefaults) { - this.configuration.config.webpackOptions.output = { - filename: "'[name].[chunkhash].js'" - }; - } - if (!this.usingDefaults && outputTypeAnswer.outputType.length) { - this.configuration.config.webpackOptions.output.path = `path.resolve(__dirname, '${ - outputTypeAnswer.outputType - }')`; - } + .then((outputDirAnswer: { + outputDir: string; + }) => { + // As entry is not required anymore and we dont set it to be an empty string or """"" + // it can be undefined so falsy check is enough (vs entry.length); + if ( + !this.configuration.config.webpackOptions.entry && + !this.usingDefaults + ) { + this.configuration.config.webpackOptions.output = { + chunkFilename: "'[name].[chunkhash].js'", + filename: "'[name].[chunkhash].js'", + }; + } else if (!this.usingDefaults) { + this.configuration.config.webpackOptions.output = { + filename: "'[name].[chunkhash].js'", + }; } - ) - .then( - (): Promise => { - this.isProd = this.usingDefaults ? true : false; - this.configuration.config.configName = this.isProd ? "prod" : "config"; - if (!this.isProd) { - this.configuration.config.webpackOptions.mode = "'development'"; - } - this.configuration.config.webpackOptions.plugins = this.isProd ? [] : getDefaultPlugins(); - return this.prompt([Confirm("babelConfirm", "Will you be using ES2015?")]); + if (!this.usingDefaults && outputDirAnswer.outputDir.length) { + this.configuration.config.webpackOptions.output.path = + `path.resolve(__dirname, '${outputDirAnswer.outputDir}')`; } + }) + .then((_: void) => + this.prompt([ + Confirm("useBabel", "Will you be using ES2015?"), + ]), ) - .then( - (babelConfirmAnswer: { babelConfirm: boolean }): void => { - if (babelConfirmAnswer.babelConfirm) { - this.configuration.config.webpackOptions.module.rules.push(getBabelPlugin()); - this.dependencies.push("babel-loader", "@babel/core", "@babel/preset-env"); - } + .then((useBabelAnswer: { + useBabel: boolean; + }) => { + if (useBabelAnswer.useBabel) { + this.configuration.config.webpackOptions.module.rules.push( + getBabelPlugin(), + ); + this.dependencies.push( + "babel-loader", + "@babel/core", + "@babel/preset-env", + ); } + }) + .then((_: void) => + this.prompt([ + List("stylingType", "Will you use one of the below CSS solutions?", [ + "No", + "CSS", + "SASS", + "LESS", + "PostCSS", + ]), + ])) + .then((stylingTypeAnswer: { + stylingType: string; + }) => + ({ ExtractUseProps, regExpForStyles } = styleQuestionHandler(self, stylingTypeAnswer.stylingType)), ) - .then( - (): Promise => { + .then((): Promise => { + if (this.isProd) { + // Ask if the user wants to use extractPlugin return this.prompt([ - List("stylingType", "Will you use one of the below CSS solutions?", [ - "No", - "CSS", - "SASS", - "LESS", - "PostCSS" - ]) + Input( + "useExtractPlugin", + "If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)", + ), ]); } - ) - .then( - (stylingTypeAnswer: { stylingType: string }): void => { - ExtractUseProps = []; - switch (stylingTypeAnswer.stylingType) { - case "SASS": - this.dependencies.push("sass-loader", "node-sass", "style-loader", "css-loader"); - regExpForStyles = `${new RegExp(/\.(scss|css)$/)}`; - if (this.isProd) { - ExtractUseProps.push( - { - loader: "'css-loader'", - options: { - sourceMap: true - } - }, - { - loader: "'sass-loader'", - options: { - sourceMap: true - } - } - ); - } else { - ExtractUseProps.push( - { - loader: "'style-loader'" - }, - { - loader: "'css-loader'" - }, - { - loader: "'sass-loader'" - } - ); - } - break; - case "LESS": - regExpForStyles = `${new RegExp(/\.(less|css)$/)}`; - this.dependencies.push("less-loader", "less", "style-loader", "css-loader"); - if (this.isProd) { - ExtractUseProps.push( - { - loader: "'css-loader'", - options: { - sourceMap: true - } - }, - { - loader: "'less-loader'", - options: { - sourceMap: true - } - } - ); - } else { - ExtractUseProps.push( - { - loader: "'css-loader'", - options: { - sourceMap: true - } - }, - { - loader: "'less-loader'", - options: { - sourceMap: true - } - } - ); - } - break; - case "PostCSS": - this.configuration.config.topScope.push( - tooltip.postcss(), - "const autoprefixer = require('autoprefixer');", - "const precss = require('precss');", - "\n" - ); - this.dependencies.push( - "style-loader", - "css-loader", - "postcss-loader", - "precss", - "autoprefixer" - ); - regExpForStyles = `${new RegExp(/\.css$/)}`; - if (this.isProd) { - ExtractUseProps.push( - { - loader: "'css-loader'", - options: { - importLoaders: 1, - sourceMap: true - } - }, - { - loader: "'postcss-loader'", - options: { - plugins: `function () { - return [ - precss, - autoprefixer - ]; - }` - } - } - ); - } else { - ExtractUseProps.push( - { - loader: "'style-loader'" - }, - { - loader: "'css-loader'", - options: { - importLoaders: 1, - sourceMap: true - } - }, - { - loader: "'postcss-loader'", - options: { - plugins: `function () { - return [ - precss, - autoprefixer - ]; - }` - } - } - ); - } - break; - case "CSS": - this.dependencies.push("style-loader", "css-loader"); - regExpForStyles = `${new RegExp(/\.css$/)}`; - if (this.isProd) { - ExtractUseProps.push({ - loader: "'css-loader'", - options: { - sourceMap: true - } - }); - } else { - ExtractUseProps.push( - { - loader: "'style-loader'", - options: { - sourceMap: true - } - }, - { - loader: "'css-loader'" - } - ); - } - break; - default: - regExpForStyles = null; - } - } - ) - .then( - (): Promise => { + }) + .then((useExtractPluginAnswer: { + useExtractPlugin: string; + }) => { + if (regExpForStyles) { if (this.isProd) { - // Ask if the user wants to use extractPlugin - return this.prompt([ - Input( - "extractPlugin", - "If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)" - ) - ]); - } - } - ) - .then( - (extractPluginAnswer: { extractPlugin: string }): void => { - if (regExpForStyles) { - if (this.isProd) { - const cssBundleName: string = extractPluginAnswer.extractPlugin; - this.configuration.config.topScope.push(tooltip.cssPlugin()); - this.dependencies.push("mini-css-extract-plugin"); - - if (cssBundleName.length !== 0) { - (this.configuration.config.webpackOptions.plugins as string[]).push( - // TODO: use [contenthash] after it is supported - `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })` - ); - } else { - (this.configuration.config.webpackOptions.plugins as string[]).push( - "new MiniCssExtractPlugin({ filename:'style.css' })" - ); - } - - ExtractUseProps.unshift({ - loader: "MiniCssExtractPlugin.loader" - }); - - const moduleRulesObj = { - test: regExpForStyles, - use: ExtractUseProps - }; - - this.configuration.config.webpackOptions.module.rules.push(moduleRulesObj); - this.configuration.config.topScope.push( - "const MiniCssExtractPlugin = require('mini-css-extract-plugin');", - "\n" + const cssBundleName: string = useExtractPluginAnswer.useExtractPlugin; + this.dependencies.push("mini-css-extract-plugin"); + this.configuration.config.topScope.push( + tooltip.cssPlugin(), + "const MiniCssExtractPlugin = require('mini-css-extract-plugin');", + "\n", + ); + if (cssBundleName.length !== 0) { + this.configuration.config.webpackOptions.plugins.push( + // TODO: use [contenthash] after it is supported + `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })`, ); } else { - const moduleRulesObj: { - test: string; - use: object[]; - } = { - test: regExpForStyles, - use: ExtractUseProps - }; - - this.configuration.config.webpackOptions.module.rules.push(moduleRulesObj); + this.configuration.config.webpackOptions.plugins.push( + "new MiniCssExtractPlugin({ filename:'style.css' })", + ); } + + ExtractUseProps.unshift({ + loader: "MiniCssExtractPlugin.loader", + }); } - // add splitChunks options for transparency - // defaults coming from: https://webpack.js.org/plugins/split-chunks-plugin/#optimization-splitchunks - this.configuration.config.topScope.push(tooltip.splitChunks()); - this.configuration.config.webpackOptions.optimization = { - splitChunks: { - cacheGroups: { - vendors: { - priority: -10, - test: "/[\\\\/]node_modules[\\\\/]/" - } - }, - chunks: "'async'", - minChunks: 1, - minSize: 30000, - // for production name is recommended to be off - name: !this.isProd - } - }; - done(); + + this.configuration.config.webpackOptions.module.rules.push( + { + test: regExpForStyles, + use: ExtractUseProps, + }, + ); } - ); + + done(); + }); } - public installPlugins(): void { - if (this.isProd) { - this.dependencies = this.dependencies.filter((p: string): boolean => p !== "terser-webpack-plugin"); - } else { - this.configuration.config.topScope.push( - tooltip.terser(), - "const TerserPlugin = require('terser-webpack-plugin');", - "\n" - ); - } + + public installPlugins() { const packager = getPackageManager(); const opts: { - dev?: boolean; - "save-dev"?: boolean; - } = packager === "yarn" ? { dev: true } : { "save-dev": true }; + dev?: boolean, + "save-dev"?: boolean, + } = packager === "yarn" ? + { dev: true } : + { "save-dev": true }; + this.scheduleInstallTask(packager, this.dependencies, opts); } public writing(): void { this.config.set("configuration", this.configuration); + + const packageJsonTemplatePath = "./templates/package.json.js"; + this.fs.extendJSON(this.destinationPath("package.json"), require(packageJsonTemplatePath)(this.isProd)); + + const entry = this.configuration.config.webpackOptions.entry; + const generateEntryFile = (entryPath: string, name: string) => { + entryPath = entryPath.replace(/'/g, ""); + this.fs.copyTpl( + path.resolve(__dirname, "./templates/index.js"), + this.destinationPath(entryPath), + { name }, + ); + }; + + if ( typeof entry === "string" ) { + generateEntryFile(entry, "your main file!"); + } else if (typeof entry === "object") { + Object.keys(entry).forEach((name) => + generateEntryFile(entry[name], `${name} main file!`), + ); + } } } From 6be92918cbe1f577bf7b386ab992d020d537a68b Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 19 Apr 2019 15:18:42 +0200 Subject: [PATCH 16/50] feat(generators): add generated file templates --- packages/generators/.gitignore | 1 + packages/generators/templates/index.js | 5 +++++ packages/generators/templates/package.json.js | 15 +++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 packages/generators/templates/index.js create mode 100644 packages/generators/templates/package.json.js diff --git a/packages/generators/.gitignore b/packages/generators/.gitignore index 74dcaf3ce86..b3cdf36cae7 100644 --- a/packages/generators/.gitignore +++ b/packages/generators/.gitignore @@ -2,3 +2,4 @@ **/*.js !*.test.js !/**/*.test.js +!/templates/*.js diff --git a/packages/generators/templates/index.js b/packages/generators/templates/index.js new file mode 100644 index 00000000000..05b1c0677bc --- /dev/null +++ b/packages/generators/templates/index.js @@ -0,0 +1,5 @@ +/** + * Application entry point + */ + +console.log("Hello World from <%= name %>"); diff --git a/packages/generators/templates/package.json.js b/packages/generators/templates/package.json.js new file mode 100644 index 00000000000..54089edb516 --- /dev/null +++ b/packages/generators/templates/package.json.js @@ -0,0 +1,15 @@ +module.exports = (isProd) => { + + let scripts = { + build: "webpack" + }; + if (!isProd) { + scripts.start = "webpack-dev-server"; + } + + return { + version: "1.0.0", + description: "My webpack project", + scripts, + }; +}; From 9856babdd88eb2d289c5d6306c5a5b874d5bdef2 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 19 Apr 2019 15:19:55 +0200 Subject: [PATCH 17/50] docs(init): improve description --- INIT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INIT.md b/INIT.md index 112ca86eb77..bc9350b8245 100644 --- a/INIT.md +++ b/INIT.md @@ -1,6 +1,6 @@ # webpack-cli init -`webpack-cli init` is used to initialize `webpack` projects quickly by scaffolding configuration and installing modules required for the project as per user preferences. +`webpack-cli init` is used to initialize `webpack` projects quickly by scaffolding configuration and a runnable project with all the dependencies based on the user preferences. ## Initial Setup From fb23aa40eb7b5683af51f1eb55d0ca6a932a60c6 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Sat, 20 Apr 2019 17:36:58 +0200 Subject: [PATCH 18/50] misc(init-generator): improve types & defaults --- INIT.md | 2 +- packages/generators/init-generator.ts | 12 ++++++++---- packages/generators/utils/entry.ts | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/INIT.md b/INIT.md index bc9350b8245..8dd9a3a7099 100644 --- a/INIT.md +++ b/INIT.md @@ -1,6 +1,6 @@ # webpack-cli init -`webpack-cli init` is used to initialize `webpack` projects quickly by scaffolding configuration and a runnable project with all the dependencies based on the user preferences. +`webpack-cli init` is used to initialize `webpack` projects quickly by scaffolding configuration and creating a runnable project with all the dependencies based on the user preferences. ## Initial Setup diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index d3a458307bb..d06a1efa097 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -151,15 +151,19 @@ export default class InitGenerator extends Generator { return this.prompt([ Confirm("multiEntries", "Will your application have multiple bundles?", false), ]) - .then((multiEntriesAnswer: any) => + .then((multiEntriesAnswer: { + multiEntries: boolean, + }) => entryQuestions(self, multiEntriesAnswer.multiEntries), ) .then((entryOption: object | string) => { if (typeof entryOption === "string" && entryOption.length > 0) { this.configuration.config.webpackOptions.entry = `${entryOption}`; + } else if (typeof entryOption === "object") { + this.configuration.config.webpackOptions.entry = entryOption; } }) - .then((_: void) => + .then(() => this.prompt([ Input( "outputDir", @@ -191,7 +195,7 @@ export default class InitGenerator extends Generator { `path.resolve(__dirname, '${outputDirAnswer.outputDir}')`; } }) - .then((_: void) => + .then(() => this.prompt([ Confirm("useBabel", "Will you be using ES2015?"), ]), @@ -210,7 +214,7 @@ export default class InitGenerator extends Generator { ); } }) - .then((_: void) => + .then(() => this.prompt([ List("stylingType", "Will you use one of the below CSS solutions?", [ "No", diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts index 5f136e0b940..e9cb3d85587 100644 --- a/packages/generators/utils/entry.ts +++ b/packages/generators/utils/entry.ts @@ -104,7 +104,7 @@ export default function entry(self: CustomGenerator, multiEntries: boolean): Pro `${entryProp}`, `What is the location of "${entryProp}"?`, validate, - `./src/${entryProp}`, + `src/${entryProp}`, ), ]), ).then((entryPropAnswer: object): object => { From 392fcfec1e50b8655e569d7adcbfc896b235fc6f Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Sat, 20 Apr 2019 19:23:34 +0200 Subject: [PATCH 19/50] misc(generators/utils/style): refactor --- packages/generators/init-generator.ts | 21 +-- packages/generators/utils/style.ts | 258 ++++++++++++++------------ 2 files changed, 148 insertions(+), 131 deletions(-) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index d06a1efa097..8ef4cdfdc23 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -11,7 +11,7 @@ import { Confirm, Input, List } from "@webpack-cli/webpack-scaffold"; import { WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; import getBabelPlugin from "./utils/module"; -import styleQuestionHandler from "./utils/style"; +import styleQuestionHandler, { ILoader, StylingType } from "./utils/style"; import tooltip from "./utils/tooltip"; /** @@ -90,12 +90,6 @@ export default class InitGenerator extends Generator { "new webpack.ProgressPlugin()", ); - if (this.isProd) { - this.configuration.config.webpackOptions.plugins.push( - "new TerserPlugin()", - ); - } - let optimizationObj; if (!this.isProd) { @@ -106,6 +100,9 @@ export default class InitGenerator extends Generator { }; } else { optimizationObj = { + minimizer: [ + "new TerserPlugin()", + ], splitChunks: { cacheGroups: { vendors: { @@ -136,7 +133,7 @@ export default class InitGenerator extends Generator { const done: () => {} = this.async(); const self: this = this; let regExpForStyles: string; - let ExtractUseProps: object[]; + let ExtractUseProps: ILoader[]; process.stdout.write( `\n${logSymbols.info}${chalk.blue(" INFO ")} ` + @@ -218,10 +215,10 @@ export default class InitGenerator extends Generator { this.prompt([ List("stylingType", "Will you use one of the below CSS solutions?", [ "No", - "CSS", - "SASS", - "LESS", - "PostCSS", + StylingType.CSS, + StylingType.SASS, + StylingType.LESS, + StylingType.PostCSS, ]), ])) .then((stylingTypeAnswer: { diff --git a/packages/generators/utils/style.ts b/packages/generators/utils/style.ts index 9d4d428ace8..5a642932f97 100644 --- a/packages/generators/utils/style.ts +++ b/packages/generators/utils/style.ts @@ -1,168 +1,188 @@ import tooltip from "./tooltip"; +export enum StylingType { + CSS = "CSS", + SASS = "SASS", + LESS = "LESS", + PostCSS = "PostCSS", +} + +export enum Loader { + CSS = "css-loader", + SASS = "sass-loader", + STYLE = "style-loader", + LESS = "less-loader", + POSTCSS = "postcss-loader", +} + +export enum StyleRegex { + CSS = "/\.css$/", + SASS = "/\.(scss|css)$/", + LESS = "/\.(less|css)$/", + PostCSS = "/\.css$/", +} + +export interface ILoader { + loader: string; + options?: { + importLoaders?: number; + sourceMap?: boolean; + plugins?: string; + }; +} + export default function style(self, stylingType) { - const ExtractUseProps = []; + const ExtractUseProps: ILoader[] = []; let regExpForStyles = null; + switch (stylingType) { - case "SASS": + case StylingType.CSS: + regExpForStyles = StyleRegex.CSS; + self.dependencies.push( - "sass-loader", - "node-sass", - "style-loader", - "css-loader", + Loader.CSS, ); - regExpForStyles = `${new RegExp(/\.(scss|css)$/)}`; - if (self.isProd) { + if (self.isProf) { + self.dependencies.push( + Loader.STYLE, + ); + } + + ExtractUseProps.push({ + loader: `"${Loader.CSS}"`, + options: { + sourceMap: true, + }, + }); + if (!self.isProd) { ExtractUseProps.push( { - loader: "'css-loader'", - options: { - sourceMap: true, - }, - }, - { - loader: "'sass-loader'", - options: { - sourceMap: true, - }, + loader: `"${Loader.STYLE}"`, }, ); - } else { - ExtractUseProps.push( - { - loader: "'style-loader'", + } + break; + + case StylingType.SASS: + regExpForStyles = StyleRegex.SASS; + + self.dependencies.push( + "node-sass", + Loader.SASS, + Loader.CSS, + ); + if (self.isProf) { + self.dependencies.push( + Loader.STYLE, + ); + } + + ExtractUseProps.push( + { + loader: `"${Loader.CSS}"`, + options: { + sourceMap: true, }, - { - loader: "'css-loader'", + }, + { + loader: `"${Loader.SASS}"`, + options: { + sourceMap: true, }, + }, + ); + if (!self.isProd) { + ExtractUseProps.push( { - loader: "'sass-loader'", + loader: `"${Loader.STYLE}"`, }, ); } break; - case "LESS": - regExpForStyles = `${new RegExp(/\.(less|css)$/)}`; + + case StylingType.LESS: + regExpForStyles = StyleRegex.LESS; + self.dependencies.push( - "less-loader", "less", - "style-loader", - "css-loader", + Loader.LESS, + Loader.CSS, ); - if (self.isProd) { - ExtractUseProps.push( - { - loader: "'css-loader'", - options: { - sourceMap: true, - }, + if (self.isProf) { + self.dependencies.push( + Loader.STYLE, + ); + } + + ExtractUseProps.push( + { + loader: `"${Loader.CSS}"`, + options: { + sourceMap: true, }, - { - loader: "'less-loader'", - options: { - sourceMap: true, - }, + }, + { + loader: `"${Loader.LESS}"`, + options: { + sourceMap: true, }, - ); - } else { + }, + ); + if (!self.isProd) { ExtractUseProps.push( { - loader: "'css-loader'", - options: { - sourceMap: true, - }, - }, - { - loader: "'less-loader'", - options: { - sourceMap: true, - }, + loader: `"${Loader.STYLE}"`, }, ); } break; - case "PostCSS": + + case StylingType.PostCSS: + regExpForStyles = StyleRegex.PostCSS; + self.configuration.config.topScope.push( tooltip.postcss(), "const autoprefixer = require('autoprefixer');", "const precss = require('precss');", "\n", ); + self.dependencies.push( - "style-loader", - "css-loader", - "postcss-loader", "precss", "autoprefixer", + Loader.CSS, + Loader.POSTCSS, ); - regExpForStyles = `${new RegExp(/\.css$/)}`; - if (self.isProd) { - ExtractUseProps.push( - { - loader: "'css-loader'", - options: { - importLoaders: 1, - sourceMap: true, - }, - }, - { - loader: "'postcss-loader'", - options: { - plugins: `function () { - return [ - precss, - autoprefixer - ]; - }`, - }, - }, - ); - } else { - ExtractUseProps.push( - { - loader: "'style-loader'", - }, - { - loader: "'css-loader'", - options: { - importLoaders: 1, - sourceMap: true, - }, - }, - { - loader: "'postcss-loader'", - options: { - plugins: `function () { - return [ - precss, - autoprefixer - ]; - }`, - }, - }, + if (self.isProf) { + self.dependencies.push( + Loader.STYLE, ); } - break; - case "CSS": - self.dependencies.push("style-loader", "css-loader"); - regExpForStyles = `${new RegExp(/\.css$/)}`; - if (self.isProd) { - ExtractUseProps.push({ - loader: "'css-loader'", + + ExtractUseProps.push( + { + loader: `"${Loader.CSS}"`, options: { + importLoaders: 1, sourceMap: true, }, - }); - } else { + }, + { + loader: `"${Loader.POSTCSS}"`, + options: { + plugins: `function () { + return [ + precss, + autoprefixer + ]; + }`, + }, + }, + ); + if (!self.isProd) { ExtractUseProps.push( { - loader: "'style-loader'", - options: { - sourceMap: true, - }, - }, - { - loader: "'css-loader'", + loader: `"${Loader.STYLE}"`, }, ); } From f46f4e539e1bff414085295abaa900413e983da9 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Sat, 20 Apr 2019 19:53:04 +0200 Subject: [PATCH 20/50] fix(genrators/utils/style): typo & fix --- packages/generators/utils/style.ts | 60 ++++++++++++------------------ 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/packages/generators/utils/style.ts b/packages/generators/utils/style.ts index 5a642932f97..cc07306d3c0 100644 --- a/packages/generators/utils/style.ts +++ b/packages/generators/utils/style.ts @@ -42,25 +42,22 @@ export default function style(self, stylingType) { self.dependencies.push( Loader.CSS, ); - if (self.isProf) { + if (!self.isProd) { self.dependencies.push( Loader.STYLE, ); + ExtractUseProps.push( + { + loader: `"${Loader.STYLE}"`, + }, + ); } - ExtractUseProps.push({ loader: `"${Loader.CSS}"`, options: { sourceMap: true, }, }); - if (!self.isProd) { - ExtractUseProps.push( - { - loader: `"${Loader.STYLE}"`, - }, - ); - } break; case StylingType.SASS: @@ -71,12 +68,16 @@ export default function style(self, stylingType) { Loader.SASS, Loader.CSS, ); - if (self.isProf) { + if (!self.isProd) { self.dependencies.push( Loader.STYLE, ); + ExtractUseProps.push( + { + loader: `"${Loader.STYLE}"`, + }, + ); } - ExtractUseProps.push( { loader: `"${Loader.CSS}"`, @@ -91,13 +92,6 @@ export default function style(self, stylingType) { }, }, ); - if (!self.isProd) { - ExtractUseProps.push( - { - loader: `"${Loader.STYLE}"`, - }, - ); - } break; case StylingType.LESS: @@ -108,12 +102,16 @@ export default function style(self, stylingType) { Loader.LESS, Loader.CSS, ); - if (self.isProf) { + if (!self.isProd) { self.dependencies.push( Loader.STYLE, ); + ExtractUseProps.push( + { + loader: `"${Loader.STYLE}"`, + }, + ); } - ExtractUseProps.push( { loader: `"${Loader.CSS}"`, @@ -128,13 +126,6 @@ export default function style(self, stylingType) { }, }, ); - if (!self.isProd) { - ExtractUseProps.push( - { - loader: `"${Loader.STYLE}"`, - }, - ); - } break; case StylingType.PostCSS: @@ -153,12 +144,16 @@ export default function style(self, stylingType) { Loader.CSS, Loader.POSTCSS, ); - if (self.isProf) { + if (!self.isProd) { self.dependencies.push( Loader.STYLE, ); + ExtractUseProps.push( + { + loader: `"${Loader.STYLE}"`, + }, + ); } - ExtractUseProps.push( { loader: `"${Loader.CSS}"`, @@ -179,13 +174,6 @@ export default function style(self, stylingType) { }, }, ); - if (!self.isProd) { - ExtractUseProps.push( - { - loader: `"${Loader.STYLE}"`, - }, - ); - } break; } return { ExtractUseProps, regExpForStyles }; From 093a36d8ddf129bb646dc2d1213dd708fba4c219 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Mon, 22 Apr 2019 12:43:50 +0200 Subject: [PATCH 21/50] feat(init): wip typescript support --- packages/generators/init-generator.ts | 23 +++++++--------- .../utils/{module.ts => language.ts} | 26 +++++++++++++++++-- 2 files changed, 33 insertions(+), 16 deletions(-) rename packages/generators/utils/{module.ts => language.ts} (55%) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 8ef4cdfdc23..e54995c3327 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -10,7 +10,7 @@ import { Confirm, Input, List } from "@webpack-cli/webpack-scaffold"; import { WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; -import getBabelPlugin from "./utils/module"; +import langQuestionHandler from "./utils/language"; import styleQuestionHandler, { ILoader, StylingType } from "./utils/style"; import tooltip from "./utils/tooltip"; @@ -194,22 +194,17 @@ export default class InitGenerator extends Generator { }) .then(() => this.prompt([ - Confirm("useBabel", "Will you be using ES2015?"), + List("langType", "Will you use one of the below JS solutions?", [ + "ES6", + "Typescript", + "No", + ]), ]), ) - .then((useBabelAnswer: { - useBabel: boolean; + .then((langTypeAnswer: { + langType: boolean; }) => { - if (useBabelAnswer.useBabel) { - this.configuration.config.webpackOptions.module.rules.push( - getBabelPlugin(), - ); - this.dependencies.push( - "babel-loader", - "@babel/core", - "@babel/preset-env", - ); - } + langQuestionHandler(this, langTypeAnswer.langType); }) .then(() => this.prompt([ diff --git a/packages/generators/utils/module.ts b/packages/generators/utils/language.ts similarity index 55% rename from packages/generators/utils/module.ts rename to packages/generators/utils/language.ts index 25b846723f1..ffa887de45d 100644 --- a/packages/generators/utils/module.ts +++ b/packages/generators/utils/language.ts @@ -1,4 +1,9 @@ -interface Module extends Object { +export enum LangType { + ES6 = "ES6", + Typescript = "Typescript", +} + +interface ModuleRule extends Object { include: string[]; loader: string; options: { @@ -16,7 +21,7 @@ type Preset = string | object; * * @returns {Function} A callable function that adds the babel-loader with env preset */ -export default function(): Module { +export function getBabelPlugin(): ModuleRule { return { include: ["path.resolve(__dirname, 'src')"], loader: "'babel-loader'", @@ -34,3 +39,20 @@ export default function(): Module { test: `${new RegExp(/\.js$/)}` }; } + +export default function language(self, langType) { + switch (langType) { + case LangType.ES6: + self.configuration.config.webpackOptions.module.rules.push( + getBabelPlugin(), + ); + self.dependencies.push( + "babel-loader", + "@babel/core", + "@babel/preset-env", + ); + break; + case LangType.Typescript: + break; + } +} From 283e0892ef12ff13c6be4fb12eb02734861ffb98 Mon Sep 17 00:00:00 2001 From: Devid Farinelli Date: Tue, 23 Apr 2019 03:20:01 +0200 Subject: [PATCH 22/50] feat(init): support ts in configuration --- packages/generators/init-generator.ts | 1 + .../generators/templates/tsconfig.json.js | 9 +++ packages/generators/utils/language.ts | 55 ++++++++++++++++--- packages/utils/run-prettier.ts | 5 +- 4 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 packages/generators/templates/tsconfig.json.js diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index e54995c3327..5230434d4c0 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -55,6 +55,7 @@ export default class InitGenerator extends Generator { config: { configName: this.isProd ? "prod" : "config", topScope: [], + // TODO migrate tslint // tslint:disable: object-literal-sort-keys webpackOptions: { mode: this.isProd ? "'production'" : "'development'", diff --git a/packages/generators/templates/tsconfig.json.js b/packages/generators/templates/tsconfig.json.js new file mode 100644 index 00000000000..418c8927cab --- /dev/null +++ b/packages/generators/templates/tsconfig.json.js @@ -0,0 +1,9 @@ +module.exports = { + compilerOptions: { + noImplicitAny: true, + module: "es6", + target: "es5", + jsx: "react", + allowJs: true + } +}; diff --git a/packages/generators/utils/language.ts b/packages/generators/utils/language.ts index ffa887de45d..0d479e229e7 100644 --- a/packages/generators/utils/language.ts +++ b/packages/generators/utils/language.ts @@ -4,9 +4,10 @@ export enum LangType { } interface ModuleRule extends Object { - include: string[]; + include?: string[]; + exclude?: string[]; loader: string; - options: { + options?: { plugins: string[]; presets: Preset[][]; }; @@ -21,8 +22,11 @@ type Preset = string | object; * * @returns {Function} A callable function that adds the babel-loader with env preset */ -export function getBabelPlugin(): ModuleRule { +export function getBabelLoader(): ModuleRule { return { + // TODO migrate tslint + // tslint:disable: object-literal-sort-keys + test: "/\.js$/", include: ["path.resolve(__dirname, 'src')"], loader: "'babel-loader'", options: { @@ -36,23 +40,60 @@ export function getBabelPlugin(): ModuleRule { ] ] }, - test: `${new RegExp(/\.js$/)}` + // tslint:enable: object-literal-sort-keys + }; +} + +export function getTypescriptLoader(): ModuleRule { + return { + // TODO migrate tslint + // tslint:disable: object-literal-sort-keys + test: "/\.tsx?$/", + loader: "'ts-loader'", + include: ["path.resolve(__dirname, 'src')"], + exclude: ["/node_modules/"], + // tslint:enable: object-literal-sort-keys }; } export default function language(self, langType) { switch (langType) { case LangType.ES6: - self.configuration.config.webpackOptions.module.rules.push( - getBabelPlugin(), - ); self.dependencies.push( "babel-loader", "@babel/core", "@babel/preset-env", ); + self.configuration.config.webpackOptions.module.rules.push( + getBabelLoader(), + ); break; + case LangType.Typescript: + self.dependencies.push( + "typescript", + "ts-loader", + ); + self.configuration.config.webpackOptions.module.rules.push( + getTypescriptLoader(), + ); + self.configuration.config.webpackOptions.resolve = { + extensions: [ "'.tsx'", "'.ts'", "'.js'" ], + }; + + // Update the entry files extensions to .ts + const jsEntryOption = self.configuration.config.webpackOptions.entry; + const jsExtension = new RegExp("\.js(?!.*\.js)"); + let tsEntryOption = {}; + if (typeof jsEntryOption === "string") { + tsEntryOption = jsEntryOption.replace(jsExtension, ".ts"); + } else if (typeof jsEntryOption === "object") { + Object.keys(jsEntryOption).map((entry) => { + tsEntryOption[entry] = jsEntryOption[entry].replace(jsExtension, ".ts"); + }); + } + self.configuration.config.webpackOptions.entry = tsEntryOption; + self.log(jsEntryOption.replace(jsExtension, ".ts"), jsEntryOption); break; } } diff --git a/packages/utils/run-prettier.ts b/packages/utils/run-prettier.ts index 254f94029d7..2b9e7083a8f 100644 --- a/packages/utils/run-prettier.ts +++ b/packages/utils/run-prettier.ts @@ -19,7 +19,7 @@ export default function runPrettier(outputPath: string, source: string, cb?: Fun try { prettySource = prettier.format(source, { filepath: outputPath, - parser: "babel", + parser: "babylon", singleQuote: true, tabWidth: 1, useTabs: true, @@ -29,7 +29,8 @@ export default function runPrettier(outputPath: string, source: string, cb?: Fun "\n" + chalk.yellow( `WARNING: Could not apply prettier to ${outputPath}` + - " due validation error, but the file has been created\n", + " due validation error, but the file has been created\n" + + err, ), ); prettySource = source; From 4627ea1da4bc467cdc05a546b45026ca7b0793b4 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Tue, 23 Apr 2019 19:13:43 +0200 Subject: [PATCH 23/50] misc(init): small refactor --- packages/generators/templates/index.js | 4 ---- packages/generators/templates/tsconfig.json.js | 2 +- packages/generators/utils/language.ts | 3 +-- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/generators/templates/index.js b/packages/generators/templates/index.js index 05b1c0677bc..0eec583fb7e 100644 --- a/packages/generators/templates/index.js +++ b/packages/generators/templates/index.js @@ -1,5 +1 @@ -/** - * Application entry point - */ - console.log("Hello World from <%= name %>"); diff --git a/packages/generators/templates/tsconfig.json.js b/packages/generators/templates/tsconfig.json.js index 418c8927cab..0eae50cb36f 100644 --- a/packages/generators/templates/tsconfig.json.js +++ b/packages/generators/templates/tsconfig.json.js @@ -1,9 +1,9 @@ module.exports = { compilerOptions: { + allowSyntheticDefaultImports: true, noImplicitAny: true, module: "es6", target: "es5", - jsx: "react", allowJs: true } }; diff --git a/packages/generators/utils/language.ts b/packages/generators/utils/language.ts index 0d479e229e7..a71f1b9f4b5 100644 --- a/packages/generators/utils/language.ts +++ b/packages/generators/utils/language.ts @@ -88,12 +88,11 @@ export default function language(self, langType) { if (typeof jsEntryOption === "string") { tsEntryOption = jsEntryOption.replace(jsExtension, ".ts"); } else if (typeof jsEntryOption === "object") { - Object.keys(jsEntryOption).map((entry) => { + Object.keys(jsEntryOption).forEach((entry) => { tsEntryOption[entry] = jsEntryOption[entry].replace(jsExtension, ".ts"); }); } self.configuration.config.webpackOptions.entry = tsEntryOption; - self.log(jsEntryOption.replace(jsExtension, ".ts"), jsEntryOption); break; } } From ac35a315789ad9179700cda9e1991566ec6efe3e Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Tue, 23 Apr 2019 19:14:25 +0200 Subject: [PATCH 24/50] misc(generators): improve prompts --- packages/generators/utils/entry.ts | 4 ++-- packages/utils/run-prettier.ts | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts index e9cb3d85587..6feca520301 100644 --- a/packages/generators/utils/entry.ts +++ b/packages/generators/utils/entry.ts @@ -24,7 +24,7 @@ export default function entry(self: CustomGenerator, multiEntries: boolean): Pro .prompt([ InputValidate( "multipleEntries", - "Type the names you want for your modules (entry files) separated by comma", + "How do you want to name your bundles? (separated by comma)", validate, "pageOne, pageTwo", ), @@ -102,7 +102,7 @@ export default function entry(self: CustomGenerator, multiEntries: boolean): Pro self.prompt([ InputValidate( `${entryProp}`, - `What is the location of "${entryProp}"?`, + `Which will be the entry point of "${entryProp}"?`, validate, `src/${entryProp}`, ), diff --git a/packages/utils/run-prettier.ts b/packages/utils/run-prettier.ts index 2b9e7083a8f..bf4980150d9 100644 --- a/packages/utils/run-prettier.ts +++ b/packages/utils/run-prettier.ts @@ -19,19 +19,17 @@ export default function runPrettier(outputPath: string, source: string, cb?: Fun try { prettySource = prettier.format(source, { filepath: outputPath, - parser: "babylon", + parser: "babel", singleQuote: true, tabWidth: 1, useTabs: true, }); } catch (err) { process.stdout.write( - "\n" + - chalk.yellow( - `WARNING: Could not apply prettier to ${outputPath}` + - " due validation error, but the file has been created\n" + - err, - ), + `\n${chalk.yellow( + `WARNING: Could not apply prettier to ${outputPath}` + + " due validation error, but the file has been created\n", + )}`, ); prettySource = source; error = err; From 488b06cc32e25e4956b5f0c018023d62e32cd74c Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Tue, 23 Apr 2019 21:40:17 +0200 Subject: [PATCH 25/50] misc(packages): complete rebase --- packages/generators/init-generator.ts | 46 ++++++------- packages/generators/utils/entry.ts | 96 +++++++++++---------------- packages/generators/utils/language.ts | 35 +++++----- packages/generators/utils/style.ts | 57 ++++++++-------- packages/utils/scaffold.ts | 42 ++++++------ 5 files changed, 125 insertions(+), 151 deletions(-) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 5230434d4c0..a40c0bc9d12 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -1,4 +1,3 @@ - import chalk from "chalk"; import * as logSymbols from "log-symbols"; import * as Generator from "yeoman-generator"; @@ -11,7 +10,7 @@ import { Confirm, Input, List } from "@webpack-cli/webpack-scaffold"; import { WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; import langQuestionHandler from "./utils/language"; -import styleQuestionHandler, { ILoader, StylingType } from "./utils/style"; +import styleQuestionHandler, { Loader, StylingType } from "./utils/style"; import tooltip from "./utils/tooltip"; /** @@ -55,8 +54,6 @@ export default class InitGenerator extends Generator { config: { configName: this.isProd ? "prod" : "config", topScope: [], - // TODO migrate tslint - // tslint:disable: object-literal-sort-keys webpackOptions: { mode: this.isProd ? "'production'" : "'development'", entry: undefined, @@ -66,7 +63,6 @@ export default class InitGenerator extends Generator { rules: [], }, }, - // tslint:enable: object-literal-sort-keys }, }; @@ -87,7 +83,7 @@ export default class InitGenerator extends Generator { ); } - this.configuration.config.webpackOptions.plugins.push( + (this.configuration.config.webpackOptions.plugins as string[]).push( "new webpack.ProgressPlugin()", ); @@ -134,7 +130,7 @@ export default class InitGenerator extends Generator { const done: () => {} = this.async(); const self: this = this; let regExpForStyles: string; - let ExtractUseProps: ILoader[]; + let ExtractUseProps: Loader[]; process.stdout.write( `\n${logSymbols.info}${chalk.blue(" INFO ")} ` + @@ -151,17 +147,17 @@ export default class InitGenerator extends Generator { ]) .then((multiEntriesAnswer: { multiEntries: boolean, - }) => + }): Promise<{}> => entryQuestions(self, multiEntriesAnswer.multiEntries), ) - .then((entryOption: object | string) => { + .then((entryOption: object | string): void => { if (typeof entryOption === "string" && entryOption.length > 0) { this.configuration.config.webpackOptions.entry = `${entryOption}`; } else if (typeof entryOption === "object") { this.configuration.config.webpackOptions.entry = entryOption; } }) - .then(() => + .then((): Promise<{}> => this.prompt([ Input( "outputDir", @@ -172,7 +168,7 @@ export default class InitGenerator extends Generator { ) .then((outputDirAnswer: { outputDir: string; - }) => { + }): void => { // As entry is not required anymore and we dont set it to be an empty string or """"" // it can be undefined so falsy check is enough (vs entry.length); if ( @@ -193,7 +189,7 @@ export default class InitGenerator extends Generator { `path.resolve(__dirname, '${outputDirAnswer.outputDir}')`; } }) - .then(() => + .then((): Promise<{}> => this.prompt([ List("langType", "Will you use one of the below JS solutions?", [ "ES6", @@ -203,11 +199,11 @@ export default class InitGenerator extends Generator { ]), ) .then((langTypeAnswer: { - langType: boolean; - }) => { + langType: string; + }): void => { langQuestionHandler(this, langTypeAnswer.langType); }) - .then(() => + .then((): Promise<{}> => this.prompt([ List("stylingType", "Will you use one of the below CSS solutions?", [ "No", @@ -219,10 +215,10 @@ export default class InitGenerator extends Generator { ])) .then((stylingTypeAnswer: { stylingType: string; - }) => - ({ ExtractUseProps, regExpForStyles } = styleQuestionHandler(self, stylingTypeAnswer.stylingType)), - ) - .then((): Promise => { + }): void => { + ({ ExtractUseProps, regExpForStyles } = styleQuestionHandler(self, stylingTypeAnswer.stylingType)); + }) + .then((): Promise<{}> | void => { if (this.isProd) { // Ask if the user wants to use extractPlugin return this.prompt([ @@ -235,7 +231,7 @@ export default class InitGenerator extends Generator { }) .then((useExtractPluginAnswer: { useExtractPlugin: string; - }) => { + }): void => { if (regExpForStyles) { if (this.isProd) { const cssBundleName: string = useExtractPluginAnswer.useExtractPlugin; @@ -246,12 +242,12 @@ export default class InitGenerator extends Generator { "\n", ); if (cssBundleName.length !== 0) { - this.configuration.config.webpackOptions.plugins.push( + (this.configuration.config.webpackOptions.plugins as string[]).push( // TODO: use [contenthash] after it is supported `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })`, ); } else { - this.configuration.config.webpackOptions.plugins.push( + (this.configuration.config.webpackOptions.plugins as string[]).push( "new MiniCssExtractPlugin({ filename:'style.css' })", ); } @@ -273,7 +269,7 @@ export default class InitGenerator extends Generator { }); } - public installPlugins() { + public installPlugins(): void { const packager = getPackageManager(); const opts: { dev?: boolean, @@ -292,7 +288,7 @@ export default class InitGenerator extends Generator { this.fs.extendJSON(this.destinationPath("package.json"), require(packageJsonTemplatePath)(this.isProd)); const entry = this.configuration.config.webpackOptions.entry; - const generateEntryFile = (entryPath: string, name: string) => { + const generateEntryFile = (entryPath: string, name: string): void => { entryPath = entryPath.replace(/'/g, ""); this.fs.copyTpl( path.resolve(__dirname, "./templates/index.js"), @@ -304,7 +300,7 @@ export default class InitGenerator extends Generator { if ( typeof entry === "string" ) { generateEntryFile(entry, "your main file!"); } else if (typeof entry === "object") { - Object.keys(entry).forEach((name) => + Object.keys(entry).forEach((name: string): void => generateEntryFile(entry[name], `${name} main file!`), ); } diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts index 6feca520301..4e3798a2a29 100644 --- a/packages/generators/utils/entry.ts +++ b/packages/generators/utils/entry.ts @@ -16,7 +16,10 @@ interface CustomGenerator extends Generator { * @returns {Object} An Object that holds the answers given by the user, later used to scaffold */ -export default function entry(self: CustomGenerator, multiEntries: boolean): Promise<{}> { +export default function entry( + self: CustomGenerator, + multiEntries: boolean, +): Promise<{}> { let entryIdentifiers: string[]; let result: Promise<{}>; if (multiEntries) { @@ -26,8 +29,8 @@ export default function entry(self: CustomGenerator, multiEntries: boolean): Pro "multipleEntries", "How do you want to name your bundles? (separated by comma)", validate, - "pageOne, pageTwo", - ), + "pageOne, pageTwo" + ) ]) .then( (multipleEntriesAnswer: { multipleEntries: string }): Promise => { @@ -53,7 +56,7 @@ export default function entry(self: CustomGenerator, multiEntries: boolean): Pro !n[val].includes("path") && !n[val].includes("process") ) { - n[val] = `\'${n[val].replace(/"|'/g, "").concat(".js")}\'`; + n[val] = `\'./${n[val].replace(/"|'/g, "").concat(".js")}\'`; } webpackEntryPoint[val] = n[val]; } @@ -66,59 +69,37 @@ export default function entry(self: CustomGenerator, multiEntries: boolean): Pro ); }, Promise.resolve()); } + return forEachPromise( entryIdentifiers, (entryProp: string): Promise => self.prompt([ InputValidate( `${entryProp}`, - `What is the location of "${entryProp}"? [example: ./src/${entryProp}]`, - validate - ) - ]) - ).then( - (entryPropAnswer: object): object => { - Object.keys(entryPropAnswer).forEach( - (val: string): void => { - if ( - entryPropAnswer[val].charAt(0) !== "(" && - entryPropAnswer[val].charAt(0) !== "[" && - !entryPropAnswer[val].includes("function") && - !entryPropAnswer[val].includes("path") && - !entryPropAnswer[val].includes("process") - ) { - n[val] = `\'./${n[val].replace(/"|'/g, "").concat(".js")}\'`; + `What is the location of "${entryProp}"?`, + validate, + `src/${entryProp}`, + ), + ])) + .then( + (entryPropAnswer: object): object => { + Object.keys(entryPropAnswer).forEach( + (val: string): void => { + if ( + entryPropAnswer[val].charAt(0) !== "(" && + entryPropAnswer[val].charAt(0) !== "[" && + !entryPropAnswer[val].includes("function") && + !entryPropAnswer[val].includes("path") && + !entryPropAnswer[val].includes("process") + ) { + entryPropAnswer[val] = `\'./${entryPropAnswer[val].replace(/"|'/g, "").concat(".js")}\'`; + } + webpackEntryPoint[val] = entryPropAnswer[val]; } - webpackEntryPoint[val] = n[val]; - }); - } else { - n = {}; + ); + return webpackEntryPoint; } - return fn(trimmedProp); - }); - }, Promise.resolve()); - } - return forEachPromise(entryIdentifiers, (entryProp: string): Promise<{} | void> => - self.prompt([ - InputValidate( - `${entryProp}`, - `Which will be the entry point of "${entryProp}"?`, - validate, - `src/${entryProp}`, - ), - ]), - ).then((entryPropAnswer: object): object => { - Object.keys(entryPropAnswer).forEach((val: string): void => { - if ( - entryPropAnswer[val].charAt(0) !== "(" && - entryPropAnswer[val].charAt(0) !== "[" && - !entryPropAnswer[val].includes("function") && - !entryPropAnswer[val].includes("path") && - !entryPropAnswer[val].includes("process") - ) { - entryPropAnswer[val] = `\'./${entryPropAnswer[val].replace(/"|'/g, "").concat(".js")}\'`; - } - ); + ); } ); } else { @@ -128,15 +109,16 @@ export default function entry(self: CustomGenerator, multiEntries: boolean): Pro "singularEntry", "Which will be your application entry point?", "src/index", - ), + ) ]) - .then((singularEntryAnswer: { - singularEntry: string, - }): string => { - let { singularEntry } = singularEntryAnswer; - singularEntry = `\'./${singularEntry.replace(/"|'/g, "").concat(".js")}\'`; - if (singularEntry.length <= 0) { - self.usingDefaults = true; + .then( + (singularEntryAnswer: { singularEntry: string }): string => { + let { singularEntry } = singularEntryAnswer; + singularEntry = `\'./${singularEntry.replace(/"|'/g, "").concat(".js")}\'`; + if (singularEntry.length <= 0) { + self.usingDefaults = true; + } + return singularEntry; } ); } diff --git a/packages/generators/utils/language.ts b/packages/generators/utils/language.ts index a71f1b9f4b5..a722eeeff53 100644 --- a/packages/generators/utils/language.ts +++ b/packages/generators/utils/language.ts @@ -16,6 +16,20 @@ interface ModuleRule extends Object { type Preset = string | object; +function updateEntryExt(self, newExt: string): void { + const jsEntryOption = self.configuration.config.webpackOptions.entry; + const jsExtension = new RegExp("\.js(?!.*\.js)"); + let tsEntryOption = {}; + if (typeof jsEntryOption === "string") { + tsEntryOption = jsEntryOption.replace(jsExtension, newExt); + } else if (typeof jsEntryOption === "object") { + Object.keys(jsEntryOption).forEach((entry: string): void => { + tsEntryOption[entry] = jsEntryOption[entry].replace(jsExtension, newExt); + }); + } + self.configuration.config.webpackOptions.entry = tsEntryOption; +} + /** * * Returns an module.rule object that has the babel loader if invoked @@ -24,8 +38,6 @@ type Preset = string | object; */ export function getBabelLoader(): ModuleRule { return { - // TODO migrate tslint - // tslint:disable: object-literal-sort-keys test: "/\.js$/", include: ["path.resolve(__dirname, 'src')"], loader: "'babel-loader'", @@ -40,23 +52,19 @@ export function getBabelLoader(): ModuleRule { ] ] }, - // tslint:enable: object-literal-sort-keys }; } export function getTypescriptLoader(): ModuleRule { return { - // TODO migrate tslint - // tslint:disable: object-literal-sort-keys test: "/\.tsx?$/", loader: "'ts-loader'", include: ["path.resolve(__dirname, 'src')"], exclude: ["/node_modules/"], - // tslint:enable: object-literal-sort-keys }; } -export default function language(self, langType) { +export default function language(self, langType: string): void { switch (langType) { case LangType.ES6: self.dependencies.push( @@ -81,18 +89,7 @@ export default function language(self, langType) { extensions: [ "'.tsx'", "'.ts'", "'.js'" ], }; - // Update the entry files extensions to .ts - const jsEntryOption = self.configuration.config.webpackOptions.entry; - const jsExtension = new RegExp("\.js(?!.*\.js)"); - let tsEntryOption = {}; - if (typeof jsEntryOption === "string") { - tsEntryOption = jsEntryOption.replace(jsExtension, ".ts"); - } else if (typeof jsEntryOption === "object") { - Object.keys(jsEntryOption).forEach((entry) => { - tsEntryOption[entry] = jsEntryOption[entry].replace(jsExtension, ".ts"); - }); - } - self.configuration.config.webpackOptions.entry = tsEntryOption; + updateEntryExt(self, ".ts"); break; } } diff --git a/packages/generators/utils/style.ts b/packages/generators/utils/style.ts index cc07306d3c0..d05a5241a75 100644 --- a/packages/generators/utils/style.ts +++ b/packages/generators/utils/style.ts @@ -7,7 +7,7 @@ export enum StylingType { PostCSS = "PostCSS", } -export enum Loader { +export enum LoaderName { CSS = "css-loader", SASS = "sass-loader", STYLE = "style-loader", @@ -22,7 +22,7 @@ export enum StyleRegex { PostCSS = "/\.css$/", } -export interface ILoader { +export interface Loader { loader: string; options?: { importLoaders?: number; @@ -31,29 +31,32 @@ export interface ILoader { }; } -export default function style(self, stylingType) { - const ExtractUseProps: ILoader[] = []; - let regExpForStyles = null; +export default function style(self, stylingType: string): { + ExtractUseProps: Loader[], + regExpForStyles: StyleRegex, +} { + const ExtractUseProps: Loader[] = []; + let regExpForStyles: StyleRegex = null; switch (stylingType) { case StylingType.CSS: regExpForStyles = StyleRegex.CSS; self.dependencies.push( - Loader.CSS, + LoaderName.CSS, ); if (!self.isProd) { self.dependencies.push( - Loader.STYLE, + LoaderName.STYLE, ); ExtractUseProps.push( { - loader: `"${Loader.STYLE}"`, + loader: `"${LoaderName.STYLE}"`, }, ); } ExtractUseProps.push({ - loader: `"${Loader.CSS}"`, + loader: `"${LoaderName.CSS}"`, options: { sourceMap: true, }, @@ -65,28 +68,28 @@ export default function style(self, stylingType) { self.dependencies.push( "node-sass", - Loader.SASS, - Loader.CSS, + LoaderName.SASS, + LoaderName.CSS, ); if (!self.isProd) { self.dependencies.push( - Loader.STYLE, + LoaderName.STYLE, ); ExtractUseProps.push( { - loader: `"${Loader.STYLE}"`, + loader: `"${LoaderName.STYLE}"`, }, ); } ExtractUseProps.push( { - loader: `"${Loader.CSS}"`, + loader: `"${LoaderName.CSS}"`, options: { sourceMap: true, }, }, { - loader: `"${Loader.SASS}"`, + loader: `"${LoaderName.SASS}"`, options: { sourceMap: true, }, @@ -99,28 +102,28 @@ export default function style(self, stylingType) { self.dependencies.push( "less", - Loader.LESS, - Loader.CSS, + LoaderName.LESS, + LoaderName.CSS, ); if (!self.isProd) { self.dependencies.push( - Loader.STYLE, + LoaderName.STYLE, ); ExtractUseProps.push( { - loader: `"${Loader.STYLE}"`, + loader: `"${LoaderName.STYLE}"`, }, ); } ExtractUseProps.push( { - loader: `"${Loader.CSS}"`, + loader: `"${LoaderName.CSS}"`, options: { sourceMap: true, }, }, { - loader: `"${Loader.LESS}"`, + loader: `"${LoaderName.LESS}"`, options: { sourceMap: true, }, @@ -141,29 +144,29 @@ export default function style(self, stylingType) { self.dependencies.push( "precss", "autoprefixer", - Loader.CSS, - Loader.POSTCSS, + LoaderName.CSS, + LoaderName.POSTCSS, ); if (!self.isProd) { self.dependencies.push( - Loader.STYLE, + LoaderName.STYLE, ); ExtractUseProps.push( { - loader: `"${Loader.STYLE}"`, + loader: `"${LoaderName.STYLE}"`, }, ); } ExtractUseProps.push( { - loader: `"${Loader.CSS}"`, + loader: `"${LoaderName.CSS}"`, options: { importLoaders: 1, sourceMap: true, }, }, { - loader: `"${Loader.POSTCSS}"`, + loader: `"${LoaderName.POSTCSS}"`, options: { plugins: `function () { return [ diff --git a/packages/utils/scaffold.ts b/packages/utils/scaffold.ts index 3fc8bf20c0f..7f0eb1acd48 100644 --- a/packages/utils/scaffold.ts +++ b/packages/utils/scaffold.ts @@ -70,30 +70,26 @@ export default function runTransform(transformConfig: TransformConfig, action: s return astTransform(j, ast, f, config[f] as any, transformAction); } return astTransform(j, ast, f, config.webpackOptions[f], transformAction); - } - ) - .then( - (): void | PromiseLike => { - let configurationName: string; - if (!config.configName) { - configurationName = "webpack.config.js"; - } else { - configurationName = "webpack." + config.configName + ".js"; - } - - const projectRoot = findProjectRoot(); - const outputPath: string = initActionNotDefined - ? transformConfig.configPath - : path.join(projectRoot || process.cwd(), configurationName); - const source: string = ast.toSource({ - quote: "single", + }) + .then((): void | PromiseLike => { + let configurationName: string; + if (!config.configName) { + configurationName = "webpack.config.js"; + } else { + configurationName = "webpack." + config.configName + ".js"; + } + const projectRoot = findProjectRoot(); + const outputPath: string = initActionNotDefined + ? transformConfig.configPath + : path.join(projectRoot || process.cwd(), configurationName); + const source: string = ast.toSource({ + quote: "single", + }); + runPrettier(outputPath, source); + }) + .catch((err: Error): void => { + console.error(err.message ? err.message : err); }); - runPrettier(outputPath, source); - - }) - .catch((err: IError) => { - console.error(err.message ? err.message : err); - }); }); let successMessage: string = chalk.green(`Congratulations! Your new webpack configuration file has been created!\n\n`) + From 1b07d2bcf6fca415d0924f1ccd59f9bf8d202a03 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Tue, 23 Apr 2019 22:40:40 +0200 Subject: [PATCH 26/50] misc(init): refactor with async/await --- packages/generators/init-generator.ts | 209 ++++++++++++-------------- packages/generators/utils/entry.ts | 2 +- 2 files changed, 98 insertions(+), 113 deletions(-) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index a40c0bc9d12..2958f5cf0b2 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -12,6 +12,7 @@ import entryQuestions from "./utils/entry"; import langQuestionHandler from "./utils/language"; import styleQuestionHandler, { Loader, StylingType } from "./utils/style"; import tooltip from "./utils/tooltip"; +import { type } from "os"; /** * @@ -126,7 +127,7 @@ export default class InitGenerator extends Generator { } // eslint-disable-next-line - public prompting(): any { + public async prompting() { const done: () => {} = this.async(); const self: this = this; let regExpForStyles: string; @@ -142,69 +143,61 @@ export default class InitGenerator extends Generator { `Alternatively, run "webpack(-cli) --help" for usage info\n\n`, ); - return this.prompt([ - Confirm("multiEntries", "Will your application have multiple bundles?", false), - ]) - .then((multiEntriesAnswer: { - multiEntries: boolean, - }): Promise<{}> => - entryQuestions(self, multiEntriesAnswer.multiEntries), - ) - .then((entryOption: object | string): void => { - if (typeof entryOption === "string" && entryOption.length > 0) { - this.configuration.config.webpackOptions.entry = `${entryOption}`; - } else if (typeof entryOption === "object") { - this.configuration.config.webpackOptions.entry = entryOption; - } - }) - .then((): Promise<{}> => - this.prompt([ - Input( - "outputDir", - "In which folder do you want to store your generated bundles?", - "dist", - ), - ]), - ) - .then((outputDirAnswer: { - outputDir: string; - }): void => { - // As entry is not required anymore and we dont set it to be an empty string or """"" - // it can be undefined so falsy check is enough (vs entry.length); - if ( - !this.configuration.config.webpackOptions.entry && - !this.usingDefaults - ) { - this.configuration.config.webpackOptions.output = { - chunkFilename: "'[name].[chunkhash].js'", - filename: "'[name].[chunkhash].js'", - }; - } else if (!this.usingDefaults) { - this.configuration.config.webpackOptions.output = { - filename: "'[name].[chunkhash].js'", - }; - } - if (!this.usingDefaults && outputDirAnswer.outputDir.length) { - this.configuration.config.webpackOptions.output.path = - `path.resolve(__dirname, '${outputDirAnswer.outputDir}')`; - } - }) - .then((): Promise<{}> => - this.prompt([ - List("langType", "Will you use one of the below JS solutions?", [ - "ES6", - "Typescript", - "No", - ]), + const { multiEntries }: { multiEntries: boolean } = await this.prompt([ + Confirm( + "multiEntries", + "Will your application have multiple bundles?", + false + ), + ]); + + const entryOption: string | object = await entryQuestions(self, multiEntries); + + if (typeof entryOption === "string" && entryOption.length > 0) { + this.configuration.config.webpackOptions.entry = `${entryOption}`; + } else if (typeof entryOption === "object") { + this.configuration.config.webpackOptions.entry = entryOption; + } + + const { outputDir }: { outputDir: string } = await this.prompt([ + Input( + "outputDir", + "In which folder do you want to store your generated bundles?", + "dist", + ), + ]); + + // As entry is not required anymore and we dont set it to be an empty string or """"" + // it can be undefined so falsy check is enough (vs entry.length); + if ( + !this.configuration.config.webpackOptions.entry && + !this.usingDefaults + ) { + this.configuration.config.webpackOptions.output = { + chunkFilename: "'[name].[chunkhash].js'", + filename: "'[name].[chunkhash].js'", + }; + } else if (!this.usingDefaults) { + this.configuration.config.webpackOptions.output = { + filename: "'[name].[chunkhash].js'", + }; + } + if (!this.usingDefaults && outputDir.length) { + this.configuration.config.webpackOptions.output.path = + `path.resolve(__dirname, '${outputDir}')`; + } + + const { langType }: { langType: string } = await this.prompt([ + List("langType", "Will you use one of the below JS solutions?", [ + "ES6", + "Typescript", + "No", ]), - ) - .then((langTypeAnswer: { - langType: string; - }): void => { - langQuestionHandler(this, langTypeAnswer.langType); - }) - .then((): Promise<{}> => - this.prompt([ + ]); + + langQuestionHandler(this, langType); + + const { stylingType }: { stylingType: string } = await this.prompt([ List("stylingType", "Will you use one of the below CSS solutions?", [ "No", StylingType.CSS, @@ -212,61 +205,53 @@ export default class InitGenerator extends Generator { StylingType.LESS, StylingType.PostCSS, ]), - ])) - .then((stylingTypeAnswer: { - stylingType: string; - }): void => { - ({ ExtractUseProps, regExpForStyles } = styleQuestionHandler(self, stylingTypeAnswer.stylingType)); - }) - .then((): Promise<{}> | void => { + ]); + + ({ ExtractUseProps, regExpForStyles } = styleQuestionHandler(self, stylingType)); + + if (this.isProd) { + // Ask if the user wants to use extractPlugin + const { useExtractPlugin }: { useExtractPlugin: string } = await this.prompt([ + Input( + "useExtractPlugin", + "If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)", + ), + ]); + + if (regExpForStyles) { if (this.isProd) { - // Ask if the user wants to use extractPlugin - return this.prompt([ - Input( - "useExtractPlugin", - "If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)", - ), - ]); - } - }) - .then((useExtractPluginAnswer: { - useExtractPlugin: string; - }): void => { - if (regExpForStyles) { - if (this.isProd) { - const cssBundleName: string = useExtractPluginAnswer.useExtractPlugin; - this.dependencies.push("mini-css-extract-plugin"); - this.configuration.config.topScope.push( - tooltip.cssPlugin(), - "const MiniCssExtractPlugin = require('mini-css-extract-plugin');", - "\n", + const cssBundleName: string = useExtractPlugin; + this.dependencies.push("mini-css-extract-plugin"); + this.configuration.config.topScope.push( + tooltip.cssPlugin(), + "const MiniCssExtractPlugin = require('mini-css-extract-plugin');", + "\n", + ); + if (cssBundleName.length !== 0) { + (this.configuration.config.webpackOptions.plugins as string[]).push( + // TODO: use [contenthash] after it is supported + `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })`, + ); + } else { + (this.configuration.config.webpackOptions.plugins as string[]).push( + "new MiniCssExtractPlugin({ filename:'style.css' })", ); - if (cssBundleName.length !== 0) { - (this.configuration.config.webpackOptions.plugins as string[]).push( - // TODO: use [contenthash] after it is supported - `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })`, - ); - } else { - (this.configuration.config.webpackOptions.plugins as string[]).push( - "new MiniCssExtractPlugin({ filename:'style.css' })", - ); - } - - ExtractUseProps.unshift({ - loader: "MiniCssExtractPlugin.loader", - }); } - this.configuration.config.webpackOptions.module.rules.push( - { - test: regExpForStyles, - use: ExtractUseProps, - }, - ); + ExtractUseProps.unshift({ + loader: "MiniCssExtractPlugin.loader", + }); } - done(); - }); + this.configuration.config.webpackOptions.module.rules.push( + { + test: regExpForStyles, + use: ExtractUseProps, + }, + ); + } + } + done(); } public installPlugins(): void { diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts index 4e3798a2a29..8748abcb1e5 100644 --- a/packages/generators/utils/entry.ts +++ b/packages/generators/utils/entry.ts @@ -19,7 +19,7 @@ interface CustomGenerator extends Generator { export default function entry( self: CustomGenerator, multiEntries: boolean, -): Promise<{}> { +): Promise { let entryIdentifiers: string[]; let result: Promise<{}>; if (multiEntries) { From 263b83c8916200d41c4c681301d1df6f8e08833b Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 26 Apr 2019 22:36:46 +0200 Subject: [PATCH 27/50] fix(generator): generate correct module.rule for babel & ts --- packages/generators/init-generator.ts | 2 - packages/generators/utils/language.ts | 57 +++++++++++++++++++++------ 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 2958f5cf0b2..88bc41604e4 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -12,7 +12,6 @@ import entryQuestions from "./utils/entry"; import langQuestionHandler from "./utils/language"; import styleQuestionHandler, { Loader, StylingType } from "./utils/style"; import tooltip from "./utils/tooltip"; -import { type } from "os"; /** * @@ -126,7 +125,6 @@ export default class InitGenerator extends Generator { } } - // eslint-disable-next-line public async prompting() { const done: () => {} = this.async(); const self: this = this; diff --git a/packages/generators/utils/language.ts b/packages/generators/utils/language.ts index a722eeeff53..46883fcf4af 100644 --- a/packages/generators/utils/language.ts +++ b/packages/generators/utils/language.ts @@ -16,30 +16,53 @@ interface ModuleRule extends Object { type Preset = string | object; +const replaceExt = (path: string, ext: string): string => + path.substr(0, path.lastIndexOf(".")) + `${ext}'`; + function updateEntryExt(self, newExt: string): void { const jsEntryOption = self.configuration.config.webpackOptions.entry; - const jsExtension = new RegExp("\.js(?!.*\.js)"); let tsEntryOption = {}; if (typeof jsEntryOption === "string") { - tsEntryOption = jsEntryOption.replace(jsExtension, newExt); + tsEntryOption = replaceExt(jsEntryOption, newExt); } else if (typeof jsEntryOption === "object") { Object.keys(jsEntryOption).forEach((entry: string): void => { - tsEntryOption[entry] = jsEntryOption[entry].replace(jsExtension, newExt); + tsEntryOption[entry] = replaceExt(jsEntryOption[entry], newExt); }); } self.configuration.config.webpackOptions.entry = tsEntryOption; } +const getFolder = (path: string): string => + path.replace("'./", "").split("/").slice(0, -1).join("/"); + +function getEntryFolders(self): string[] { + const entryOption = self.configuration.config.webpackOptions.entry; + let entryFolders = {}; + if (typeof entryOption === "string") { + const folder = getFolder(entryOption); + if (folder.length > 0) entryFolders[folder] = true; + } else if (typeof entryOption === "object") { + Object.keys(entryOption).forEach((entry: string): void => { + const folder = getFolder(entryOption[entry]); + if (folder.length > 0) entryFolders[folder] = true; + }); + } + return Object.keys(entryFolders); +} + /** * - * Returns an module.rule object that has the babel loader if invoked - * - * @returns {Function} A callable function that adds the babel-loader with env preset + * Returns an module.rule object for the babel loader + * @param {string[]} includeFolders An array of folders to include + * @returns {ModuleRule} A configuration containing the babel-loader with env preset */ -export function getBabelLoader(): ModuleRule { +export function getBabelLoader(includeFolders: string[]): ModuleRule { + const include = includeFolders.map((folder: string) => + `path.resolve(__dirname, '${folder}')` + ); return { test: "/\.js$/", - include: ["path.resolve(__dirname, 'src')"], + include, loader: "'babel-loader'", options: { plugins: ["'syntax-dynamic-import'"], @@ -55,16 +78,26 @@ export function getBabelLoader(): ModuleRule { }; } -export function getTypescriptLoader(): ModuleRule { +/** + * + * Returns an module.rule object for the typescript loader + * @param {string[]} includeFolders An array of folders to include + * @returns {ModuleRule} A configuration containing the ts-loader + */ +export function getTypescriptLoader(includeFolders: string[]): ModuleRule { + const include = includeFolders.map((folder: string) => + `path.resolve(__dirname, '${folder}')` + ); return { test: "/\.tsx?$/", loader: "'ts-loader'", - include: ["path.resolve(__dirname, 'src')"], + include, exclude: ["/node_modules/"], }; } export default function language(self, langType: string): void { + const entryFolders = getEntryFolders(self); switch (langType) { case LangType.ES6: self.dependencies.push( @@ -73,7 +106,7 @@ export default function language(self, langType: string): void { "@babel/preset-env", ); self.configuration.config.webpackOptions.module.rules.push( - getBabelLoader(), + getBabelLoader(entryFolders), ); break; @@ -83,7 +116,7 @@ export default function language(self, langType: string): void { "ts-loader", ); self.configuration.config.webpackOptions.module.rules.push( - getTypescriptLoader(), + getTypescriptLoader(entryFolders), ); self.configuration.config.webpackOptions.resolve = { extensions: [ "'.tsx'", "'.ts'", "'.js'" ], From 25ab7e67b72d4b2b747198adeee8bec2efb75db4 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 26 Apr 2019 22:54:40 +0200 Subject: [PATCH 28/50] feat(init): generate tsconfig --- packages/generators/init-generator.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 88bc41604e4..29428aed471 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -9,7 +9,7 @@ import { Confirm, Input, List } from "@webpack-cli/webpack-scaffold"; import { WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; -import langQuestionHandler from "./utils/language"; +import langQuestionHandler, { LangType } from "./utils/language"; import styleQuestionHandler, { Loader, StylingType } from "./utils/style"; import tooltip from "./utils/tooltip"; @@ -33,6 +33,7 @@ export default class InitGenerator extends Generator { webpackOptions?: WebpackOptions; }; }; + private langType: string; public constructor(args, opts) { super(args, opts); @@ -187,13 +188,14 @@ export default class InitGenerator extends Generator { const { langType }: { langType: string } = await this.prompt([ List("langType", "Will you use one of the below JS solutions?", [ - "ES6", - "Typescript", + LangType.ES6, + LangType.Typescript, "No", ]), ]); langQuestionHandler(this, langType); + this.langType = langType; const { stylingType }: { stylingType: string } = await this.prompt([ List("stylingType", "Will you use one of the below CSS solutions?", [ @@ -270,7 +272,6 @@ export default class InitGenerator extends Generator { const packageJsonTemplatePath = "./templates/package.json.js"; this.fs.extendJSON(this.destinationPath("package.json"), require(packageJsonTemplatePath)(this.isProd)); - const entry = this.configuration.config.webpackOptions.entry; const generateEntryFile = (entryPath: string, name: string): void => { entryPath = entryPath.replace(/'/g, ""); this.fs.copyTpl( @@ -280,6 +281,8 @@ export default class InitGenerator extends Generator { ); }; + // Generate entry file/files + const entry = this.configuration.config.webpackOptions.entry; if ( typeof entry === "string" ) { generateEntryFile(entry, "your main file!"); } else if (typeof entry === "object") { @@ -287,5 +290,10 @@ export default class InitGenerator extends Generator { generateEntryFile(entry[name], `${name} main file!`), ); } + + if (this.langType === LangType.Typescript) { + const tsConfigTemplatePath = "./templates/tsconfig.json.js"; + this.fs.extendJSON(this.destinationPath("tsconfig.json"), require(tsConfigTemplatePath)); + } } } From c090b17c4afc3bf12b31ee5dc017da95fdb8f344 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 26 Apr 2019 23:09:08 +0200 Subject: [PATCH 29/50] feat(init): generate README --- packages/generators/init-generator.ts | 7 +++++++ packages/generators/templates/README.md | 15 +++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 packages/generators/templates/README.md diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 29428aed471..ebe49ee6c13 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -291,6 +291,13 @@ export default class InitGenerator extends Generator { ); } + // Generate README + this.fs.copyTpl( + path.resolve(__dirname, "./templates/README.md"), + this.destinationPath("README.md") + ); + + // Genrate tsconfig if (this.langType === LangType.Typescript) { const tsConfigTemplatePath = "./templates/tsconfig.json.js"; this.fs.extendJSON(this.destinationPath("tsconfig.json"), require(tsConfigTemplatePath)); diff --git a/packages/generators/templates/README.md b/packages/generators/templates/README.md new file mode 100644 index 00000000000..92053bba6ec --- /dev/null +++ b/packages/generators/templates/README.md @@ -0,0 +1,15 @@ +# 🚀 Welcome to your new awesome project! + +This project has been created using **webpack scaffold**, you can now run + +``` +npm run build +``` + +or + +``` +yarn build +``` + +to bundle your application From 8b6d47bfaa0d1a921e7c6af4f60ab9666a3eeb43 Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Fri, 26 Apr 2019 23:22:03 +0200 Subject: [PATCH 30/50] docs(utils): update prettier --- packages/utils/package-lock.json | 6 +++--- packages/utils/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/utils/package-lock.json b/packages/utils/package-lock.json index 313aec15a47..efe1c450fdd 100644 --- a/packages/utils/package-lock.json +++ b/packages/utils/package-lock.json @@ -5665,9 +5665,9 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" }, "prettier": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz", - "integrity": "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==" + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz", + "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==" }, "pretty-bytes": { "version": "5.1.0", diff --git a/packages/utils/package.json b/packages/utils/package.json index fc26be79aa3..f234ab8f8d1 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -19,7 +19,7 @@ "jscodeshift": "^0.5.1", "log-symbols": "^2.2.0", "p-each-series": "^1.0.0", - "prettier": "^1.15.2", + "prettier": "^1.17.0", "yeoman-environment": "^2.3.4", "yeoman-generator": "^3.1.1" }, From 85ef3e77bf81c20c9cced220d1654f07cebe100c Mon Sep 17 00:00:00 2001 From: Devid Farinelli Date: Fri, 3 May 2019 14:58:58 +0200 Subject: [PATCH 31/50] misc(types): correct types --- packages/generators/init-generator.ts | 17 +++++++++-------- packages/generators/utils/entry.ts | 4 ++-- packages/generators/utils/language.ts | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index ebe49ee6c13..7a4df24f43c 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -1,7 +1,6 @@ import chalk from "chalk"; import * as logSymbols from "log-symbols"; import * as Generator from "yeoman-generator"; -import * as Inquirer from "inquirer"; import * as path from "path"; import { getPackageManager } from "@webpack-cli/utils/package-manager"; @@ -142,7 +141,7 @@ export default class InitGenerator extends Generator { `Alternatively, run "webpack(-cli) --help" for usage info\n\n`, ); - const { multiEntries }: { multiEntries: boolean } = await this.prompt([ + const { multiEntries } = await this.prompt([ Confirm( "multiEntries", "Will your application have multiple bundles?", @@ -150,7 +149,8 @@ export default class InitGenerator extends Generator { ), ]); - const entryOption: string | object = await entryQuestions(self, multiEntries); + // TODO string | object + const entryOption: void | {} = await entryQuestions(self, multiEntries); if (typeof entryOption === "string" && entryOption.length > 0) { this.configuration.config.webpackOptions.entry = `${entryOption}`; @@ -158,7 +158,7 @@ export default class InitGenerator extends Generator { this.configuration.config.webpackOptions.entry = entryOption; } - const { outputDir }: { outputDir: string } = await this.prompt([ + const { outputDir } = await this.prompt([ Input( "outputDir", "In which folder do you want to store your generated bundles?", @@ -186,7 +186,7 @@ export default class InitGenerator extends Generator { `path.resolve(__dirname, '${outputDir}')`; } - const { langType }: { langType: string } = await this.prompt([ + const { langType } = await this.prompt([ List("langType", "Will you use one of the below JS solutions?", [ LangType.ES6, LangType.Typescript, @@ -197,7 +197,7 @@ export default class InitGenerator extends Generator { langQuestionHandler(this, langType); this.langType = langType; - const { stylingType }: { stylingType: string } = await this.prompt([ + const { stylingType } = await this.prompt([ List("stylingType", "Will you use one of the below CSS solutions?", [ "No", StylingType.CSS, @@ -211,7 +211,7 @@ export default class InitGenerator extends Generator { if (this.isProd) { // Ask if the user wants to use extractPlugin - const { useExtractPlugin }: { useExtractPlugin: string } = await this.prompt([ + const { useExtractPlugin } = await this.prompt([ Input( "useExtractPlugin", "If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)", @@ -294,7 +294,8 @@ export default class InitGenerator extends Generator { // Generate README this.fs.copyTpl( path.resolve(__dirname, "./templates/README.md"), - this.destinationPath("README.md") + this.destinationPath("README.md"), + {} ); // Genrate tsconfig diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts index 8748abcb1e5..ea979b4dc94 100644 --- a/packages/generators/utils/entry.ts +++ b/packages/generators/utils/entry.ts @@ -19,9 +19,9 @@ interface CustomGenerator extends Generator { export default function entry( self: CustomGenerator, multiEntries: boolean, -): Promise { +): Promise { let entryIdentifiers: string[]; - let result: Promise<{}>; + let result: Promise; if (multiEntries) { result = self .prompt([ diff --git a/packages/generators/utils/language.ts b/packages/generators/utils/language.ts index 46883fcf4af..266a16c8ccb 100644 --- a/packages/generators/utils/language.ts +++ b/packages/generators/utils/language.ts @@ -57,7 +57,7 @@ function getEntryFolders(self): string[] { * @returns {ModuleRule} A configuration containing the babel-loader with env preset */ export function getBabelLoader(includeFolders: string[]): ModuleRule { - const include = includeFolders.map((folder: string) => + const include = includeFolders.map((folder: string): string => `path.resolve(__dirname, '${folder}')` ); return { @@ -85,7 +85,7 @@ export function getBabelLoader(includeFolders: string[]): ModuleRule { * @returns {ModuleRule} A configuration containing the ts-loader */ export function getTypescriptLoader(includeFolders: string[]): ModuleRule { - const include = includeFolders.map((folder: string) => + const include = includeFolders.map((folder: string): string => `path.resolve(__dirname, '${folder}')` ); return { From a650e0eb8b979e93758496fcf4ff98ff05619766 Mon Sep 17 00:00:00 2001 From: Devid Farinelli Date: Wed, 22 May 2019 16:33:44 +0200 Subject: [PATCH 32/50] misc(init-generator): use webpackOption types, improve test rules --- packages/generators/types/index.ts | 2 +- packages/generators/utils/language.ts | 27 ++++++++------------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/packages/generators/types/index.ts b/packages/generators/types/index.ts index 449dc0cc477..32ed902ab23 100644 --- a/packages/generators/types/index.ts +++ b/packages/generators/types/index.ts @@ -214,7 +214,7 @@ export interface WebpackOptions { }; } -interface Rule { +export interface Rule { enforce?: "pre" | "post"; exclude?: IRuleSetCondition; include?: IRuleSetCondition; diff --git a/packages/generators/utils/language.ts b/packages/generators/utils/language.ts index 266a16c8ccb..7d3c1f901cf 100644 --- a/packages/generators/utils/language.ts +++ b/packages/generators/utils/language.ts @@ -1,21 +1,10 @@ +import { Rule } from "../types"; + export enum LangType { ES6 = "ES6", Typescript = "Typescript", } -interface ModuleRule extends Object { - include?: string[]; - exclude?: string[]; - loader: string; - options?: { - plugins: string[]; - presets: Preset[][]; - }; - test: string; -} - -type Preset = string | object; - const replaceExt = (path: string, ext: string): string => path.substr(0, path.lastIndexOf(".")) + `${ext}'`; @@ -54,14 +43,14 @@ function getEntryFolders(self): string[] { * * Returns an module.rule object for the babel loader * @param {string[]} includeFolders An array of folders to include - * @returns {ModuleRule} A configuration containing the babel-loader with env preset + * @returns {Rule} A configuration containing the babel-loader with env preset */ -export function getBabelLoader(includeFolders: string[]): ModuleRule { +export function getBabelLoader(includeFolders: string[]): Rule { const include = includeFolders.map((folder: string): string => `path.resolve(__dirname, '${folder}')` ); return { - test: "/\.js$/", + test: "/\.(js|jsx)$/", include, loader: "'babel-loader'", options: { @@ -82,14 +71,14 @@ export function getBabelLoader(includeFolders: string[]): ModuleRule { * * Returns an module.rule object for the typescript loader * @param {string[]} includeFolders An array of folders to include - * @returns {ModuleRule} A configuration containing the ts-loader + * @returns {Rule} A configuration containing the ts-loader */ -export function getTypescriptLoader(includeFolders: string[]): ModuleRule { +export function getTypescriptLoader(includeFolders: string[]): Rule { const include = includeFolders.map((folder: string): string => `path.resolve(__dirname, '${folder}')` ); return { - test: "/\.tsx?$/", + test: "/\.(ts|tsx)?$/", loader: "'ts-loader'", include, exclude: ["/node_modules/"], From 782f56c1b3f7cf1899aeeb49e3df67f1fd4c672c Mon Sep 17 00:00:00 2001 From: "devid.farinelli@gmail.com" Date: Tue, 28 May 2019 14:19:38 +0200 Subject: [PATCH 33/50] misc(generators): small text improvements --- packages/generators/utils/entry.ts | 2 +- packages/webpack-scaffold/README.md | 51 +++++++++++++++-------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts index ea979b4dc94..2d29c7dda6b 100644 --- a/packages/generators/utils/entry.ts +++ b/packages/generators/utils/entry.ts @@ -27,7 +27,7 @@ export default function entry( .prompt([ InputValidate( "multipleEntries", - "How do you want to name your bundles? (separated by comma)", + "What do you want to name your bundles? (separated by comma)", validate, "pageOne, pageTwo" ) diff --git a/packages/webpack-scaffold/README.md b/packages/webpack-scaffold/README.md index 33282ca8cf9..2d727cc00bf 100755 --- a/packages/webpack-scaffold/README.md +++ b/packages/webpack-scaffold/README.md @@ -11,20 +11,21 @@ npm i -D webpack-cli @webpack-cli/webpack-scaffold ``` # API -- [parseValue](#parsevalue) -- [createArrowFunction](#createarrowfunction) -- [createRegularFunction](#createregularfunction) -- [createDynamicPromise](#createdynamicpromise) -- [createAssetFilterFunction](#createassetfilterfunction) -- [createExternalFunction](#createexternalfunction) -- [createRequire](#createrequire) -- [Inquirer](#inquirer) - - [List](#list) - - [RawList](#rawlist) - - [CheckList](#checklist) - - [Input](#input) - - [InputValidate](#inputvalidate) - - [Confirm](#confirm) + +- [parseValue](#parsevalue) +- [createArrowFunction](#createarrowfunction) +- [createRegularFunction](#createregularfunction) +- [createDynamicPromise](#createdynamicpromise) +- [createAssetFilterFunction](#createassetfilterfunction) +- [createExternalFunction](#createexternalfunction) +- [createRequire](#createrequire) +- [Inquirer](#inquirer) + - [List](#list) + - [RawList](#rawlist) + - [CheckList](#checklist) + - [Input](#input) + - [InputValidate](#inputvalidate) + - [Confirm](#confirm) ## parseValue @@ -175,7 +176,7 @@ Creates an Input from Inquirer ```js const Input = require("@webpack-cli/webpack-scaffold").Input; -Input('entry', 'what is your entry point?', 'src/index') +Input("entry", "what is your entry point?", "src/index"); ``` ### InputValidate @@ -185,16 +186,16 @@ Param: `name, message, [validate, default]` Creates an Input from Inquirer ```js -const InputValidate = require('@webpack-cli/webpack-scaffold').InputValidate; - -const validation = (value) => { - if(value.length > 4) { - return true; - } else { - return 'Wow, that was short!' - } -} -InputValidate('entry', 'what is your entry point?', validation, 'src/index') +const InputValidate = require("@webpack-cli/webpack-scaffold").InputValidate; + +const validation = value => { + if (value.length > 4) { + return true; + } else { + return "The entry point must be longer than 4, try again"; + } +}; +InputValidate("entry", "what is your entry point?", validation, "src/index"); ``` ### Confirm From 90f397c7f136eda23969d00ea95d008e89ee580c Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Wed, 29 May 2019 10:00:06 +0200 Subject: [PATCH 34/50] chore: revise version support --- SECURITY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index ef1676b50d2..3eb4961763c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -8,8 +8,8 @@ webpack CLI is currently supporting webpack v4 and webpack v5. Security fixes ar | webpack version | webpack-cli version | Supported | | --------------- | ----------------------------- | ------------------ | -| 4.x.0 | ^3.1.2 | :white_check_mark: | -| 4.0.x | ^3.1.2 | :white_check_mark: | +| > 4.20.0 | ^3.1.2 | :white_check_mark: | +| 4.20.x | ^3.1.2 | :white_check_mark: | | 5.x.0 | ^3.1.2 | :white_check_mark: | | 5.0.x | ^3.1.2 | :white_check_mark: | | < 4.x.x | (CLI included in webpack < 4) | :x: | From 9cdc3570df687afd66eabe722e644e6537b8fc0b Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Wed, 29 May 2019 11:08:44 +0200 Subject: [PATCH 35/50] chore: revise SECURITY.md Co-Authored-By: Emanuele --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 3eb4961763c..833651fcd0b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -8,7 +8,7 @@ webpack CLI is currently supporting webpack v4 and webpack v5. Security fixes ar | webpack version | webpack-cli version | Supported | | --------------- | ----------------------------- | ------------------ | -| > 4.20.0 | ^3.1.2 | :white_check_mark: | +| >= 4.20.x | ^3.1.2 | :white_check_mark: | | 4.20.x | ^3.1.2 | :white_check_mark: | | 5.x.0 | ^3.1.2 | :white_check_mark: | | 5.0.x | ^3.1.2 | :white_check_mark: | From 2a9e3048bc5ed3cff37dd8ad57eb1e36aafbbcc7 Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Wed, 29 May 2019 11:08:54 +0200 Subject: [PATCH 36/50] chore: revise SECURITY.md Co-Authored-By: Emanuele --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 833651fcd0b..c54aedcf910 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -9,7 +9,7 @@ webpack CLI is currently supporting webpack v4 and webpack v5. Security fixes ar | webpack version | webpack-cli version | Supported | | --------------- | ----------------------------- | ------------------ | | >= 4.20.x | ^3.1.2 | :white_check_mark: | -| 4.20.x | ^3.1.2 | :white_check_mark: | +| <= 4.19.x | ^3.1.1 | :white_check_mark: | | 5.x.0 | ^3.1.2 | :white_check_mark: | | 5.0.x | ^3.1.2 | :white_check_mark: | | < 4.x.x | (CLI included in webpack < 4) | :x: | From 376dcbd8ca8c3d6121f5d0e4fe5b0b65f5dcfe86 Mon Sep 17 00:00:00 2001 From: Devid Farinelli Date: Wed, 29 May 2019 16:01:58 +0200 Subject: [PATCH 37/50] misc(generators): refactor --- packages/generators/init-generator.ts | 37 +++---------------- .../utils/{language.ts => languageSupport.ts} | 0 .../utils/{style.ts => styleSupport.ts} | 0 packages/generators/utils/webpackConfig.ts | 32 ++++++++++++++++ packages/webpack-scaffold/README.md | 2 +- 5 files changed, 38 insertions(+), 33 deletions(-) rename packages/generators/utils/{language.ts => languageSupport.ts} (100%) rename packages/generators/utils/{style.ts => styleSupport.ts} (100%) create mode 100644 packages/generators/utils/webpackConfig.ts diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 7a4df24f43c..a2733828d8b 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -6,10 +6,11 @@ import * as path from "path"; import { getPackageManager } from "@webpack-cli/utils/package-manager"; import { Confirm, Input, List } from "@webpack-cli/webpack-scaffold"; +import { getDefaultOptimization } from "./utils/webpackConfig"; import { WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; -import langQuestionHandler, { LangType } from "./utils/language"; -import styleQuestionHandler, { Loader, StylingType } from "./utils/style"; +import langQuestionHandler, { LangType } from "./utils/languageSupport"; +import styleQuestionHandler, { Loader, StylingType } from "./utils/styleSupport"; import tooltip from "./utils/tooltip"; /** @@ -87,36 +88,8 @@ export default class InitGenerator extends Generator { "new webpack.ProgressPlugin()", ); - let optimizationObj; - - if (!this.isProd) { - optimizationObj = { - splitChunks: { - chunks: "'all'", - }, - }; - } else { - optimizationObj = { - minimizer: [ - "new TerserPlugin()", - ], - splitChunks: { - cacheGroups: { - vendors: { - priority: -10, - test: "/[\\\\/]node_modules[\\\\/]/", - }, - }, - chunks: "'async'", - minChunks: 1, - minSize: 30000, - // for production name is recommended to be off - name: !this.isProd, - }, - }; - } - - this.configuration.config.webpackOptions.optimization = optimizationObj; + let optimizationConfig = getDefaultOptimization(this.isProd); + this.configuration.config.webpackOptions.optimization = optimizationConfig; if (!this.isProd) { this.configuration.config.webpackOptions.devServer = { diff --git a/packages/generators/utils/language.ts b/packages/generators/utils/languageSupport.ts similarity index 100% rename from packages/generators/utils/language.ts rename to packages/generators/utils/languageSupport.ts diff --git a/packages/generators/utils/style.ts b/packages/generators/utils/styleSupport.ts similarity index 100% rename from packages/generators/utils/style.ts rename to packages/generators/utils/styleSupport.ts diff --git a/packages/generators/utils/webpackConfig.ts b/packages/generators/utils/webpackConfig.ts new file mode 100644 index 00000000000..1fddf5ee84d --- /dev/null +++ b/packages/generators/utils/webpackConfig.ts @@ -0,0 +1,32 @@ +import { WebpackOptions } from '../types'; + +export function getDefaultOptimization(isProd: boolean): WebpackOptions["optimization"] { + let optimizationOptions; + if (isProd) { + optimizationOptions = { + splitChunks: { + chunks: "'all'", + }, + }; + } else { + optimizationOptions = { + minimizer: [ + "new TerserPlugin()", + ], + splitChunks: { + cacheGroups: { + vendors: { + priority: -10, + test: "/[\\\\/]node_modules[\\\\/]/", + }, + }, + chunks: "'async'", + minChunks: 1, + minSize: 30000, + // for production name is recommended to be off + name: !this.isProd, + }, + }; + } + return optimizationOptions; +} \ No newline at end of file diff --git a/packages/webpack-scaffold/README.md b/packages/webpack-scaffold/README.md index 2d727cc00bf..5c430fe9495 100755 --- a/packages/webpack-scaffold/README.md +++ b/packages/webpack-scaffold/README.md @@ -192,7 +192,7 @@ const validation = value => { if (value.length > 4) { return true; } else { - return "The entry point must be longer than 4, try again"; + return "Your answer must be longer than 4, try again"; } }; InputValidate("entry", "what is your entry point?", validation, "src/index"); From fb25bd2cb1d72def40e14ba431fe368cd6df6653 Mon Sep 17 00:00:00 2001 From: Devid Farinelli Date: Wed, 29 May 2019 16:03:20 +0200 Subject: [PATCH 38/50] tests(inputvalidate): remove undefined --- .../__tests__/__snapshots__/index.test.ts.snap | 1 - packages/webpack-scaffold/__tests__/index.test.ts | 1 - packages/webpack-scaffold/index.ts | 5 +++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/webpack-scaffold/__tests__/__snapshots__/index.test.ts.snap b/packages/webpack-scaffold/__tests__/__snapshots__/index.test.ts.snap index 0e06b120337..2bb1ed2117f 100755 --- a/packages/webpack-scaffold/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/webpack-scaffold/__tests__/__snapshots__/index.test.ts.snap @@ -2,7 +2,6 @@ exports[`utils Inquirer should make an Input object with validation 1`] = ` Object { - "default": undefined, "message": "what is your plugin?", "name": "plugins", "type": "input", diff --git a/packages/webpack-scaffold/__tests__/index.test.ts b/packages/webpack-scaffold/__tests__/index.test.ts index 586bbcd9a58..2d0ccef8582 100755 --- a/packages/webpack-scaffold/__tests__/index.test.ts +++ b/packages/webpack-scaffold/__tests__/index.test.ts @@ -76,7 +76,6 @@ describe("utils", () => { }); it("should make an Input object", () => { expect(utils.Input("plugins", "what is your plugin?")).toEqual({ - default: undefined, message: "what is your plugin?", name: "plugins", type: "input", diff --git a/packages/webpack-scaffold/index.ts b/packages/webpack-scaffold/index.ts index 6477030c331..8eea29f9f95 100755 --- a/packages/webpack-scaffold/index.ts +++ b/packages/webpack-scaffold/index.ts @@ -92,13 +92,14 @@ export function InputValidate( defaultChoice?: string, ): Generator.Question { - return { - default: defaultChoice, + const input: Generator.Question = { message, name, type: "input", validate: cb }; + if (defaultChoice !== undefined) input.default = defaultChoice; + return input; } export function Confirm(name: string, message: string, defaultChoice: boolean = true): Generator.Question { From dcf44c155c6900f599d09219723ccf7b5b4cf109 Mon Sep 17 00:00:00 2001 From: Devid Farinelli Date: Thu, 30 May 2019 01:44:25 +0200 Subject: [PATCH 39/50] misc(init-generator): small refactor --- packages/webpack-scaffold/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/webpack-scaffold/index.ts b/packages/webpack-scaffold/index.ts index 8eea29f9f95..6c609b8e522 100755 --- a/packages/webpack-scaffold/index.ts +++ b/packages/webpack-scaffold/index.ts @@ -91,14 +91,13 @@ export function InputValidate( cb?: (input: string) => string | boolean, defaultChoice?: string, ): Generator.Question { - const input: Generator.Question = { message, name, type: "input", validate: cb }; - if (defaultChoice !== undefined) input.default = defaultChoice; + if (defaultChoice) input.default = defaultChoice; return input; } From 4872416a5b2859021a2d969db0685227f108e253 Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Thu, 30 May 2019 11:34:56 +0530 Subject: [PATCH 40/50] chore: pluginarrlength for length of the plugin assigned length of the plugin to a constant --- packages/generators/utils/plugins.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/generators/utils/plugins.ts b/packages/generators/utils/plugins.ts index 560eaa35b50..4b60bd3f307 100644 --- a/packages/generators/utils/plugins.ts +++ b/packages/generators/utils/plugins.ts @@ -43,7 +43,8 @@ export const replaceAt = (str: string, index: number, replace: string) : string export const generatePluginName = (rawPluginName: string): string => { let myPluginNameArray : string[]; myPluginNameArray = rawPluginName.split("-"); - for (let i = 0; i < myPluginNameArray.length && myPluginNameArray.length > 1 ; i++) { + const pluginArrLength : number = myPluginNameArray.length; + for (let i = 0; i < pluginArrLength && pluginArrLength > 1 ; i++) { myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); } return myPluginNameArray.join("") From f9716327050dcd6eacae3e6057ec5c72874e57c7 Mon Sep 17 00:00:00 2001 From: Devid Farinelli Date: Thu, 30 May 2019 15:55:59 +0200 Subject: [PATCH 41/50] misc(init-generator): improve readme --- packages/webpack-scaffold/README.md | 33 ++++++++++++++++------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/packages/webpack-scaffold/README.md b/packages/webpack-scaffold/README.md index 5c430fe9495..413c223a51a 100755 --- a/packages/webpack-scaffold/README.md +++ b/packages/webpack-scaffold/README.md @@ -12,20 +12,23 @@ npm i -D webpack-cli @webpack-cli/webpack-scaffold # API -- [parseValue](#parsevalue) -- [createArrowFunction](#createarrowfunction) -- [createRegularFunction](#createregularfunction) -- [createDynamicPromise](#createdynamicpromise) -- [createAssetFilterFunction](#createassetfilterfunction) -- [createExternalFunction](#createexternalfunction) -- [createRequire](#createrequire) -- [Inquirer](#inquirer) - - [List](#list) - - [RawList](#rawlist) - - [CheckList](#checklist) - - [Input](#input) - - [InputValidate](#inputvalidate) - - [Confirm](#confirm) +- [webpack-scaffold](#webpack-scaffold) +- [Installation](#installation) +- [API](#api) + - [parseValue](#parsevalue) + - [createArrowFunction](#createarrowfunction) + - [createRegularFunction](#createregularfunction) + - [createDynamicPromise](#createdynamicpromise) + - [createAssetFilterFunction](#createassetfilterfunction) + - [createExternalFunction](#createexternalfunction) + - [createRequire](#createrequire) + - [Inquirer](#inquirer) + - [List](#list) + - [RawList](#rawlist) + - [CheckList](#checklist) + - [Input](#input) + - [InputValidate](#inputvalidate) + - [Confirm](#confirm) ## parseValue @@ -192,7 +195,7 @@ const validation = value => { if (value.length > 4) { return true; } else { - return "Your answer must be longer than 4, try again"; + return "Your answer must be longer than 4 characters, try again"; } }; InputValidate("entry", "what is your entry point?", validation, "src/index"); From 61697b8ea6a6923f173680b6ea35be743eca0d6f Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Thu, 30 May 2019 17:08:29 +0200 Subject: [PATCH 42/50] fix: json module resolve --- packages/generators/add-generator.ts | 4 ++-- tsconfig.base.json | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/generators/add-generator.ts b/packages/generators/add-generator.ts index 03d8619c895..705afb0da0c 100644 --- a/packages/generators/add-generator.ts +++ b/packages/generators/add-generator.ts @@ -12,8 +12,8 @@ import { AutoComplete, Confirm, Input, List } from "@webpack-cli/webpack-scaffol import { SchemaProperties, WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; import { generatePluginName } from "./utils/plugins"; -import webpackDevServerSchema from "webpack-dev-server/lib/options.json"; -import webpackSchema from "./utils/optionsSchema.json"; +import * as webpackDevServerSchema from "webpack-dev-server/lib/options.json"; +import * as webpackSchema from "./utils/optionsSchema.json"; const PROPS: string[] = Array.from(PROP_TYPES.keys()); diff --git a/tsconfig.base.json b/tsconfig.base.json index d92fae8bb6a..dc260d82933 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -4,7 +4,8 @@ "module": "commonjs", "moduleResolution": "node", "allowSyntheticDefaultImports": true, - "skipLibCheck": true + "skipLibCheck": true, + "resolveJsonModule": true, }, "include": ["packages/**/*.ts"], "exclude": [ From 4e8bc760c622bc1fe6d91c0ae7a366adc2163d3b Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Thu, 30 May 2019 17:44:05 +0200 Subject: [PATCH 43/50] fix: change parser options --- package-lock.json | 3 +-- packages/utils/run-prettier.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7b47fe3b74d..4e17dad8491 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13179,8 +13179,7 @@ "prettier": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz", - "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==", - "dev": true + "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==" }, "prettier-eslint": { "version": "8.8.2", diff --git a/packages/utils/run-prettier.ts b/packages/utils/run-prettier.ts index bf4980150d9..da5cc0a890a 100644 --- a/packages/utils/run-prettier.ts +++ b/packages/utils/run-prettier.ts @@ -19,7 +19,7 @@ export default function runPrettier(outputPath: string, source: string, cb?: Fun try { prettySource = prettier.format(source, { filepath: outputPath, - parser: "babel", + parser: "babylon", singleQuote: true, tabWidth: 1, useTabs: true, From bd06a69076d95863827fe43fa76b8fb554e7dbb1 Mon Sep 17 00:00:00 2001 From: Devid Farinelli Date: Thu, 30 May 2019 17:58:33 +0200 Subject: [PATCH 44/50] misc(generators): remove comment --- packages/generators/utils/webpackConfig.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/generators/utils/webpackConfig.ts b/packages/generators/utils/webpackConfig.ts index 1fddf5ee84d..3ae9ce88d5a 100644 --- a/packages/generators/utils/webpackConfig.ts +++ b/packages/generators/utils/webpackConfig.ts @@ -23,7 +23,6 @@ export function getDefaultOptimization(isProd: boolean): WebpackOptions["optimiz chunks: "'async'", minChunks: 1, minSize: 30000, - // for production name is recommended to be off name: !this.isProd, }, }; From 88fcfa8222f32593b3d8adae46a24b545f7d1c78 Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Thu, 30 May 2019 18:23:17 +0200 Subject: [PATCH 45/50] feat: add htmlWebpackPlugin in development --- packages/generators/init-generator.ts | 14 ++++++++++++++ packages/generators/utils/tooltip.ts | 11 +++++++++++ packages/generators/utils/webpackConfig.ts | 6 +++--- packages/utils/run-prettier.ts | 2 +- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index a2733828d8b..8997c3f66e5 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -12,6 +12,7 @@ import entryQuestions from "./utils/entry"; import langQuestionHandler, { LangType } from "./utils/languageSupport"; import styleQuestionHandler, { Loader, StylingType } from "./utils/styleSupport"; import tooltip from "./utils/tooltip"; +import { generatePluginName } from "./utils/plugins"; /** * @@ -224,6 +225,19 @@ export default class InitGenerator extends Generator { ); } } + if(!this.isProd) { + this.dependencies.push("html-webpack-plugin"); + const htmlWebpackDependency: string = "html-webpack-plugin"; + const htmlwebpackPlugin: string = generatePluginName(htmlWebpackDependency); + (this.configuration.config.topScope as string[]).push( + `const ${htmlwebpackPlugin} = require('${htmlWebpackDependency}')`, + "\n", + tooltip.html(), + ); + (this.configuration.config.webpackOptions.plugins as string[]).push( + `new ${htmlwebpackPlugin}()`, + ); + } done(); } diff --git a/packages/generators/utils/tooltip.ts b/packages/generators/utils/tooltip.ts index cd9dba4e7ec..c58c7fba922 100644 --- a/packages/generators/utils/tooltip.ts +++ b/packages/generators/utils/tooltip.ts @@ -57,6 +57,17 @@ export default { * * https://github.com/webpack-contrib/terser-webpack-plugin * + */`; + }, + + html: (): string => { + return `/* + * We've enabled HtmlWebpackPlugin for you! This generates a html + * page for you when you compile webpack, which will make you start + * developing and prototyping faster. + * + * https://github.com/jantimon/html-webpack-plugin + * */`; } }; diff --git a/packages/generators/utils/webpackConfig.ts b/packages/generators/utils/webpackConfig.ts index 3ae9ce88d5a..b67d3c6d0c5 100644 --- a/packages/generators/utils/webpackConfig.ts +++ b/packages/generators/utils/webpackConfig.ts @@ -4,15 +4,15 @@ export function getDefaultOptimization(isProd: boolean): WebpackOptions["optimiz let optimizationOptions; if (isProd) { optimizationOptions = { + minimizer: [ + "new TerserPlugin()", + ], splitChunks: { chunks: "'all'", }, }; } else { optimizationOptions = { - minimizer: [ - "new TerserPlugin()", - ], splitChunks: { cacheGroups: { vendors: { diff --git a/packages/utils/run-prettier.ts b/packages/utils/run-prettier.ts index da5cc0a890a..bf4980150d9 100644 --- a/packages/utils/run-prettier.ts +++ b/packages/utils/run-prettier.ts @@ -19,7 +19,7 @@ export default function runPrettier(outputPath: string, source: string, cb?: Fun try { prettySource = prettier.format(source, { filepath: outputPath, - parser: "babylon", + parser: "babel", singleQuote: true, tabWidth: 1, useTabs: true, From 0552f76922452203a9765bd8aa371393b9fe09a2 Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Thu, 30 May 2019 18:31:50 +0200 Subject: [PATCH 46/50] fix: remove type from inherited type --- packages/generators/init-generator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 8997c3f66e5..dbaa16c6058 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -228,7 +228,7 @@ export default class InitGenerator extends Generator { if(!this.isProd) { this.dependencies.push("html-webpack-plugin"); const htmlWebpackDependency: string = "html-webpack-plugin"; - const htmlwebpackPlugin: string = generatePluginName(htmlWebpackDependency); + const htmlwebpackPlugin = generatePluginName(htmlWebpackDependency); (this.configuration.config.topScope as string[]).push( `const ${htmlwebpackPlugin} = require('${htmlWebpackDependency}')`, "\n", From 960e73a47715cadbe2b850065b1ce0a4acf63a29 Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Thu, 30 May 2019 18:38:45 +0200 Subject: [PATCH 47/50] fix: remove type from inherited type --- packages/generators/init-generator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index dbaa16c6058..9d5b33f0b51 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -227,7 +227,7 @@ export default class InitGenerator extends Generator { } if(!this.isProd) { this.dependencies.push("html-webpack-plugin"); - const htmlWebpackDependency: string = "html-webpack-plugin"; + const htmlWebpackDependency = "html-webpack-plugin"; const htmlwebpackPlugin = generatePluginName(htmlWebpackDependency); (this.configuration.config.topScope as string[]).push( `const ${htmlwebpackPlugin} = require('${htmlWebpackDependency}')`, From e9d426d8be4de9fff9fe388a8f9b4dc74af7c8ab Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Thu, 30 May 2019 18:57:20 +0200 Subject: [PATCH 48/50] chore: format and revise code w.r.t style --- bin/opencollective.js | 6 +++++- bin/utils/prompt-command.js | 19 ++++++++--------- package-lock.json | 41 ++++++++++++++++++++++++++---------- package.json | 3 +-- packages/utils/path-utils.ts | 15 +------------ 5 files changed, 46 insertions(+), 38 deletions(-) diff --git a/bin/opencollective.js b/bin/opencollective.js index a6266a25b4e..16207dc7575 100644 --- a/bin/opencollective.js +++ b/bin/opencollective.js @@ -26,7 +26,11 @@ function printBadge() { print(`Please consider donating to our ${chalk.bold.blue("Open Collective")}`); print("to help us maintain this package."); console.log("\n\n"); - print(`${emoji("👉")} ${chalk.bold.yellow(" Donate:")} ${chalk.reset.underline.yellow("https://opencollective.com/webpack/donate")}`); + print( + `${emoji("👉")} ${chalk.bold.yellow(" Donate:")} ${chalk.reset.underline.yellow( + "https://opencollective.com/webpack/donate" + )}` + ); console.log("\n"); } diff --git a/bin/utils/prompt-command.js b/bin/utils/prompt-command.js index 907434c6c71..1ee4beab8c6 100644 --- a/bin/utils/prompt-command.js +++ b/bin/utils/prompt-command.js @@ -31,20 +31,20 @@ const npmGlobalRoot = () => { const cp = require("child_process"); return new Promise((resolve, reject) => { const command = cp.spawn("npm", ["root", "-g"]); - command.on("error", (error) => reject(error)); - command.stdout.on("data", (data) => resolve(data.toString())); - command.stderr.on("data", (data) => reject(data)); + command.on("error", error => reject(error)); + command.stdout.on("data", data => resolve(data.toString())); + command.stderr.on("data", data => reject(data)); }); }; const runWhenInstalled = (packages, pathForCmd, ...args) => { const package = require(pathForCmd); const func = package.default; - if (typeof func !== 'function') { + if (typeof func !== "function") { throw new Error(`@webpack-cli/${packages} failed to export a default function`); } return func(...args); -} +}; module.exports = function promptForInstallation(packages, ...args) { const nameOfPackage = "@webpack-cli/" + packages; @@ -102,19 +102,18 @@ module.exports = function promptForInstallation(packages, ...args) { case "y": case "yes": case "1": { - runCommand(packageManager, options) - .then(_=> { + .then(_ => { if (packages === "init") { npmGlobalRoot() - .then((root) => { + .then(root => { const pathtoInit = path.resolve(root.trim(), "@webpack-cli", "init"); return pathtoInit; }) - .then((pathForInit) => { + .then(pathForInit => { return require(pathForInit).default(...args); }) - .catch((error) => { + .catch(error => { console.error(error); process.exitCode = 1; }); diff --git a/package-lock.json b/package-lock.json index 3fa90818763..7be88ee429b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7480,7 +7480,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -7501,12 +7502,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7521,17 +7524,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -7648,7 +7654,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -7660,6 +7667,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7674,6 +7682,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7681,12 +7690,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7705,6 +7716,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -7785,7 +7797,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -7797,6 +7810,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -7882,7 +7896,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -7918,6 +7933,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7937,6 +7953,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7980,12 +7997,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/package.json b/package.json index a3d62ea17cc..b9ed22b9862 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,7 @@ "clean:all": "rimraf node_modules packages/*/{node_modules}", "commit": "git-cz", "docs": "typedoc", - "format": "prettier-eslint ./bin/*.js ./test/**/*.js ./packages/**/*.js --write", - "lint:codeOnly": "eslint \"{bin}/**/!(__testfixtures__)/*.js\" \"{bin}/**.js\"", + "format": "prettier-eslint ./bin/*.js ./bin/**/*.js ./test/**/*.js ./packages/**/*.js ./packages/**/**/*.js --write", "lint": "eslint \"./bin/*.js\" \"./test/**/*.js\" \"packages/**/!(node_modules)/*.test.js\"", "postinstall": "node ./bin/opencollective.js", "pretest": "npm run build && npm run lint && npm run tslint", diff --git a/packages/utils/path-utils.ts b/packages/utils/path-utils.ts index 468572a59b9..29def6d2257 100644 --- a/packages/utils/path-utils.ts +++ b/packages/utils/path-utils.ts @@ -17,19 +17,6 @@ export function isLocalPath(str: string): boolean { return path.isAbsolute(str) || /^\./.test(str) || fs.existsSync(str); } -/** - * Get absolute path of a webpack config in a project. - * - * @param {String[]} str - array of extensions to look for. - * @returns {String} Absolute path of the config. - */ - -export function webpackConfigPath(extensions: string[]): string { - const defaultConfigFileNames = ["webpack.config", "webpackfile"].join("|"); - const webpackConfigFileRegExp = `(${defaultConfigFileNames})(${extensions.join("|")})`; - return findup(webpackConfigFileRegExp); -} - /** * Find the root directory path of a project. * @@ -37,7 +24,7 @@ export function webpackConfigPath(extensions: string[]): string { */ export function findProjectRoot(): string { - const rootFilePath = findup(`package.json`); + const rootFilePath = findup("package.json"); const projectRoot = path.dirname(rootFilePath); return projectRoot; } From eb3909b06074b351e7a38e3eddec0d699bcf18da Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Thu, 30 May 2019 19:08:21 +0200 Subject: [PATCH 49/50] fix: formatting files --- bin/cli.js | 9 +- package-lock.json | 73 ++++++--- package.json | 11 +- .../__tests__/add-generator.test.ts | 3 +- packages/generators/add-generator.ts | 8 +- packages/generators/addon-generator.ts | 3 +- packages/generators/index.ts | 2 +- packages/generators/init-generator.ts | 153 +++++++----------- packages/generators/loader-generator.ts | 8 +- packages/generators/plugin-generator.ts | 8 +- packages/generators/templates/package.json.js | 5 +- packages/generators/utils/entry.ts | 75 ++++----- packages/generators/utils/languageSupport.ts | 66 ++++---- packages/generators/utils/plugins.ts | 19 +-- packages/generators/utils/styleSupport.ts | 128 ++++++--------- packages/generators/utils/webpackConfig.ts | 56 ++++--- packages/migrate/__tests__/migrate.test.ts | 46 +++--- .../__tests__/commonsChunkPlugin.test.ts | 24 +-- .../extractTextPlugin/extractTextPlugin.ts | 3 +- .../__tests__/loaderOptionsPlugin.test.ts | 24 +-- packages/migrate/loaders/loaders.ts | 22 ++- .../moduleConcatenationPlugin.test.ts | 18 +-- .../__tests__/noEmitOnErrorsPlugin.test.ts | 18 +-- packages/migrate/outputPath/outputPath.ts | 114 ++++++------- .../__tests__/removeDeprecatedPlugins.test.ts | 30 +--- .../__tests__/removeJsonLoader.test.ts | 24 +-- packages/migrate/resolve/resolve.ts | 7 +- packages/migrate/types/NodePath.ts | 6 +- .../migrate/uglifyJsPlugin/uglifyJsPlugin.ts | 6 +- packages/utils/__tests__/npm-exists.test.ts | 4 +- .../__tests__/npm-packages-exists.test.ts | 2 +- .../utils/__tests__/package-manager.test.ts | 10 +- .../utils/__tests__/recursive-parser.test.ts | 28 ++-- packages/utils/ast-utils.ts | 2 +- packages/utils/modify-config-helper.ts | 6 +- packages/utils/prop-types.ts | 2 +- packages/utils/run-prettier.ts | 6 +- packages/utils/scaffold.ts | 50 +++--- packages/utils/types/NodePath.ts | 6 +- .../webpack-scaffold/__tests__/index.test.ts | 34 ++-- packages/webpack-scaffold/index.ts | 10 +- 41 files changed, 476 insertions(+), 653 deletions(-) diff --git a/bin/cli.js b/bin/cli.js index aea8f6fd3e4..03faa127ee2 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -326,19 +326,14 @@ For more information, see https://webpack.js.org/api/cli/.`); const SIX_DAYS = 518400000; const now = new Date(); if (now.getDay() === MONDAY) { - const { - access, - constants, - statSync, - utimesSync, - } = require("fs"); + const { access, constants, statSync, utimesSync } = require("fs"); const lastPrint = statSync(openCollectivePath).atime; const lastPrintTS = new Date(lastPrint).getTime(); const timeSinceLastPrint = now.getTime() - lastPrintTS; if (timeSinceLastPrint > SIX_DAYS) { require(openCollectivePath); // On windows we need to manually update the atime - access(openCollectivePath, constants.W_OK, (e) => { + access(openCollectivePath, constants.W_OK, e => { if (!e) utimesSync(openCollectivePath, now, now); }); } diff --git a/package-lock.json b/package-lock.json index 4e17dad8491..6677cfe9e17 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2686,40 +2686,69 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.7.0.tgz", - "integrity": "sha512-NUSz1aTlIzzTjFFVFyzrbo8oFjHg3K/M9MzYByqbMCxeFdErhLAcGITVfXzSz+Yvp5OOpMu3HkIttB0NyKl54Q==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.9.0.tgz", + "integrity": "sha512-FOgfBorxjlBGpDIw+0LaZIXRX6GEEUfzj8LXwaQIUCp+gDOvkI+1WgugJ7SmWiISqK9Vj5r8S7NDKO/LB+6X9A==", "dev": true, "requires": { - "@typescript-eslint/parser": "1.7.0", - "@typescript-eslint/typescript-estree": "1.7.0", + "@typescript-eslint/experimental-utils": "1.9.0", + "@typescript-eslint/parser": "1.9.0", "eslint-utils": "^1.3.1", + "functional-red-black-tree": "^1.0.1", "regexpp": "^2.0.1", "requireindex": "^1.2.0", "tsutils": "^3.7.0" } }, - "@typescript-eslint/parser": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.7.0.tgz", - "integrity": "sha512-1QFKxs2V940372srm12ovSE683afqc1jB6zF/f8iKhgLz1yoSjYeGHipasao33VXKI+0a/ob9okeogGdKGvvlg==", + "@typescript-eslint/experimental-utils": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.9.0.tgz", + "integrity": "sha512-1s2dY9XxBwtS9IlSnRIlzqILPyeMly5tz1bfAmQ84Ul687xBBve5YsH5A5EKeIcGurYYqY2w6RkHETXIwnwV0A==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "1.7.0", - "eslint-scope": "^4.0.0", - "eslint-visitor-keys": "^1.0.0" + "@typescript-eslint/typescript-estree": "1.9.0" + }, + "dependencies": { + "@typescript-eslint/typescript-estree": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.9.0.tgz", + "integrity": "sha512-7Eg0TEQpCkTsEwsl1lIzd6i7L3pJLQFWesV08dS87bNz0NeSjbL78gNAP1xCKaCejkds4PhpLnZkaAjx9SU8OA==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } } }, - "@typescript-eslint/typescript-estree": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.7.0.tgz", - "integrity": "sha512-K5uedUxVmlYrVkFbyV3htDipvLqTE3QMOUQEHYJaKtgzxj6r7c5Ca/DG1tGgFxX+fsbi9nDIrf4arq7Ib7H/Yw==", + "@typescript-eslint/parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.9.0.tgz", + "integrity": "sha512-CWgC1XrQ34H/+LwAU7vY5xteZDkNqeAkeidEpJnJgkKu0yqQ3ZhQ7S+dI6MX4vmmM1TKRbOrKuXc6W0fIHhdbA==", "dev": true, "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.5.0" + "@typescript-eslint/experimental-utils": "1.9.0", + "@typescript-eslint/typescript-estree": "1.9.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0" }, "dependencies": { + "@typescript-eslint/typescript-estree": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.9.0.tgz", + "integrity": "sha512-7Eg0TEQpCkTsEwsl1lIzd6i7L3pJLQFWesV08dS87bNz0NeSjbL78gNAP1xCKaCejkds4PhpLnZkaAjx9SU8OA==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + } + }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", @@ -12418,7 +12447,7 @@ }, "resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "resolved": false, "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, @@ -16502,9 +16531,9 @@ "dev": true }, "tsutils": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz", - "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.12.0.tgz", + "integrity": "sha512-64KxDOb3+5ZVbz6NDZlCtOHstLk9+W96Y7d5Z/s5ge92gLaunxDeXYahvB7Rhl1dbaa3ifyq/W53o4mshIV1Tw==", "dev": true, "requires": { "tslib": "^1.8.1" diff --git a/package.json b/package.json index 5135a191ba4..9b3a166d93d 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,10 @@ "clean:all": "rimraf node_modules packages/*/{node_modules}", "commit": "git-cz", "docs": "typedoc", - "format": "prettier-eslint ./bin/*.js ./test/**/*.js ./packages/**/*.js --write", - "lint:codeOnly": "eslint \"{bin}/**/!(__testfixtures__)/*.js\" \"{bin}/**.js\"", - "lint": "eslint \"./bin/*.js\" \"./test/**/*.js\" \"packages/**/!(node_modules)/*.ts\"", + "format": "npm run format:js && npm run format:ts", + "format:ts": "prettier-eslint ./bin/*.js ./bin/**/*.js ./test/**/*.js ./packages/**/**/*.js ./packages/**/*.js --write", + "format:js": "prettier-eslint ./packages/**/**/*.ts ./packages/**/*.ts ./packages/**/**/**/*.ts --write", + "lint": "eslint \"./bin/*.js\" \"./bin/**/*.js\" \"./test/**/*.js\" \"packages/**/!(node_modules)/*.ts\" \"packages/**/!(node_modules)/**/*.ts\"", "postinstall": "node ./bin/opencollective.js", "pretest": "npm run build && npm run lint", "reportCoverage": "nyc report --reporter=json && codecov -f coverage/coverage-final.json --disable=gcov", @@ -145,8 +146,8 @@ "@commitlint/travis-cli": "^7.2.1", "@types/jest": "^23.3.14", "@types/node": "^10.12.9", - "@typescript-eslint/eslint-plugin": "^1.6.0", - "@typescript-eslint/parser": "^1.6.0", + "@typescript-eslint/eslint-plugin": "^1.9.0", + "@typescript-eslint/parser": "^1.9.0", "babel-preset-env": "^1.7.0", "babel-preset-jest": "^24.3.0", "bundlesize": "^0.17.2", diff --git a/packages/generators/__tests__/add-generator.test.ts b/packages/generators/__tests__/add-generator.test.ts index 7906123cb4e..76588aa87df 100644 --- a/packages/generators/__tests__/add-generator.test.ts +++ b/packages/generators/__tests__/add-generator.test.ts @@ -1,4 +1,4 @@ -import { generatePluginName } from "../utils/plugins" +import { generatePluginName } from "../utils/plugins"; describe("generatePluginName", () => { it("should return webpack Standard Plugin Name for Name : extract-text-webpack-plugin", () => { @@ -11,4 +11,3 @@ describe("generatePluginName", () => { expect(pluginName).toEqual("webpack.DefinePlugin"); }); }); - diff --git a/packages/generators/add-generator.ts b/packages/generators/add-generator.ts index ced8cd62311..0bdcd282498 100644 --- a/packages/generators/add-generator.ts +++ b/packages/generators/add-generator.ts @@ -16,7 +16,6 @@ import * as webpackDevServerSchema from "webpack-dev-server/lib/options.json"; import * as webpackSchema from "./utils/optionsSchema.json"; const PROPS: string[] = Array.from(PROP_TYPES.keys()); - /** * * Checks if the given array has a given property @@ -91,8 +90,9 @@ export default class AddGenerator extends Generator { const done: () => {} = this.async(); let action: string; const self: this = this; - const manualOrListInput: (promptAction: string) => Generator.Question = (promptAction: string): Generator.Question => - Input("actionAnswer", `What do you want to add to ${promptAction}?`); + const manualOrListInput: (promptAction: string) => Generator.Question = ( + promptAction: string + ): Generator.Question => Input("actionAnswer", `What do you want to add to ${promptAction}?`); let inputPrompt: Generator.Question; // first index indicates if it has a deep prop, 2nd indicates what kind of @@ -380,7 +380,7 @@ export default class AddGenerator extends Generator { (p: boolean): void => { if (p) { this.dependencies.push(answerToAction.actionAnswer); - const pluginName = generatePluginName(answerToAction.actionAnswer) + const pluginName = generatePluginName(answerToAction.actionAnswer); this.configuration.config.topScope.push( `const ${pluginName} = require("${answerToAction.actionAnswer}")` ); diff --git a/packages/generators/addon-generator.ts b/packages/generators/addon-generator.ts index fbbcf7fc8e5..0e61f7748d8 100644 --- a/packages/generators/addon-generator.ts +++ b/packages/generators/addon-generator.ts @@ -31,7 +31,8 @@ const addonGenerator = ( copyFiles: string[], copyTemplateFiles: string[], templateFn: Function -): typeof Generator => class AddonGenerator extends Generator { +): typeof Generator => + class AddonGenerator extends Generator { public props: Generator.Question; public copy: (value: string, index: number, array: string[]) => void; public copyTpl: (value: string, index: number, array: string[]) => void; diff --git a/packages/generators/index.ts b/packages/generators/index.ts index dd4bd030f27..b537adb02f6 100644 --- a/packages/generators/index.ts +++ b/packages/generators/index.ts @@ -13,5 +13,5 @@ export { loaderGenerator, pluginGenerator, removeGenerator, - updateGenerator, + updateGenerator }; diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 9d5b33f0b51..8ba18e4ca65 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -38,14 +38,9 @@ export default class InitGenerator extends Generator { public constructor(args, opts) { super(args, opts); - this.usingDefaults = false, - this.isProd = this.usingDefaults ? true : false; - - this.dependencies = [ - "webpack", - "webpack-cli", - "babel-plugin-syntax-dynamic-import", - ]; + (this.usingDefaults = false), (this.isProd = this.usingDefaults ? true : false); + + this.dependencies = ["webpack", "webpack-cli", "babel-plugin-syntax-dynamic-import"]; if (this.isProd) { this.dependencies.push("terser-webpack-plugin"); } else { @@ -62,10 +57,10 @@ export default class InitGenerator extends Generator { output: undefined, plugins: [], module: { - rules: [], - }, - }, - }, + rules: [] + } + } + } }; // add splitChunks options for transparency @@ -74,27 +69,25 @@ export default class InitGenerator extends Generator { "const path = require('path');", "const webpack = require('webpack');", "\n", - tooltip.splitChunks(), + tooltip.splitChunks() ); if (this.isProd) { this.configuration.config.topScope.push( tooltip.terser(), "const TerserPlugin = require('terser-webpack-plugin');", - "\n", + "\n" ); } - (this.configuration.config.webpackOptions.plugins as string[]).push( - "new webpack.ProgressPlugin()", - ); + (this.configuration.config.webpackOptions.plugins as string[]).push("new webpack.ProgressPlugin()"); let optimizationConfig = getDefaultOptimization(this.isProd); this.configuration.config.webpackOptions.optimization = optimizationConfig; if (!this.isProd) { this.configuration.config.webpackOptions.devServer = { - open: true, + open: true }; } } @@ -107,25 +100,21 @@ export default class InitGenerator extends Generator { process.stdout.write( `\n${logSymbols.info}${chalk.blue(" INFO ")} ` + - `For more information and a detailed description of each question, have a look at: ` + - `${chalk.bold.green("https://github.com/webpack/webpack-cli/blob/master/INIT.md")}\n`, + `For more information and a detailed description of each question, have a look at: ` + + `${chalk.bold.green("https://github.com/webpack/webpack-cli/blob/master/INIT.md")}\n` ); process.stdout.write( `${logSymbols.info}${chalk.blue(" INFO ")} ` + - `Alternatively, run "webpack(-cli) --help" for usage info\n\n`, + `Alternatively, run "webpack(-cli) --help" for usage info\n\n` ); const { multiEntries } = await this.prompt([ - Confirm( - "multiEntries", - "Will your application have multiple bundles?", - false - ), - ]); + Confirm("multiEntries", "Will your application have multiple bundles?", false) + ]); // TODO string | object const entryOption: void | {} = await entryQuestions(self, multiEntries); - + if (typeof entryOption === "string" && entryOption.length > 0) { this.configuration.config.webpackOptions.entry = `${entryOption}`; } else if (typeof entryOption === "object") { @@ -133,53 +122,41 @@ export default class InitGenerator extends Generator { } const { outputDir } = await this.prompt([ - Input( - "outputDir", - "In which folder do you want to store your generated bundles?", - "dist", - ), - ]); + Input("outputDir", "In which folder do you want to store your generated bundles?", "dist") + ]); // As entry is not required anymore and we dont set it to be an empty string or """"" // it can be undefined so falsy check is enough (vs entry.length); - if ( - !this.configuration.config.webpackOptions.entry && - !this.usingDefaults - ) { + if (!this.configuration.config.webpackOptions.entry && !this.usingDefaults) { this.configuration.config.webpackOptions.output = { chunkFilename: "'[name].[chunkhash].js'", - filename: "'[name].[chunkhash].js'", + filename: "'[name].[chunkhash].js'" }; } else if (!this.usingDefaults) { this.configuration.config.webpackOptions.output = { - filename: "'[name].[chunkhash].js'", + filename: "'[name].[chunkhash].js'" }; } if (!this.usingDefaults && outputDir.length) { - this.configuration.config.webpackOptions.output.path = - `path.resolve(__dirname, '${outputDir}')`; + this.configuration.config.webpackOptions.output.path = `path.resolve(__dirname, '${outputDir}')`; } - + const { langType } = await this.prompt([ - List("langType", "Will you use one of the below JS solutions?", [ - LangType.ES6, - LangType.Typescript, - "No", - ]), - ]); - + List("langType", "Will you use one of the below JS solutions?", [LangType.ES6, LangType.Typescript, "No"]) + ]); + langQuestionHandler(this, langType); this.langType = langType; - const { stylingType } = await this.prompt([ - List("stylingType", "Will you use one of the below CSS solutions?", [ - "No", - StylingType.CSS, - StylingType.SASS, - StylingType.LESS, - StylingType.PostCSS, - ]), - ]); + const { stylingType } = await this.prompt([ + List("stylingType", "Will you use one of the below CSS solutions?", [ + "No", + StylingType.CSS, + StylingType.SASS, + StylingType.LESS, + StylingType.PostCSS + ]) + ]); ({ ExtractUseProps, regExpForStyles } = styleQuestionHandler(self, stylingType)); @@ -188,10 +165,10 @@ export default class InitGenerator extends Generator { const { useExtractPlugin } = await this.prompt([ Input( "useExtractPlugin", - "If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)", - ), + "If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)" + ) ]); - + if (regExpForStyles) { if (this.isProd) { const cssBundleName: string = useExtractPlugin; @@ -199,44 +176,40 @@ export default class InitGenerator extends Generator { this.configuration.config.topScope.push( tooltip.cssPlugin(), "const MiniCssExtractPlugin = require('mini-css-extract-plugin');", - "\n", + "\n" ); if (cssBundleName.length !== 0) { (this.configuration.config.webpackOptions.plugins as string[]).push( // TODO: use [contenthash] after it is supported - `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })`, + `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })` ); } else { (this.configuration.config.webpackOptions.plugins as string[]).push( - "new MiniCssExtractPlugin({ filename:'style.css' })", + "new MiniCssExtractPlugin({ filename:'style.css' })" ); } ExtractUseProps.unshift({ - loader: "MiniCssExtractPlugin.loader", + loader: "MiniCssExtractPlugin.loader" }); } - this.configuration.config.webpackOptions.module.rules.push( - { - test: regExpForStyles, - use: ExtractUseProps, - }, - ); + this.configuration.config.webpackOptions.module.rules.push({ + test: regExpForStyles, + use: ExtractUseProps + }); } } - if(!this.isProd) { + if (!this.isProd) { this.dependencies.push("html-webpack-plugin"); const htmlWebpackDependency = "html-webpack-plugin"; const htmlwebpackPlugin = generatePluginName(htmlWebpackDependency); (this.configuration.config.topScope as string[]).push( `const ${htmlwebpackPlugin} = require('${htmlWebpackDependency}')`, "\n", - tooltip.html(), - ); - (this.configuration.config.webpackOptions.plugins as string[]).push( - `new ${htmlwebpackPlugin}()`, + tooltip.html() ); + (this.configuration.config.webpackOptions.plugins as string[]).push(`new ${htmlwebpackPlugin}()`); } done(); } @@ -244,11 +217,9 @@ export default class InitGenerator extends Generator { public installPlugins(): void { const packager = getPackageManager(); const opts: { - dev?: boolean, - "save-dev"?: boolean, - } = packager === "yarn" ? - { dev: true } : - { "save-dev": true }; + dev?: boolean; + "save-dev"?: boolean; + } = packager === "yarn" ? { dev: true } : { "save-dev": true }; this.scheduleInstallTask(packager, this.dependencies, opts); } @@ -261,29 +232,19 @@ export default class InitGenerator extends Generator { const generateEntryFile = (entryPath: string, name: string): void => { entryPath = entryPath.replace(/'/g, ""); - this.fs.copyTpl( - path.resolve(__dirname, "./templates/index.js"), - this.destinationPath(entryPath), - { name }, - ); + this.fs.copyTpl(path.resolve(__dirname, "./templates/index.js"), this.destinationPath(entryPath), { name }); }; // Generate entry file/files const entry = this.configuration.config.webpackOptions.entry; - if ( typeof entry === "string" ) { + if (typeof entry === "string") { generateEntryFile(entry, "your main file!"); } else if (typeof entry === "object") { - Object.keys(entry).forEach((name: string): void => - generateEntryFile(entry[name], `${name} main file!`), - ); + Object.keys(entry).forEach((name: string): void => generateEntryFile(entry[name], `${name} main file!`)); } // Generate README - this.fs.copyTpl( - path.resolve(__dirname, "./templates/README.md"), - this.destinationPath("README.md"), - {} - ); + this.fs.copyTpl(path.resolve(__dirname, "./templates/README.md"), this.destinationPath("README.md"), {}); // Genrate tsconfig if (this.langType === LangType.Typescript) { diff --git a/packages/generators/loader-generator.ts b/packages/generators/loader-generator.ts index aaec1666ae2..e36dab18f4d 100644 --- a/packages/generators/loader-generator.ts +++ b/packages/generators/loader-generator.ts @@ -35,8 +35,8 @@ const LoaderGenerator = addonGenerator( message: "Loader name", name: "name", type: "input", - validate: (str: string): boolean => str.length > 0, - }, + validate: (str: string): boolean => str.length > 0 + } ], path.resolve(__dirname, "..", "generate-loader"), [ @@ -48,10 +48,10 @@ const LoaderGenerator = addonGenerator( "examples/simple/webpack.config.js.tpl", "examples/simple/src/index.js.tpl", "examples/simple/src/lazy-module.js.tpl", - "examples/simple/src/static-esm-module.js.tpl", + "examples/simple/src/static-esm-module.js.tpl" ], ["src/_index.js.tpl"], - (gen): object => ({ name: gen.props.name }), + (gen): object => ({ name: gen.props.name }) ); export default LoaderGenerator; diff --git a/packages/generators/plugin-generator.ts b/packages/generators/plugin-generator.ts index 82550f520a2..22a0295332e 100644 --- a/packages/generators/plugin-generator.ts +++ b/packages/generators/plugin-generator.ts @@ -19,8 +19,8 @@ const PluginGenerator = addonGenerator( message: "Plugin name", name: "name", type: "input", - validate: (str: string): boolean => str.length > 0, - }, + validate: (str: string): boolean => str.length > 0 + } ], path.resolve(__dirname, "..", "generate-plugin"), [ @@ -29,10 +29,10 @@ const PluginGenerator = addonGenerator( "test/functional.test.js.tpl", "examples/simple/src/index.js.tpl", "examples/simple/src/lazy-module.js.tpl", - "examples/simple/src/static-esm-module.js.tpl", + "examples/simple/src/static-esm-module.js.tpl" ], ["src/_index.js.tpl", "examples/simple/_webpack.config.js.tpl"], - (gen): object => ({ name: _.upperFirst(_.camelCase(gen.props.name)) }), + (gen): object => ({ name: _.upperFirst(_.camelCase(gen.props.name)) }) ); export default PluginGenerator; diff --git a/packages/generators/templates/package.json.js b/packages/generators/templates/package.json.js index 54089edb516..caa852fbc6c 100644 --- a/packages/generators/templates/package.json.js +++ b/packages/generators/templates/package.json.js @@ -1,5 +1,4 @@ -module.exports = (isProd) => { - +module.exports = isProd => { let scripts = { build: "webpack" }; @@ -10,6 +9,6 @@ module.exports = (isProd) => { return { version: "1.0.0", description: "My webpack project", - scripts, + scripts }; }; diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts index 2d29c7dda6b..3146d8b61de 100644 --- a/packages/generators/utils/entry.ts +++ b/packages/generators/utils/entry.ts @@ -16,10 +16,7 @@ interface CustomGenerator extends Generator { * @returns {Object} An Object that holds the answers given by the user, later used to scaffold */ -export default function entry( - self: CustomGenerator, - multiEntries: boolean, -): Promise { +export default function entry(self: CustomGenerator, multiEntries: boolean): Promise { let entryIdentifiers: string[]; let result: Promise; if (multiEntries) { @@ -78,49 +75,43 @@ export default function entry( `${entryProp}`, `What is the location of "${entryProp}"?`, validate, - `src/${entryProp}`, - ), - ])) - .then( - (entryPropAnswer: object): object => { - Object.keys(entryPropAnswer).forEach( - (val: string): void => { - if ( - entryPropAnswer[val].charAt(0) !== "(" && - entryPropAnswer[val].charAt(0) !== "[" && - !entryPropAnswer[val].includes("function") && - !entryPropAnswer[val].includes("path") && - !entryPropAnswer[val].includes("process") - ) { - entryPropAnswer[val] = `\'./${entryPropAnswer[val].replace(/"|'/g, "").concat(".js")}\'`; - } - webpackEntryPoint[val] = entryPropAnswer[val]; + `src/${entryProp}` + ) + ]) + ).then( + (entryPropAnswer: object): object => { + Object.keys(entryPropAnswer).forEach( + (val: string): void => { + if ( + entryPropAnswer[val].charAt(0) !== "(" && + entryPropAnswer[val].charAt(0) !== "[" && + !entryPropAnswer[val].includes("function") && + !entryPropAnswer[val].includes("path") && + !entryPropAnswer[val].includes("process") + ) { + entryPropAnswer[val] = `\'./${entryPropAnswer[val] + .replace(/"|'/g, "") + .concat(".js")}\'`; } - ); - return webpackEntryPoint; - } - ); + webpackEntryPoint[val] = entryPropAnswer[val]; + } + ); + return webpackEntryPoint; + } + ); } ); } else { - result = self - .prompt([ - Input( - "singularEntry", - "Which will be your application entry point?", - "src/index", - ) - ]) - .then( - (singularEntryAnswer: { singularEntry: string }): string => { - let { singularEntry } = singularEntryAnswer; - singularEntry = `\'./${singularEntry.replace(/"|'/g, "").concat(".js")}\'`; - if (singularEntry.length <= 0) { - self.usingDefaults = true; - } - return singularEntry; + result = self.prompt([Input("singularEntry", "Which will be your application entry point?", "src/index")]).then( + (singularEntryAnswer: { singularEntry: string }): string => { + let { singularEntry } = singularEntryAnswer; + singularEntry = `\'./${singularEntry.replace(/"|'/g, "").concat(".js")}\'`; + if (singularEntry.length <= 0) { + self.usingDefaults = true; } - ); + return singularEntry; + } + ); } return result; } diff --git a/packages/generators/utils/languageSupport.ts b/packages/generators/utils/languageSupport.ts index 7d3c1f901cf..b564d8a9dc1 100644 --- a/packages/generators/utils/languageSupport.ts +++ b/packages/generators/utils/languageSupport.ts @@ -2,11 +2,10 @@ import { Rule } from "../types"; export enum LangType { ES6 = "ES6", - Typescript = "Typescript", + Typescript = "Typescript" } -const replaceExt = (path: string, ext: string): string => - path.substr(0, path.lastIndexOf(".")) + `${ext}'`; +const replaceExt = (path: string, ext: string): string => path.substr(0, path.lastIndexOf(".")) + `${ext}'`; function updateEntryExt(self, newExt: string): void { const jsEntryOption = self.configuration.config.webpackOptions.entry; @@ -14,15 +13,21 @@ function updateEntryExt(self, newExt: string): void { if (typeof jsEntryOption === "string") { tsEntryOption = replaceExt(jsEntryOption, newExt); } else if (typeof jsEntryOption === "object") { - Object.keys(jsEntryOption).forEach((entry: string): void => { - tsEntryOption[entry] = replaceExt(jsEntryOption[entry], newExt); - }); + Object.keys(jsEntryOption).forEach( + (entry: string): void => { + tsEntryOption[entry] = replaceExt(jsEntryOption[entry], newExt); + } + ); } self.configuration.config.webpackOptions.entry = tsEntryOption; } const getFolder = (path: string): string => - path.replace("'./", "").split("/").slice(0, -1).join("/"); + path + .replace("'./", "") + .split("/") + .slice(0, -1) + .join("/"); function getEntryFolders(self): string[] { const entryOption = self.configuration.config.webpackOptions.entry; @@ -31,10 +36,12 @@ function getEntryFolders(self): string[] { const folder = getFolder(entryOption); if (folder.length > 0) entryFolders[folder] = true; } else if (typeof entryOption === "object") { - Object.keys(entryOption).forEach((entry: string): void => { - const folder = getFolder(entryOption[entry]); - if (folder.length > 0) entryFolders[folder] = true; - }); + Object.keys(entryOption).forEach( + (entry: string): void => { + const folder = getFolder(entryOption[entry]); + if (folder.length > 0) entryFolders[folder] = true; + } + ); } return Object.keys(entryFolders); } @@ -46,11 +53,9 @@ function getEntryFolders(self): string[] { * @returns {Rule} A configuration containing the babel-loader with env preset */ export function getBabelLoader(includeFolders: string[]): Rule { - const include = includeFolders.map((folder: string): string => - `path.resolve(__dirname, '${folder}')` - ); + const include = includeFolders.map((folder: string): string => `path.resolve(__dirname, '${folder}')`); return { - test: "/\.(js|jsx)$/", + test: "/.(js|jsx)$/", include, loader: "'babel-loader'", options: { @@ -63,7 +68,7 @@ export function getBabelLoader(includeFolders: string[]): Rule { } ] ] - }, + } }; } @@ -74,14 +79,12 @@ export function getBabelLoader(includeFolders: string[]): Rule { * @returns {Rule} A configuration containing the ts-loader */ export function getTypescriptLoader(includeFolders: string[]): Rule { - const include = includeFolders.map((folder: string): string => - `path.resolve(__dirname, '${folder}')` - ); + const include = includeFolders.map((folder: string): string => `path.resolve(__dirname, '${folder}')`); return { - test: "/\.(ts|tsx)?$/", + test: "/.(ts|tsx)?$/", loader: "'ts-loader'", include, - exclude: ["/node_modules/"], + exclude: ["/node_modules/"] }; } @@ -89,26 +92,15 @@ export default function language(self, langType: string): void { const entryFolders = getEntryFolders(self); switch (langType) { case LangType.ES6: - self.dependencies.push( - "babel-loader", - "@babel/core", - "@babel/preset-env", - ); - self.configuration.config.webpackOptions.module.rules.push( - getBabelLoader(entryFolders), - ); + self.dependencies.push("babel-loader", "@babel/core", "@babel/preset-env"); + self.configuration.config.webpackOptions.module.rules.push(getBabelLoader(entryFolders)); break; case LangType.Typescript: - self.dependencies.push( - "typescript", - "ts-loader", - ); - self.configuration.config.webpackOptions.module.rules.push( - getTypescriptLoader(entryFolders), - ); + self.dependencies.push("typescript", "ts-loader"); + self.configuration.config.webpackOptions.module.rules.push(getTypescriptLoader(entryFolders)); self.configuration.config.webpackOptions.resolve = { - extensions: [ "'.tsx'", "'.ts'", "'.js'" ], + extensions: ["'.tsx'", "'.ts'", "'.js'"] }; updateEntryExt(self, ".ts"); diff --git a/packages/generators/utils/plugins.ts b/packages/generators/utils/plugins.ts index 4b60bd3f307..ebc57bc0f79 100644 --- a/packages/generators/utils/plugins.ts +++ b/packages/generators/utils/plugins.ts @@ -1,4 +1,3 @@ - /** * * Callable function with the initial plugins @@ -7,7 +6,7 @@ * that consists of terser-webpack-plugin */ -export default function (): string[] { +export default function(): string[] { return ["new TerserPlugin()"]; } @@ -24,10 +23,9 @@ export default function (): string[] { * */ -export const replaceAt = (str: string, index: number, replace: string) : string => { +export const replaceAt = (str: string, index: number, replace: string): string => { return str.substring(0, index) + replace + str.substring(index + 1); -} - +}; /** * @@ -39,13 +37,12 @@ export const replaceAt = (str: string, index: number, replace: string) : string * */ - export const generatePluginName = (rawPluginName: string): string => { - let myPluginNameArray : string[]; + let myPluginNameArray: string[]; myPluginNameArray = rawPluginName.split("-"); - const pluginArrLength : number = myPluginNameArray.length; - for (let i = 0; i < pluginArrLength && pluginArrLength > 1 ; i++) { + const pluginArrLength: number = myPluginNameArray.length; + for (let i = 0; i < pluginArrLength && pluginArrLength > 1; i++) { myPluginNameArray[i] = replaceAt(myPluginNameArray[i], 0, myPluginNameArray[i].charAt(0).toUpperCase()); } - return myPluginNameArray.join("") -} + return myPluginNameArray.join(""); +}; diff --git a/packages/generators/utils/styleSupport.ts b/packages/generators/utils/styleSupport.ts index d05a5241a75..8a875626fa7 100644 --- a/packages/generators/utils/styleSupport.ts +++ b/packages/generators/utils/styleSupport.ts @@ -4,7 +4,7 @@ export enum StylingType { CSS = "CSS", SASS = "SASS", LESS = "LESS", - PostCSS = "PostCSS", + PostCSS = "PostCSS" } export enum LoaderName { @@ -12,14 +12,14 @@ export enum LoaderName { SASS = "sass-loader", STYLE = "style-loader", LESS = "less-loader", - POSTCSS = "postcss-loader", + POSTCSS = "postcss-loader" } export enum StyleRegex { - CSS = "/\.css$/", - SASS = "/\.(scss|css)$/", - LESS = "/\.(less|css)$/", - PostCSS = "/\.css$/", + CSS = "/.css$/", + SASS = "/.(scss|css)$/", + LESS = "/.(less|css)$/", + PostCSS = "/.css$/" } export interface Loader { @@ -31,9 +31,12 @@ export interface Loader { }; } -export default function style(self, stylingType: string): { - ExtractUseProps: Loader[], - regExpForStyles: StyleRegex, +export default function style( + self, + stylingType: string +): { + ExtractUseProps: Loader[]; + regExpForStyles: StyleRegex; } { const ExtractUseProps: Loader[] = []; let regExpForStyles: StyleRegex = null; @@ -42,92 +45,70 @@ export default function style(self, stylingType: string): { case StylingType.CSS: regExpForStyles = StyleRegex.CSS; - self.dependencies.push( - LoaderName.CSS, - ); + self.dependencies.push(LoaderName.CSS); if (!self.isProd) { - self.dependencies.push( - LoaderName.STYLE, - ); - ExtractUseProps.push( - { - loader: `"${LoaderName.STYLE}"`, - }, - ); + self.dependencies.push(LoaderName.STYLE); + ExtractUseProps.push({ + loader: `"${LoaderName.STYLE}"` + }); } ExtractUseProps.push({ loader: `"${LoaderName.CSS}"`, options: { - sourceMap: true, - }, + sourceMap: true + } }); break; case StylingType.SASS: regExpForStyles = StyleRegex.SASS; - self.dependencies.push( - "node-sass", - LoaderName.SASS, - LoaderName.CSS, - ); + self.dependencies.push("node-sass", LoaderName.SASS, LoaderName.CSS); if (!self.isProd) { - self.dependencies.push( - LoaderName.STYLE, - ); - ExtractUseProps.push( - { - loader: `"${LoaderName.STYLE}"`, - }, - ); + self.dependencies.push(LoaderName.STYLE); + ExtractUseProps.push({ + loader: `"${LoaderName.STYLE}"` + }); } ExtractUseProps.push( { loader: `"${LoaderName.CSS}"`, options: { - sourceMap: true, - }, + sourceMap: true + } }, { loader: `"${LoaderName.SASS}"`, options: { - sourceMap: true, - }, - }, + sourceMap: true + } + } ); break; case StylingType.LESS: regExpForStyles = StyleRegex.LESS; - self.dependencies.push( - "less", - LoaderName.LESS, - LoaderName.CSS, - ); + self.dependencies.push("less", LoaderName.LESS, LoaderName.CSS); if (!self.isProd) { - self.dependencies.push( - LoaderName.STYLE, - ); - ExtractUseProps.push( - { - loader: `"${LoaderName.STYLE}"`, - }, - ); + self.dependencies.push(LoaderName.STYLE); + ExtractUseProps.push({ + loader: `"${LoaderName.STYLE}"` + }); } ExtractUseProps.push( { loader: `"${LoaderName.CSS}"`, options: { - sourceMap: true, - }, + sourceMap: true + } }, { loader: `"${LoaderName.LESS}"`, options: { - sourceMap: true, - }, - }, + sourceMap: true + } + } ); break; @@ -138,32 +119,23 @@ export default function style(self, stylingType: string): { tooltip.postcss(), "const autoprefixer = require('autoprefixer');", "const precss = require('precss');", - "\n", + "\n" ); - self.dependencies.push( - "precss", - "autoprefixer", - LoaderName.CSS, - LoaderName.POSTCSS, - ); + self.dependencies.push("precss", "autoprefixer", LoaderName.CSS, LoaderName.POSTCSS); if (!self.isProd) { - self.dependencies.push( - LoaderName.STYLE, - ); - ExtractUseProps.push( - { - loader: `"${LoaderName.STYLE}"`, - }, - ); + self.dependencies.push(LoaderName.STYLE); + ExtractUseProps.push({ + loader: `"${LoaderName.STYLE}"` + }); } ExtractUseProps.push( { loader: `"${LoaderName.CSS}"`, options: { importLoaders: 1, - sourceMap: true, - }, + sourceMap: true + } }, { loader: `"${LoaderName.POSTCSS}"`, @@ -173,9 +145,9 @@ export default function style(self, stylingType: string): { precss, autoprefixer ]; - }`, - }, - }, + }` + } + } ); break; } diff --git a/packages/generators/utils/webpackConfig.ts b/packages/generators/utils/webpackConfig.ts index b67d3c6d0c5..16ef191970c 100644 --- a/packages/generators/utils/webpackConfig.ts +++ b/packages/generators/utils/webpackConfig.ts @@ -1,31 +1,29 @@ -import { WebpackOptions } from '../types'; +import { WebpackOptions } from "../types"; export function getDefaultOptimization(isProd: boolean): WebpackOptions["optimization"] { - let optimizationOptions; - if (isProd) { - optimizationOptions = { - minimizer: [ - "new TerserPlugin()", - ], - splitChunks: { - chunks: "'all'", - }, - }; - } else { - optimizationOptions = { - splitChunks: { - cacheGroups: { - vendors: { - priority: -10, - test: "/[\\\\/]node_modules[\\\\/]/", - }, - }, - chunks: "'async'", - minChunks: 1, - minSize: 30000, - name: !this.isProd, - }, - }; - } - return optimizationOptions; -} \ No newline at end of file + let optimizationOptions; + if (isProd) { + optimizationOptions = { + minimizer: ["new TerserPlugin()"], + splitChunks: { + chunks: "'all'" + } + }; + } else { + optimizationOptions = { + splitChunks: { + cacheGroups: { + vendors: { + priority: -10, + test: "/[\\\\/]node_modules[\\\\/]/" + } + }, + chunks: "'async'", + minChunks: 1, + minSize: 30000, + name: !this.isProd + } + }; + } + return optimizationOptions; +} diff --git a/packages/migrate/__tests__/migrate.test.ts b/packages/migrate/__tests__/migrate.test.ts index 4369f0f86b7..f367e19ee34 100644 --- a/packages/migrate/__tests__/migrate.test.ts +++ b/packages/migrate/__tests__/migrate.test.ts @@ -30,34 +30,34 @@ module.exports = { `; describe("transform", () => { - it("should not transform if no transformations defined", (done) => { - transform(input, []).then((output) => { - expect(output).toMatchSnapshot(input); - done(); + it("should not transform if no transformations defined", done => { + transform(input, []).then(output => { + expect(output).toMatchSnapshot(input); + done(); + }); }); - }); - it("should transform using all transformations", (done) => { - transform(input).then((output) => { - expect(output).toMatchSnapshot(); - done(); + it("should transform using all transformations", done => { + transform(input).then(output => { + expect(output).toMatchSnapshot(); + done(); + }); }); - }); - it("should transform only using specified transformations", (done) => { - transform(input, [transformations.loadersTransform]).then((output) => { - expect(output).toMatchSnapshot(); - done(); + it("should transform only using specified transformations", done => { + transform(input, [transformations.loadersTransform]).then(output => { + expect(output).toMatchSnapshot(); + done(); + }); }); - }); - it("should respect recast options", (done) => { - transform(input, undefined, { - quote: "double", - trailingComma: true, - }).then((output) => { - expect(output).toMatchSnapshot(); - done(); + it("should respect recast options", done => { + transform(input, undefined, { + quote: "double", + trailingComma: true + }).then(output => { + expect(output).toMatchSnapshot(); + done(); + }); }); - }); }); diff --git a/packages/migrate/commonsChunkPlugin/__tests__/commonsChunkPlugin.test.ts b/packages/migrate/commonsChunkPlugin/__tests__/commonsChunkPlugin.test.ts index 5c2e28e1f40..80ec6de5f7e 100644 --- a/packages/migrate/commonsChunkPlugin/__tests__/commonsChunkPlugin.test.ts +++ b/packages/migrate/commonsChunkPlugin/__tests__/commonsChunkPlugin.test.ts @@ -9,24 +9,8 @@ defineTest(dirName, "commonsChunkPlugin", "commonsChunkPlugin-2"); defineTest(dirName, "commonsChunkPlugin", "commonsChunkPlugin-3"); defineTest(dirName, "commonsChunkPlugin", "commonsChunkPlugin-4"); defineTest(dirName, "commonsChunkPlugin", "commonsChunkPlugin-5"); -defineTest( - dirName, - "commonsChunkPlugin", - "commonsChunkPlugin-6a", -); -defineTest( - dirName, - "commonsChunkPlugin", - "commonsChunkPlugin-6b", -); -defineTest( - dirName, - "commonsChunkPlugin", - "commonsChunkPlugin-6c", -); -defineTest( - dirName, - "commonsChunkPlugin", - "commonsChunkPlugin-6d", -); +defineTest(dirName, "commonsChunkPlugin", "commonsChunkPlugin-6a"); +defineTest(dirName, "commonsChunkPlugin", "commonsChunkPlugin-6b"); +defineTest(dirName, "commonsChunkPlugin", "commonsChunkPlugin-6c"); +defineTest(dirName, "commonsChunkPlugin", "commonsChunkPlugin-6d"); defineTest(dirName, "commonsChunkPlugin", "commonsChunkPlugin-7"); diff --git a/packages/migrate/extractTextPlugin/extractTextPlugin.ts b/packages/migrate/extractTextPlugin/extractTextPlugin.ts index fcc3931a394..565ff11c3ce 100644 --- a/packages/migrate/extractTextPlugin/extractTextPlugin.ts +++ b/packages/migrate/extractTextPlugin/extractTextPlugin.ts @@ -39,7 +39,8 @@ export default function(j: JSCodeshift, ast: Node): void | Node { if (literalArgs && literalArgs.length > 1) { const newArgs: object = j.objectExpression( literalArgs.map( - (p: Node, index: number): Node => utils.createProperty(j, index === 0 ? "fallback" : "use", p.value as Node) + (p: Node, index: number): Node => + utils.createProperty(j, index === 0 ? "fallback" : "use", p.value as Node) ) ); (path.value as Node).arguments = [newArgs]; diff --git a/packages/migrate/loaderOptionsPlugin/__tests__/loaderOptionsPlugin.test.ts b/packages/migrate/loaderOptionsPlugin/__tests__/loaderOptionsPlugin.test.ts index 0126a11b8cd..d827273f340 100644 --- a/packages/migrate/loaderOptionsPlugin/__tests__/loaderOptionsPlugin.test.ts +++ b/packages/migrate/loaderOptionsPlugin/__tests__/loaderOptionsPlugin.test.ts @@ -3,23 +3,7 @@ import { join } from "path"; const dirName: string = join(__dirname, ".."); -defineTest( - dirName, - "loaderOptionsPlugin", - "loaderOptionsPlugin-0", -); -defineTest( - dirName, - "loaderOptionsPlugin", - "loaderOptionsPlugin-1", -); -defineTest( - dirName, - "loaderOptionsPlugin", - "loaderOptionsPlugin-2", -); -defineTest( - dirName, - "loaderOptionsPlugin", - "loaderOptionsPlugin-3", -); +defineTest(dirName, "loaderOptionsPlugin", "loaderOptionsPlugin-0"); +defineTest(dirName, "loaderOptionsPlugin", "loaderOptionsPlugin-1"); +defineTest(dirName, "loaderOptionsPlugin", "loaderOptionsPlugin-2"); +defineTest(dirName, "loaderOptionsPlugin", "loaderOptionsPlugin-3"); diff --git a/packages/migrate/loaders/loaders.ts b/packages/migrate/loaders/loaders.ts index 0f5452c2ac1..54f75dac271 100644 --- a/packages/migrate/loaders/loaders.ts +++ b/packages/migrate/loaders/loaders.ts @@ -55,7 +55,7 @@ export default function(j: JSCodeshift, ast: Node): Node { */ const createArrayExpressionFromArray = (path: Node): Node => { - const value: Node = (path.value as Node); + const value: Node = path.value as Node; // Find paths with `loaders` keys in the given Object const paths: Node[] = value.properties.filter((prop: Node): boolean => prop.key.name.startsWith("loader")); // For each pair of key and value @@ -73,7 +73,9 @@ export default function(j: JSCodeshift, ast: Node): Node { // If items of the array are Strings if (arrElement.type === j.Literal.name) { // Replace with `{ loader: LOADER }` Object - return j.objectExpression([utils.createProperty(j, "loader", (arrElement.value as Node))]); + return j.objectExpression([ + utils.createProperty(j, "loader", arrElement.value as Node) + ]); } // otherwise keep the existing element return arrElement; @@ -108,7 +110,8 @@ export default function(j: JSCodeshift, ast: Node): Node { const createLoaderWithQuery = (p: Node): Node => { const properties: Node[] = (p.value as Node).properties; const loaderValue: string = properties.reduce( - (val: string, prop: Node): string => (prop.key.name === "loader" ? (prop.value as Node).value as string: val), + (val: string, prop: Node): string => + prop.key.name === "loader" ? ((prop.value as Node).value as string) : val, "" ); const loader: string = loaderValue.split("?")[0]; @@ -137,7 +140,8 @@ export default function(j: JSCodeshift, ast: Node): Node { const findLoaderWithQueryString = (p: Node): boolean => { return (p.value as Node).properties.reduce((predicate: boolean, prop: Node): boolean => { return ( - (utils.safeTraverse(prop, ["value", "value", "indexOf"]) && ((prop.value as Node).value as string).indexOf("?") > -1) || + (utils.safeTraverse(prop, ["value", "value", "indexOf"]) && + ((prop.value as Node).value as string).indexOf("?") > -1) || predicate ); }, false); @@ -192,7 +196,9 @@ export default function(j: JSCodeshift, ast: Node): Node { } ); if (loaders) { - (p.value as Node).properties = (p.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "loaders"); + (p.value as Node).properties = (p.value as Node).properties.filter( + (prop: Node): boolean => prop.key.name === "loaders" + ); } return p; }; @@ -306,7 +312,7 @@ export default function(j: JSCodeshift, ast: Node): Node { utils.safeTraverse(prop, ["value", "value"]) && !((prop.value as Node).value as string).endsWith("-loader") ) { - prop.value = j.literal((prop.value as Node).value as string + "-loader"); + prop.value = j.literal(((prop.value as Node).value as string) + "-loader"); } } ); @@ -333,7 +339,9 @@ export default function(j: JSCodeshift, ast: Node): Node { ); if (options) { - (p.value as Node).properties = (p.value as Node).properties.filter((prop: Node): boolean => prop.key.name !== "options"); + (p.value as Node).properties = (p.value as Node).properties.filter( + (prop: Node): boolean => prop.key.name !== "options" + ); (p.value as Node).properties.forEach( (prop: Node): void => { diff --git a/packages/migrate/moduleConcatenationPlugin/__tests__/moduleConcatenationPlugin.test.ts b/packages/migrate/moduleConcatenationPlugin/__tests__/moduleConcatenationPlugin.test.ts index 840dee420a2..69fcf1c07a0 100644 --- a/packages/migrate/moduleConcatenationPlugin/__tests__/moduleConcatenationPlugin.test.ts +++ b/packages/migrate/moduleConcatenationPlugin/__tests__/moduleConcatenationPlugin.test.ts @@ -3,18 +3,6 @@ import { join } from "path"; const dirName: string = join(__dirname, ".."); -defineTest( - dirName, - "moduleConcatenationPlugin", - "moduleConcatenationPlugin-0", -); -defineTest( - dirName, - "moduleConcatenationPlugin", - "moduleConcatenationPlugin-1", -); -defineTest( - dirName, - "moduleConcatenationPlugin", - "moduleConcatenationPlugin-2", -); +defineTest(dirName, "moduleConcatenationPlugin", "moduleConcatenationPlugin-0"); +defineTest(dirName, "moduleConcatenationPlugin", "moduleConcatenationPlugin-1"); +defineTest(dirName, "moduleConcatenationPlugin", "moduleConcatenationPlugin-2"); diff --git a/packages/migrate/noEmitOnErrorsPlugin/__tests__/noEmitOnErrorsPlugin.test.ts b/packages/migrate/noEmitOnErrorsPlugin/__tests__/noEmitOnErrorsPlugin.test.ts index 760a5a1aa75..a1e43ea1021 100644 --- a/packages/migrate/noEmitOnErrorsPlugin/__tests__/noEmitOnErrorsPlugin.test.ts +++ b/packages/migrate/noEmitOnErrorsPlugin/__tests__/noEmitOnErrorsPlugin.test.ts @@ -3,18 +3,6 @@ import { join } from "path"; const dirName: string = join(__dirname, ".."); -defineTest( - dirName, - "noEmitOnErrorsPlugin", - "noEmitOnErrorsPlugin-0", -); -defineTest( - dirName, - "noEmitOnErrorsPlugin", - "noEmitOnErrorsPlugin-1", -); -defineTest( - dirName, - "noEmitOnErrorsPlugin", - "noEmitOnErrorsPlugin-2", -); +defineTest(dirName, "noEmitOnErrorsPlugin", "noEmitOnErrorsPlugin-0"); +defineTest(dirName, "noEmitOnErrorsPlugin", "noEmitOnErrorsPlugin-1"); +defineTest(dirName, "noEmitOnErrorsPlugin", "noEmitOnErrorsPlugin-2"); diff --git a/packages/migrate/outputPath/outputPath.ts b/packages/migrate/outputPath/outputPath.ts index e3d1c0bd087..90ea98f5ff6 100644 --- a/packages/migrate/outputPath/outputPath.ts +++ b/packages/migrate/outputPath/outputPath.ts @@ -2,18 +2,13 @@ import * as utils from "@webpack-cli/utils/ast-utils"; import { JSCodeshift, Node } from "../types/NodePath"; +function replaceWithPath(j: JSCodeshift, p: Node, pathVarName: string): Node { + const convertedPath: Node = j.callExpression( + j.memberExpression(j.identifier(pathVarName), j.identifier("join"), false), + [j.identifier("__dirname"), p.value as Node] + ); -function replaceWithPath( - j: JSCodeshift, - p: Node, - pathVarName: string, -): Node { - const convertedPath: Node = j.callExpression( - j.memberExpression(j.identifier(pathVarName), j.identifier("join"), false), - [j.identifier("__dirname"), p.value as Node], - ); - - return convertedPath; + return convertedPath; } /** @@ -25,67 +20,50 @@ function replaceWithPath( * @returns {Node} ast - jscodeshift ast */ export default function(j: JSCodeshift, ast: Node): Node | void { - const literalOutputPath: Node = ast - .find(j.ObjectExpression) - .filter( - (p: Node): boolean => - utils.safeTraverse(p, ["parentPath", "value", "key", "name"]) === - "output", - ) - .find(j.Property) - .filter( - (p: Node): boolean => - utils.safeTraverse(p, ["value", "key", "name"]) === "path" && - utils.safeTraverse(p, ["value", "value", "type"]) === "Literal", - ); - - if (literalOutputPath) { - let pathVarName = "path"; - let isPathPresent = false; - const pathDeclaration: Node = ast - .find(j.VariableDeclarator) - .filter( - (p: Node): boolean => - utils.safeTraverse(p, ["value", "init", "callee", "name"]) === - "require", - ) + const literalOutputPath: Node = ast + .find(j.ObjectExpression) + .filter((p: Node): boolean => utils.safeTraverse(p, ["parentPath", "value", "key", "name"]) === "output") + .find(j.Property) .filter( - (p: Node): boolean => - utils.safeTraverse(p, ["value", "init", "arguments"]) && - // TODO: to fix when we have proper typing (@types/jscodeshift) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (p.value as any).init.arguments.reduce( - (isPresent: boolean, a: Node): boolean => { - return (a.type === "Literal" && a.value === "path") || isPresent; - }, - false, - ), + (p: Node): boolean => + utils.safeTraverse(p, ["value", "key", "name"]) === "path" && + utils.safeTraverse(p, ["value", "value", "type"]) === "Literal" ); - if (pathDeclaration) { - isPathPresent = true; - pathDeclaration.forEach( - (p: Node): void => { - pathVarName = utils.safeTraverse(p, ["value", "id", "name"]) as string; - }, - ); - } - const finalPathName = pathVarName; - literalOutputPath - .find(j.Literal) - .replaceWith((p: Node): Node => replaceWithPath(j, p, finalPathName)); + if (literalOutputPath) { + let pathVarName = "path"; + let isPathPresent = false; + const pathDeclaration: Node = ast + .find(j.VariableDeclarator) + .filter((p: Node): boolean => utils.safeTraverse(p, ["value", "init", "callee", "name"]) === "require") + .filter( + (p: Node): boolean => + utils.safeTraverse(p, ["value", "init", "arguments"]) && + // TODO: to fix when we have proper typing (@types/jscodeshift) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (p.value as any).init.arguments.reduce((isPresent: boolean, a: Node): boolean => { + return (a.type === "Literal" && a.value === "path") || isPresent; + }, false) + ); - if (!isPathPresent) { - const pathRequire: Node = utils.getRequire(j, "path", "path"); - return ast - .find(j.Program) - .replaceWith( - (p: Node): Node => - j.program([].concat(pathRequire).concat((p.value as Node).body)), - ); + if (pathDeclaration) { + isPathPresent = true; + pathDeclaration.forEach( + (p: Node): void => { + pathVarName = utils.safeTraverse(p, ["value", "id", "name"]) as string; + } + ); + } + const finalPathName = pathVarName; + literalOutputPath.find(j.Literal).replaceWith((p: Node): Node => replaceWithPath(j, p, finalPathName)); + + if (!isPathPresent) { + const pathRequire: Node = utils.getRequire(j, "path", "path"); + return ast + .find(j.Program) + .replaceWith((p: Node): Node => j.program([].concat(pathRequire).concat((p.value as Node).body))); + } } - } - return ast; + return ast; } - diff --git a/packages/migrate/removeDeprecatedPlugins/__tests__/removeDeprecatedPlugins.test.ts b/packages/migrate/removeDeprecatedPlugins/__tests__/removeDeprecatedPlugins.test.ts index 922ca71424c..2e4285f1b77 100644 --- a/packages/migrate/removeDeprecatedPlugins/__tests__/removeDeprecatedPlugins.test.ts +++ b/packages/migrate/removeDeprecatedPlugins/__tests__/removeDeprecatedPlugins.test.ts @@ -3,28 +3,8 @@ import { join } from "path"; const dirName: string = join(__dirname, ".."); -defineTest( - dirName, - "removeDeprecatedPlugins", - "removeDeprecatedPlugins-0", -); -defineTest( - dirName, - "removeDeprecatedPlugins", - "removeDeprecatedPlugins-1", -); -defineTest( - dirName, - "removeDeprecatedPlugins", - "removeDeprecatedPlugins-2", -); -defineTest( - dirName, - "removeDeprecatedPlugins", - "removeDeprecatedPlugins-3", -); -defineTest( - dirName, - "removeDeprecatedPlugins", - "removeDeprecatedPlugins-4", -); +defineTest(dirName, "removeDeprecatedPlugins", "removeDeprecatedPlugins-0"); +defineTest(dirName, "removeDeprecatedPlugins", "removeDeprecatedPlugins-1"); +defineTest(dirName, "removeDeprecatedPlugins", "removeDeprecatedPlugins-2"); +defineTest(dirName, "removeDeprecatedPlugins", "removeDeprecatedPlugins-3"); +defineTest(dirName, "removeDeprecatedPlugins", "removeDeprecatedPlugins-4"); diff --git a/packages/migrate/removeJsonLoader/__tests__/removeJsonLoader.test.ts b/packages/migrate/removeJsonLoader/__tests__/removeJsonLoader.test.ts index 6d705023056..33274324889 100644 --- a/packages/migrate/removeJsonLoader/__tests__/removeJsonLoader.test.ts +++ b/packages/migrate/removeJsonLoader/__tests__/removeJsonLoader.test.ts @@ -3,23 +3,7 @@ import { join } from "path"; const dirName: string = join(__dirname, ".."); -defineTest( - dirName, - "removeJsonLoader", - "removeJsonLoader-0", -); -defineTest( - dirName, - "removeJsonLoader", - "removeJsonLoader-1", -); -defineTest( - dirName, - "removeJsonLoader", - "removeJsonLoader-2", -); -defineTest( - dirName, - "removeJsonLoader", - "removeJsonLoader-3", -); +defineTest(dirName, "removeJsonLoader", "removeJsonLoader-0"); +defineTest(dirName, "removeJsonLoader", "removeJsonLoader-1"); +defineTest(dirName, "removeJsonLoader", "removeJsonLoader-2"); +defineTest(dirName, "removeJsonLoader", "removeJsonLoader-3"); diff --git a/packages/migrate/resolve/resolve.ts b/packages/migrate/resolve/resolve.ts index be60e4e69b0..a9022039b1e 100644 --- a/packages/migrate/resolve/resolve.ts +++ b/packages/migrate/resolve/resolve.ts @@ -21,7 +21,9 @@ export default function transformer(j: JSCodeshift, ast: Node): Node { }; const isModulePresent = (p: Node): Node | false => { - const modules: Node[] = (p.node.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "modules"); + const modules: Node[] = (p.node.value as Node).properties.filter( + (prop: Node): boolean => prop.key.name === "modules" + ); return modules.length > 0 && modules[0]; }; @@ -68,7 +70,8 @@ export default function transformer(j: JSCodeshift, ast: Node): Node { (p: Node): boolean => { return ( p.node.key.name === "resolve" && - (p.node.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "root").length === 1 + (p.node.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "root") + .length === 1 ); } ) diff --git a/packages/migrate/types/NodePath.ts b/packages/migrate/types/NodePath.ts index 1b828378ddb..66098c06894 100644 --- a/packages/migrate/types/NodePath.ts +++ b/packages/migrate/types/NodePath.ts @@ -39,11 +39,7 @@ export interface Node extends Object { size?: () => number; type?: string; value?: Node | string | Node[]; - toSource?: ( - object: { - quote?: string; - } - ) => string; + toSource?: (object: { quote?: string }) => string; source?: string; ast?: Node; rules?: ModuleRule[]; diff --git a/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts b/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts index 71980715a60..172d6f2f1d7 100644 --- a/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts +++ b/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts @@ -81,7 +81,11 @@ export default function(j: JSCodeshift, ast: Node): Node { j.arrayExpression([j.newExpression(j.identifier("TerserPlugin"), [pluginOptions[0]])]) ); } else { - expressionContent = j.property("init", j.identifier("minimizer"), j.arrayExpression([node.value as Node])); + expressionContent = j.property( + "init", + j.identifier("minimizer"), + j.arrayExpression([node.value as Node]) + ); } } else { searchForRequirePlugin.forEach((n: Node): void => j(n).remove()); diff --git a/packages/utils/__tests__/npm-exists.test.ts b/packages/utils/__tests__/npm-exists.test.ts index 2b773259af1..a5a98f168f0 100644 --- a/packages/utils/__tests__/npm-exists.test.ts +++ b/packages/utils/__tests__/npm-exists.test.ts @@ -3,13 +3,13 @@ import exists from "../npm-exists"; describe("npm-exists", () => { it("should successfully existence of a published module", () => { - exists("webpack-scaffold-demo").then((status) => { + exists("webpack-scaffold-demo").then(status => { expect(status).toBe(true); }); }); it("should return false for the existence of a fake module", () => { - exists("webpack-scaffold-noop").then((status) => { + exists("webpack-scaffold-noop").then(status => { expect(status).toBe(false); }); }); diff --git a/packages/utils/__tests__/npm-packages-exists.test.ts b/packages/utils/__tests__/npm-packages-exists.test.ts index 151eb82f863..4c75f72699d 100644 --- a/packages/utils/__tests__/npm-packages-exists.test.ts +++ b/packages/utils/__tests__/npm-packages-exists.test.ts @@ -1,5 +1,5 @@ import npmPackagesExists from "../npm-packages-exists"; -import {resolvePackages} from "../resolve-packages"; +import { resolvePackages } from "../resolve-packages"; jest.mock("../npm-exists"); jest.mock("../resolve-packages"); diff --git a/packages/utils/__tests__/package-manager.test.ts b/packages/utils/__tests__/package-manager.test.ts index baa4204822a..c21a0e45aa8 100644 --- a/packages/utils/__tests__/package-manager.test.ts +++ b/packages/utils/__tests__/package-manager.test.ts @@ -19,15 +19,15 @@ describe("package-manager", () => { signal: null, status: 1, stderr: null, - stdout: null, + stdout: null }; function mockSpawnErrorOnce() { spawn.sync.mockReturnValueOnce( Object.assign({}, defaultSyncResult, { error: new Error(), - status: null, - }), + status: null + }) ); } @@ -103,8 +103,8 @@ describe("package-manager", () => { // Mock stdout of `yarn global dir` spawn.sync.mockReturnValueOnce({ stdout: { - toString: () => `${yarnDir}\n`, - }, + toString: () => `${yarnDir}\n` + } }); const globalPath = packageManager.getPathToGlobalPackages(); const expected = path.join(yarnDir, "node_modules"); diff --git a/packages/utils/__tests__/recursive-parser.test.ts b/packages/utils/__tests__/recursive-parser.test.ts index 87778124f13..20de356e54e 100644 --- a/packages/utils/__tests__/recursive-parser.test.ts +++ b/packages/utils/__tests__/recursive-parser.test.ts @@ -15,11 +15,11 @@ defineTest(join(__dirname, ".."), "init", "fixture-1", "entry", { include: ["customObj", "'Stringy'"], loader: "'eslint-loader'", options: { - formatter: "'someOption'", + formatter: "'someOption'" }, - test: new RegExp(/\.(js|vue)$/), - }, - ], + test: new RegExp(/\.(js|vue)$/) + } + ] }); defineTest(join(__dirname, ".."), "add", "fixture-2", "entry", { @@ -35,31 +35,31 @@ defineTest(join(__dirname, ".."), "add", "fixture-2", "entry", { include: ["asd", "'Stringy'"], loader: "'pia-loader'", options: { - formatter: "'nao'", + formatter: "'nao'" }, - test: new RegExp(/\.(wasm|c)$/), - }, - ], + test: new RegExp(/\.(wasm|c)$/) + } + ] }); defineTest(join(__dirname, ".."), "remove", "fixture-3", "resolve", { - alias: null, + alias: null }); defineTest(join(__dirname, ".."), "remove", "fixture-3", "plugins", ["plugin2"]); defineTest(join(__dirname, ".."), "remove", "fixture-3", "module", { - noParse: null, + noParse: null }); defineTest(join(__dirname, ".."), "remove", "fixture-3", "entry", { - a: null, + a: null }); defineTest(join(__dirname, ".."), "remove", "fixture-3", "module", { rules: [ { - loader: "eslint-loader", - }, - ], + loader: "eslint-loader" + } + ] }); diff --git a/packages/utils/ast-utils.ts b/packages/utils/ast-utils.ts index 7a6fed5a657..5ff459b10b1 100644 --- a/packages/utils/ast-utils.ts +++ b/packages/utils/ast-utils.ts @@ -570,7 +570,7 @@ function removeProperty(j: JSCodeshift, ast: Node, key: string, value: valueType * @returns ast - jscodeshift API */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars +// eslint-disable-next-line @typescript-eslint/no-unused-vars function parseTopScope(j: JSCodeshift, ast: Node, value: string[], action: string): boolean | Node { function createTopScopeProperty(p: Node): boolean { value.forEach( diff --git a/packages/utils/modify-config-helper.ts b/packages/utils/modify-config-helper.ts index 5d25385c8c0..d27b37bd608 100644 --- a/packages/utils/modify-config-helper.ts +++ b/packages/utils/modify-config-helper.ts @@ -5,7 +5,6 @@ import * as path from "path"; import * as yeoman from "yeoman-environment"; import * as Generator from "yeoman-generator"; - import runTransform from "./scaffold"; export interface Config extends Object { @@ -87,11 +86,12 @@ export default function modifyHelperUtil( } }; } - + env.registerStub(generator, generatorName); env.run(generatorName, { configFile - }).then( + }) + .then( (): void => { let configModule: object; try { diff --git a/packages/utils/prop-types.ts b/packages/utils/prop-types.ts index 894ec0e3c47..cccf77a1079 100644 --- a/packages/utils/prop-types.ts +++ b/packages/utils/prop-types.ts @@ -34,7 +34,7 @@ const PROP_TYPES: Set = new Set([ "target", "topScope", "watch", - "watchOptions", + "watchOptions" ]); export default PROP_TYPES; diff --git a/packages/utils/run-prettier.ts b/packages/utils/run-prettier.ts index bf4980150d9..5f0537f82ef 100644 --- a/packages/utils/run-prettier.ts +++ b/packages/utils/run-prettier.ts @@ -22,14 +22,14 @@ export default function runPrettier(outputPath: string, source: string, cb?: Fun parser: "babel", singleQuote: true, tabWidth: 1, - useTabs: true, + useTabs: true }); } catch (err) { process.stdout.write( `\n${chalk.yellow( `WARNING: Could not apply prettier to ${outputPath}` + - " due validation error, but the file has been created\n", - )}`, + " due validation error, but the file has been created\n" + )}` ); prettySource = source; error = err; diff --git a/packages/utils/scaffold.ts b/packages/utils/scaffold.ts index 8da1fd7df79..f842d3a777e 100644 --- a/packages/utils/scaffold.ts +++ b/packages/utils/scaffold.ts @@ -70,35 +70,39 @@ export default function runTransform(transformConfig: TransformConfig, action: s return astTransform(j, ast, f, config[f] as any, transformAction); } return astTransform(j, ast, f, config.webpackOptions[f], transformAction); - }) - .then((): void | PromiseLike => { - let configurationName: string; - if (!config.configName) { - configurationName = "webpack.config.js"; - } else { - configurationName = "webpack." + config.configName + ".js"; + } + ) + .then( + (): void | PromiseLike => { + let configurationName: string; + if (!config.configName) { + configurationName = "webpack.config.js"; + } else { + configurationName = "webpack." + config.configName + ".js"; + } + const projectRoot = findProjectRoot(); + const outputPath: string = initActionNotDefined + ? transformConfig.configPath + : path.join(projectRoot || process.cwd(), configurationName); + const source: string = ast.toSource({ + quote: "single" + }); + runPrettier(outputPath, source); } - const projectRoot = findProjectRoot(); - const outputPath: string = initActionNotDefined - ? transformConfig.configPath - : path.join(projectRoot || process.cwd(), configurationName); - const source: string = ast.toSource({ - quote: "single", - }); - runPrettier(outputPath, source); - }) - .catch((err: Error): void => { - console.error(err.message ? err.message : err); - }); - }); + ) + .catch( + (err: Error): void => { + console.error(err.message ? err.message : err); + } + ); + } + ); let successMessage: string = chalk.green(`Congratulations! Your new webpack configuration file has been created!\n\n`) + `You can now run ${chalk.green("npm run start")} to run your project!\n\n`; if (initActionNotDefined && transformConfig.config.item) { - successMessage = chalk.green(`Congratulations! ${ - transformConfig.config.item - } has been ${action}ed!\n`); + successMessage = chalk.green(`Congratulations! ${transformConfig.config.item} has been ${action}ed!\n`); } process.stdout.write(`\n${successMessage}`); } diff --git a/packages/utils/types/NodePath.ts b/packages/utils/types/NodePath.ts index 1b828378ddb..66098c06894 100644 --- a/packages/utils/types/NodePath.ts +++ b/packages/utils/types/NodePath.ts @@ -39,11 +39,7 @@ export interface Node extends Object { size?: () => number; type?: string; value?: Node | string | Node[]; - toSource?: ( - object: { - quote?: string; - } - ) => string; + toSource?: (object: { quote?: string }) => string; source?: string; ast?: Node; rules?: ModuleRule[]; diff --git a/packages/webpack-scaffold/__tests__/index.test.ts b/packages/webpack-scaffold/__tests__/index.test.ts index 2d0ccef8582..f6b4d238c8d 100755 --- a/packages/webpack-scaffold/__tests__/index.test.ts +++ b/packages/webpack-scaffold/__tests__/index.test.ts @@ -17,9 +17,7 @@ describe("utils", () => { expect(utils.createDynamicPromise("app.js")).toMatchSnapshot(); }); it("should stringify an array", () => { - expect( - utils.createDynamicPromise(["app.js", "index.js"]), - ).toMatchSnapshot(); + expect(utils.createDynamicPromise(["app.js", "index.js"])).toMatchSnapshot(); }); }); describe("createAssetFilterFunction", () => { @@ -51,34 +49,30 @@ describe("utils", () => { choices: ["Yes", "Maybe"], message: "does it work?", name: "entry", - type: "list", + type: "list" }); }); it("should make a RawList object", () => { - expect( - utils.RawList("output", "does it work?", ["Yes", "Maybe"]), - ).toEqual({ + expect(utils.RawList("output", "does it work?", ["Yes", "Maybe"])).toEqual({ choices: ["Yes", "Maybe"], message: "does it work?", name: "output", - type: "rawlist", + type: "rawlist" }); }); it("should make a CheckList object", () => { - expect( - utils.CheckList("context", "does it work?", ["Yes", "Maybe"]), - ).toEqual({ + expect(utils.CheckList("context", "does it work?", ["Yes", "Maybe"])).toEqual({ choices: ["Yes", "Maybe"], message: "does it work?", name: "context", - type: "checkbox", + type: "checkbox" }); }); it("should make an Input object", () => { expect(utils.Input("plugins", "what is your plugin?")).toEqual({ message: "what is your plugin?", name: "plugins", - type: "input", + type: "input" }); }); it("should make an Input object", () => { @@ -86,7 +80,7 @@ describe("utils", () => { default: "my-plugin", message: "what is your plugin?", name: "plugins", - type: "input", + type: "input" }); }); it("should make a Confirm object", () => { @@ -94,7 +88,7 @@ describe("utils", () => { default: true, message: "what is your context?", name: "context", - type: "confirm", + type: "confirm" }); }); it("should make a Confirm object with No as default", () => { @@ -102,18 +96,14 @@ describe("utils", () => { default: false, message: "what is your context?", name: "context", - type: "confirm", + type: "confirm" }); }); it("should make an Input object with validation", () => { - expect( - utils.InputValidate("plugins", "what is your plugin?", () => true), - ).toMatchSnapshot(); + expect(utils.InputValidate("plugins", "what is your plugin?", () => true)).toMatchSnapshot(); }); it("should make an Input object with validation and default value", () => { - expect( - utils.InputValidate("plugins", "what is your plugin?", () => true, "my-plugin"), - ).toMatchSnapshot(); + expect(utils.InputValidate("plugins", "what is your plugin?", () => true, "my-plugin")).toMatchSnapshot(); }); }); }); diff --git a/packages/webpack-scaffold/index.ts b/packages/webpack-scaffold/index.ts index 6c609b8e522..77a0a7bcf6f 100755 --- a/packages/webpack-scaffold/index.ts +++ b/packages/webpack-scaffold/index.ts @@ -86,11 +86,11 @@ export function Input(name: string, message: string, defaultChoice?: string): Ge } export function InputValidate( - name: string, - message: string, - cb?: (input: string) => string | boolean, - defaultChoice?: string, - ): Generator.Question { + name: string, + message: string, + cb?: (input: string) => string | boolean, + defaultChoice?: string +): Generator.Question { const input: Generator.Question = { message, name, From c7c1a830eab3c9f5b68210ce28c4087d91ad82de Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Thu, 30 May 2019 19:19:25 +0200 Subject: [PATCH 50/50] chore: fix linting --- .eslintignore | 3 ++- packages/init/init.ts | 2 +- packages/utils/package-manager.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.eslintignore b/.eslintignore index 05bb8944870..f6c8e2019eb 100644 --- a/.eslintignore +++ b/.eslintignore @@ -9,4 +9,5 @@ test/**/null.js test/**/main.js test/**/cliEntry.js test/**/foo.js -test/binCases/config-location/webpack-babel-config/bin/es6.js \ No newline at end of file +test/binCases/config-location/webpack-babel-config/bin/es6.js +packages/utils/validate-identifier.ts \ No newline at end of file diff --git a/packages/init/init.ts b/packages/init/init.ts index b4063cd15e9..2cd0bef21e3 100644 --- a/packages/init/init.ts +++ b/packages/init/init.ts @@ -81,7 +81,7 @@ export default function runTransform(webpackProperties: WebpackProperties, actio } ); - let successMessage: string = `Congratulations! Your new webpack configuration file has been created!`; + let successMessage = `Congratulations! Your new webpack configuration file has been created!`; if (initActionNotDefined && webpackProperties.config.item) { successMessage = `Congratulations! ${webpackProperties.config.item} has been ${action}ed!`; } diff --git a/packages/utils/package-manager.ts b/packages/utils/package-manager.ts index 888b974ef18..87bf62e59bb 100644 --- a/packages/utils/package-manager.ts +++ b/packages/utils/package-manager.ts @@ -102,7 +102,7 @@ export function spawnChild(pkg: string): SpawnSyncReturns { const rootPath: string = getPathToGlobalPackages(); const pkgPath: string = path.resolve(rootPath, pkg); const packageManager: string = getPackageManager(); - const isNew: boolean = !fs.existsSync(pkgPath); + const isNew = !fs.existsSync(pkgPath); return SPAWN_FUNCTIONS[packageManager](pkg, isNew); }