From 0a2274ec18b9c9e77b02d80a61c2ce150f91078f Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Sat, 23 Mar 2019 20:49:17 +0530 Subject: [PATCH 01/39] 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 3e870e244ab08f396db7f6b83624e84ee7f9650a Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Wed, 27 Mar 2019 03:35:44 +0530 Subject: [PATCH 02/39] fix(scaffold): config file is always generated at the project root (#801) * fix(scaffold): config file is always generated at the project root config file is generated at the project root * chore(scaffold): add package-lock for utils add package-lock for utils as new dep was introduced * chore(utils): fix ci fix ci * fix(scaffold): migrated to findup-sync to find the project root migrated to use find-up sync to determine project root, removed additional packages * chore(utils): added findup-sync package to utils package added findup-sync to utils package * chore(scaffold): do not pass process.cwd() do not pass process.cwd() --- packages/utils/find-root.ts | 8 + packages/utils/package-lock.json | 340 +++++++++++++++++++++++++++---- packages/utils/package.json | 1 + packages/utils/scaffold.ts | 9 +- 4 files changed, 316 insertions(+), 42 deletions(-) create mode 100644 packages/utils/find-root.ts diff --git a/packages/utils/find-root.ts b/packages/utils/find-root.ts new file mode 100644 index 00000000000..9e1baf5b1a6 --- /dev/null +++ b/packages/utils/find-root.ts @@ -0,0 +1,8 @@ +import * as findup from "findup-sync"; +import * as path from "path"; + +export function findProjectRoot(): string { + const rootFilePath = findup(`package.json`); + const projectRoot = path.dirname(rootFilePath); + return projectRoot; +} diff --git a/packages/utils/package-lock.json b/packages/utils/package-lock.json index d0ff77c38cb..5c04b28b295 100644 --- a/packages/utils/package-lock.json +++ b/packages/utils/package-lock.json @@ -1,6 +1,6 @@ { "name": "@webpack-cli/utils", - "version": "0.1.3", + "version": "0.1.5", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1935,6 +1935,11 @@ "resolved": "https://registry.npmjs.org/detect-conflict/-/detect-conflict-1.0.1.tgz", "integrity": "sha1-CIZXpmqWHAUBnbfEIwiDsca0F24=" }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", @@ -2583,6 +2588,280 @@ "locate-path": "^2.0.0" } }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, "first-chunk-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", @@ -2663,8 +2942,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -2682,13 +2960,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2701,18 +2977,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -2815,8 +3088,7 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -2826,7 +3098,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2839,20 +3110,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.2.4", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -2869,7 +3137,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -2942,8 +3209,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -2953,7 +3219,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -3029,8 +3294,7 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -3060,7 +3324,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3078,7 +3341,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3117,13 +3379,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.0.2", - "bundled": true, - "optional": true + "bundled": true } } }, @@ -3534,6 +3794,16 @@ "requires": { "pkg-dir": "^2.0.0", "resolve-cwd": "^2.0.0" + }, + "dependencies": { + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "requires": { + "find-up": "^2.1.0" + } + } } }, "imurmurhash": { @@ -5299,14 +5569,6 @@ "pinkie": "^2.0.0" } }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "requires": { - "find-up": "^2.1.0" - } - }, "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", diff --git a/packages/utils/package.json b/packages/utils/package.json index 620aeaf5a2b..512f289e354 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -12,6 +12,7 @@ "dependencies": { "chalk": "^2.4.1", "cross-spawn": "^6.0.5", + "findup-sync": "^3.0.0", "global-modules": "^1.0.0", "got": "8.x.x", "jest": "^23.6.0", diff --git a/packages/utils/scaffold.ts b/packages/utils/scaffold.ts index c1bd9ecbeca..7aa5ff7eb63 100644 --- a/packages/utils/scaffold.ts +++ b/packages/utils/scaffold.ts @@ -2,7 +2,9 @@ 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 { IError } from "../init/types"; import { IConfig, ITransformConfig } from "./modify-config-helper"; import propTypes from "./prop-types"; import astTransform from "./recursive-parser"; @@ -74,14 +76,15 @@ export default function runTransform(transformConfig: ITransformConfig, action: configurationName = "webpack." + config.configName + ".js"; } + const projectRoot = findProjectRoot(); const outputPath: string = initActionNotDefined - ? transformConfig.configPath - : path.join(process.cwd(), configurationName); + ? 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); From b26cd903c59577a57b24f104f8545da04070b5b9 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Fri, 29 Mar 2019 13:18:49 +0530 Subject: [PATCH 03/39] chore(tests): updated test regex, some helper scripts (#809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISSUES CLOSED: #808 **What kind of change does this PR introduce?** Updated test regex to run all tests, added some helper scripts for running tests **Did you add tests for your changes?** Yes **If relevant, did you update the documentation?** Yes **Summary** * Updated tests regex to run all tests * Added helper scripts to run cli and package tests separately **Does this PR introduce a breaking change?** No **Other information** --- .github/CONTRIBUTING.md | 24 +++++++++++++++++++ package.json | 7 +++++- .../stats/single-config/single-config.test.js | 4 ++-- .../info-verbosity-off.test.js | 2 +- .../info-verbosity-verbose.test.js | 2 +- .../multi-config-watch-opt.test.js | 2 +- .../watch/multi-config/multi-config.test.js | 2 +- .../single-config-watch-opt.test.js | 2 +- .../watch/single-config/single-config.test.js | 2 +- 9 files changed, 38 insertions(+), 9 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 4ed7f17ccba..8f937259c0c 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -83,6 +83,18 @@ In case you are suggesting a new feature, we will match your idea with our curre npm run test ``` +* Run CLI tests with: + + ```bash + npm run test:cli + ``` + +* Run tests of all packages: + + ```bash + npm run test:packages + ``` + * Test a single CLI test case: ```bash @@ -110,6 +122,18 @@ In case you are suggesting a new feature, we will match your idea with our curre yarn test ``` +* Run CLI tests with: + + ```bash + yarn test:cli` + ``` + +* Run tests of all packages: + + ```bash + yarn test:packages + ``` + * Test a single CLI test case: ```bash diff --git a/package.json b/package.json index 06baa84f421..8e0eeb180fd 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,8 @@ "pretest": "npm run build && npm run lint && npm run tslint", "reportCoverage": "nyc report --reporter=json && codecov -f coverage/coverage-final.json --disable=gcov", "test": "nyc jest --maxWorkers=4 --reporters=default --reporters=jest-junit", + "test:cli": "nyc jest test/ --maxWorkers=4 --reporters=default --reporters=jest-junit", + "test:packages": "nyc jest packages/ --maxWorkers=4 --reporters=default --reporters=jest-junit", "test:ci": "nyc jest --maxWorkers=$(nproc) --reporters=default --reporters=jest-junit", "travis:integration": "npm run build && npm run test && npm run reportCoverage", "travis:lint": "npm run build && npm run lint && npm run tslint", @@ -76,7 +78,10 @@ "transform": { "^.+\\.(ts)?$": "ts-jest" }, - "testRegex": "/__tests__/.*\\.(test.js|test.ts)$", + "testRegex": [ + "/__tests__/.*\\.(test.js|test.ts)$", + "/test/.*\\.(test.js|test.ts)$" + ], "moduleFileExtensions": [ "ts", "js", diff --git a/test/binCases/stats/single-config/single-config.test.js b/test/binCases/stats/single-config/single-config.test.js index e7b29b4a12c..e8f50126247 100644 --- a/test/binCases/stats/single-config/single-config.test.js +++ b/test/binCases/stats/single-config/single-config.test.js @@ -6,8 +6,8 @@ jest.setTimeout(10E6); const { run, extractSummary } = require("../../../testUtils"); -test("single-config", async done => { - const { code, stdout, stderr } = await run(__dirname); +test("single-config", done => { + const { code, stdout, stderr } = run(__dirname); const summary = extractSummary(stdout); diff --git a/test/binCases/watch/info-verbosity-off/info-verbosity-off.test.js b/test/binCases/watch/info-verbosity-off/info-verbosity-off.test.js index 10313d086bf..bb416f354bd 100644 --- a/test/binCases/watch/info-verbosity-off/info-verbosity-off.test.js +++ b/test/binCases/watch/info-verbosity-off/info-verbosity-off.test.js @@ -28,7 +28,7 @@ afterEach(() => { } }); -test.skip("info-verbosity-off", async done => { +test.skip("info-verbosity-off", done => { var webpackProc = runAndGetWatchProc(__dirname, [ "--entry ", "./index.js", diff --git a/test/binCases/watch/info-verbosity-verbose/info-verbosity-verbose.test.js b/test/binCases/watch/info-verbosity-verbose/info-verbosity-verbose.test.js index c3ccd9102e4..5b6b3972189 100644 --- a/test/binCases/watch/info-verbosity-verbose/info-verbosity-verbose.test.js +++ b/test/binCases/watch/info-verbosity-verbose/info-verbosity-verbose.test.js @@ -28,7 +28,7 @@ afterEach(() => { } }); -test.skip("info-verbosity-verbose", async done => { +test.skip("info-verbosity-verbose", done => { const webpackProc = runAndGetWatchProc(__dirname, [ "--entry ", "./index.js", diff --git a/test/binCases/watch/multi-config-watch-opt/multi-config-watch-opt.test.js b/test/binCases/watch/multi-config-watch-opt/multi-config-watch-opt.test.js index 1b691428608..a89fb1b53e8 100644 --- a/test/binCases/watch/multi-config-watch-opt/multi-config-watch-opt.test.js +++ b/test/binCases/watch/multi-config-watch-opt/multi-config-watch-opt.test.js @@ -28,7 +28,7 @@ afterEach(() => { } }); -test.skip("multi-config-watch-opt", async done => { +test.skip("multi-config-watch-opt", done => { const webpackProc = runAndGetWatchProc(__dirname, [ "--entry", "./index.js", diff --git a/test/binCases/watch/multi-config/multi-config.test.js b/test/binCases/watch/multi-config/multi-config.test.js index fbb4f055d58..7738b81472d 100644 --- a/test/binCases/watch/multi-config/multi-config.test.js +++ b/test/binCases/watch/multi-config/multi-config.test.js @@ -28,7 +28,7 @@ afterEach(() => { } }); -test.skip("multi-config", async done => { +test.skip("multi-config", done => { const webpackProc = runAndGetWatchProc(__dirname); // info-verbosity is set to info by default diff --git a/test/binCases/watch/single-config-watch-opt/single-config-watch-opt.test.js b/test/binCases/watch/single-config-watch-opt/single-config-watch-opt.test.js index 1d1ab6be2f5..47c512c47ce 100644 --- a/test/binCases/watch/single-config-watch-opt/single-config-watch-opt.test.js +++ b/test/binCases/watch/single-config-watch-opt/single-config-watch-opt.test.js @@ -28,7 +28,7 @@ afterEach(() => { } }); -test.skip("single-config-watch-opt", async done => { +test.skip("single-config-watch-opt", done => { const webpackProc = runAndGetWatchProc(__dirname, [ "--entry", "./index.js", diff --git a/test/binCases/watch/single-config/single-config.test.js b/test/binCases/watch/single-config/single-config.test.js index 51fca537634..1865cd130a9 100644 --- a/test/binCases/watch/single-config/single-config.test.js +++ b/test/binCases/watch/single-config/single-config.test.js @@ -28,7 +28,7 @@ afterEach(() => { } }); -test.skip("single-config", async(done) => { +test.skip("single-config", done => { const webpackProc = runAndGetWatchProc(__dirname, [ "--entry", "./index.js", From 6cfed0fee0ebf455311be3aa315b663e99a4bcf5 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Mon, 1 Apr 2019 23:12:24 +0530 Subject: [PATCH 04/39] fix(init): refactored the init.ts success message (#810) Previously there was multiple `stdout.write` due to the presence of conditional statements. In this PR I have scrapped those repeating lines into a single `process.stdout.write` **What kind of change does this PR introduce?** Refactoring **Did you add tests for your changes?** No **If relevant, did you update the documentation?** Can't say **Does this PR introduce a breaking change?** Probably not --- packages/init/init.ts | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/init/init.ts b/packages/init/init.ts index 5e77c0075b6..1b60fe34c7e 100644 --- a/packages/init/init.ts +++ b/packages/init/init.ts @@ -78,21 +78,10 @@ export default function runTransform(webpackProperties: IWebpackProperties, acti }); }); + let successMessage: string = `Congratulations! Your new webpack configuration file has been created!`; if (initActionNotDefined && webpackProperties.config.item) { - process.stdout.write( - "\n" + - chalk.green( - `Congratulations! ${ - webpackProperties.config.item - } has been ${action}ed!\n`, - ), - ); - } else { - process.stdout.write( - "\n" + - chalk.green( - "Congratulations! Your new webpack configuration file has been created!\n", - ), - ); + successMessage = `Congratulations! ${webpackProperties.config.item} has been ${action}ed!`; + } + process.stdout.write("\n" + chalk.green(`${successMessage}\n`)); } From b96857f182481623db2c1fc799fdab59dab81107 Mon Sep 17 00:00:00 2001 From: Loonride Date: Tue, 2 Apr 2019 05:26:54 -0500 Subject: [PATCH 05/39] fix(bin, serve): force default package export, add serve default (#815) * fix(prompt-command, serve): force default package export, add serve default ISSUES CLOSED: #572 * misc(serve): remove unnecessary exports, update docs --- bin/utils/prompt-command.js | 16 +++++++++++----- packages/serve/README.md | 2 +- packages/serve/index.ts | 11 ++--------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/bin/utils/prompt-command.js b/bin/utils/prompt-command.js index 021fa90527b..907434c6c71 100644 --- a/bin/utils/prompt-command.js +++ b/bin/utils/prompt-command.js @@ -37,6 +37,15 @@ const npmGlobalRoot = () => { }); }; +const runWhenInstalled = (packages, pathForCmd, ...args) => { + const package = require(pathForCmd); + const func = package.default; + 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; let packageIsInstalled = false; @@ -113,10 +122,7 @@ module.exports = function promptForInstallation(packages, ...args) { } pathForCmd = path.resolve(process.cwd(), "node_modules", "@webpack-cli", packages); - if (packages === "serve") { - return require(pathForCmd).default.serve(); - } - return require(pathForCmd).default(...args); //eslint-disable-line + return runWhenInstalled(packages, pathForCmd, ...args); }) .catch(error => { console.error(error); @@ -132,6 +138,6 @@ module.exports = function promptForInstallation(packages, ...args) { } }); } else { - require(pathForCmd).default(...args); // eslint-disable-line + return runWhenInstalled(packages, pathForCmd, ...args); } }; diff --git a/packages/serve/README.md b/packages/serve/README.md index eb647361781..a6612b6f9be 100644 --- a/packages/serve/README.md +++ b/packages/serve/README.md @@ -16,7 +16,7 @@ To run the scaffolding instance programmatically, install it as a dependency. Wh ### Node ```js -const serve = require("@webpack-cli/serve").serve; +const serve = require("@webpack-cli/serve").default; serve(); ``` diff --git a/packages/serve/index.ts b/packages/serve/index.ts index d4fa9cad4a0..950ae78d3b7 100644 --- a/packages/serve/index.ts +++ b/packages/serve/index.ts @@ -47,11 +47,11 @@ const getRootPathModule = (dep: string): string => path.resolve(process.cwd(), d * * Prompts for installing the devServer and running it * - * @param {Object} args - args processed from the CLI + * @param {String[]} args - args processed from the CLI * @returns {Function} invokes the devServer API */ -function serve() { +export default function serve(...args: string[]) { const packageJSONPath = getRootPathModule("package.json"); if (!packageJSONPath) { console.error( @@ -169,10 +169,3 @@ function serve() { }); } } - -export = { - getRootPathModule, - serve, - spawnNPMWithArg, - spawnYarnWithArg, -}; From 0b28fb337a1a9c491d2b5aacbc8ca9300f057906 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Sat, 6 Apr 2019 19:48:12 +0530 Subject: [PATCH 06/39] misc(utils): refactors scaffold refactors the conditional statements in scaffold.ts --- packages/utils/scaffold.ts | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/packages/utils/scaffold.ts b/packages/utils/scaffold.ts index 7aa5ff7eb63..682f91ae989 100644 --- a/packages/utils/scaffold.ts +++ b/packages/utils/scaffold.ts @@ -90,22 +90,16 @@ export default function runTransform(transformConfig: ITransformConfig, action: console.error(err.message ? err.message : err); }); }); - + let successMessage : string = `Congratulations! Your new webpack configuration file has been created!\n` if (initActionNotDefined && transformConfig.config.item) { - process.stdout.write( - "\n" + - chalk.green( - `Congratulations! ${ - transformConfig.config.item - } has been ${action}ed!\n`, - ), - ); - } else { - process.stdout.write( - "\n" + - chalk.green( - "Congratulations! Your new webpack configuration file has been created!\n", - ), - ); + successMessage = `Congratulations! ${ + transformConfig.config.item + } has been ${action}ed!\n` } + process.stdout.write( + "\n" + + chalk.green( + successMessage + ) + ); } From 7fe35435a75b89fbce10c4a0281a75b3030a7edb Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Thu, 11 Apr 2019 14:52:25 +0530 Subject: [PATCH 07/39] fix(utils): refactors utils impoves the codebase by adding comments --- junit.xml | 632 +++++++++++++++++------------------ packages/utils/defineTest.ts | 1 + packages/utils/find-root.ts | 6 + packages/utils/scaffold.ts | 8 +- 4 files changed, 327 insertions(+), 320 deletions(-) diff --git a/junit.xml b/junit.xml index 304ccef7cc6..319cffbd123 100644 --- a/junit.xml +++ b/junit.xml @@ -1,149 +1,199 @@ - - - + + + - + - + - + - + - + - + - + + + - - - + + - - + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - - - + + - - - + + - - - + + - - - + + - - + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + - + + + - + + + - + + + - + + + - + + + - - - + + - - + + - + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -155,403 +205,353 @@ - + - + - - - - - - + + - - + + - + + + - + - + - + - + - - - + - + - + - + - + - + - + - - - + - + - + - + - + + + - + + + - + + + - + + + - + - + - + - - - + - + - + - + - - + + - - + + - - - + - - - + - - + + - - - - - - - - + + - - + + - - + + - - + + - - - + + - - - + - - - + - + - - - + - - - + - - - + - - - + - - - + - - + + - - - + - + - + - + - + - + - + - + - + - - - - + - - + + - - + + + + + + - - + + - + - + - + - + - - + + - - - + - - - + - + - - + + - - - + - - - + - - - + - - - + - - - + - - - + - + - - - + - - + + - - + + - - - + - - - + - - - + - - - + - - + + - + - + - - - + - - + + + + + + - - + + - + - + - + - - + + + - - + + + - - + + - + - + - - - - - - - - + + + - - + + + - - + + + - - - - - - + + + - - + + + - - + + + - - + + - - - + - + - + + + - - + + - + - + - - + + - + - + - - - + - - + + - - - + - - + + - - - + + + + + + + + + \ No newline at end of file diff --git a/packages/utils/defineTest.ts b/packages/utils/defineTest.ts index b5b076cfa4b..a5ee041d26f 100644 --- a/packages/utils/defineTest.ts +++ b/packages/utils/defineTest.ts @@ -1,5 +1,6 @@ import * as fs from "fs"; import * as path from "path"; + import { IJSCodeshift, INode } from "./types/NodePath"; interface IModule { diff --git a/packages/utils/find-root.ts b/packages/utils/find-root.ts index 9e1baf5b1a6..0345da2db62 100644 --- a/packages/utils/find-root.ts +++ b/packages/utils/find-root.ts @@ -1,6 +1,12 @@ 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); diff --git a/packages/utils/scaffold.ts b/packages/utils/scaffold.ts index 682f91ae989..a3add9ee769 100644 --- a/packages/utils/scaffold.ts +++ b/packages/utils/scaffold.ts @@ -90,16 +90,16 @@ export default function runTransform(transformConfig: ITransformConfig, action: console.error(err.message ? err.message : err); }); }); - let successMessage : string = `Congratulations! Your new webpack configuration file has been created!\n` + let successMessage: string = `Congratulations! Your new webpack configuration file has been created!\n`; if (initActionNotDefined && transformConfig.config.item) { successMessage = `Congratulations! ${ transformConfig.config.item - } has been ${action}ed!\n` + } has been ${action}ed!\n`; } process.stdout.write( "\n" + chalk.green( - successMessage - ) + successMessage, + ), ); } From 74179b5a94acc5b15e0b936a3321c4f03c01ef2b Mon Sep 17 00:00:00 2001 From: Rishabh Chawla Date: Sat, 13 Apr 2019 16:54:02 +0530 Subject: [PATCH 08/39] docs(README): update scaffolding links Links from webpack.js.org --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f25b9208ac..2c9befb35a3 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ You will answer many questions when running the `init` so webpack CLI can provid With v3 of webpack CLI, we introduced scaffolding as an integral part of the CLI. Our goal is to simplify the creation of webpack configurations for different purposes. Additionally, sharing such solutions with the community is beneficial and with webpack webpack's we want to allow this. We provide `webpack-scaffold` as a utility suite for creating these scaffolds. It contains functions that could be of use for creating an scaffold yourself. -You can read more about [Scaffolding](./SCAFFOLDING.md) or check out the example project [How do I compose a webpack-scaffold?](https://github.com/evenstensberg/webpack-scaffold-demo). +You can read more about [Scaffolding](https://webpack.js.org/guides/scaffolding) or learn [How to compose a webpack-scaffold?](https://webpack.js.org/contribute/writing-a-scaffold). ## Contributing and Internal Documentation From e35a194bebee233a23076a8d591606ab21d7e594 Mon Sep 17 00:00:00 2001 From: Rishabh Chawla Date: Sat, 13 Apr 2019 16:59:38 +0530 Subject: [PATCH 09/39] docs(README): add link to webpack-scaffold-starter --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c9befb35a3..4a51ed0966a 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ You will answer many questions when running the `init` so webpack CLI can provid With v3 of webpack CLI, we introduced scaffolding as an integral part of the CLI. Our goal is to simplify the creation of webpack configurations for different purposes. Additionally, sharing such solutions with the community is beneficial and with webpack webpack's we want to allow this. We provide `webpack-scaffold` as a utility suite for creating these scaffolds. It contains functions that could be of use for creating an scaffold yourself. -You can read more about [Scaffolding](https://webpack.js.org/guides/scaffolding) or learn [How to compose a webpack-scaffold?](https://webpack.js.org/contribute/writing-a-scaffold). +You can read more about [Scaffolding](https://webpack.js.org/guides/scaffolding), learn [How to compose a webpack-scaffold?](https://webpack.js.org/contribute/writing-a-scaffold) or start writing scaffolds with [webpack-scaffold-starter](https://github.com/rishabh3112/webpack-scaffold-starter) on the go. ## Contributing and Internal Documentation From 3a11a16e83dce66604d5de2b3241b92350170b75 Mon Sep 17 00:00:00 2001 From: Rishabh Chawla Date: Sat, 13 Apr 2019 17:02:59 +0530 Subject: [PATCH 10/39] docs(README): phrase change --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a51ed0966a..f3aad250670 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ You will answer many questions when running the `init` so webpack CLI can provid With v3 of webpack CLI, we introduced scaffolding as an integral part of the CLI. Our goal is to simplify the creation of webpack configurations for different purposes. Additionally, sharing such solutions with the community is beneficial and with webpack webpack's we want to allow this. We provide `webpack-scaffold` as a utility suite for creating these scaffolds. It contains functions that could be of use for creating an scaffold yourself. -You can read more about [Scaffolding](https://webpack.js.org/guides/scaffolding), learn [How to compose a webpack-scaffold?](https://webpack.js.org/contribute/writing-a-scaffold) or start writing scaffolds with [webpack-scaffold-starter](https://github.com/rishabh3112/webpack-scaffold-starter) on the go. +You can read more about [Scaffolding](https://webpack.js.org/guides/scaffolding), learn [How to compose a webpack-scaffold?](https://webpack.js.org/contribute/writing-a-scaffold) or generate one with [webpack-scaffold-starter](https://github.com/rishabh3112/webpack-scaffold-starter). ## Contributing and Internal Documentation From 80fd4facdd49a46c7deeaa9bcab5998c2ef93337 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Sun, 14 Apr 2019 03:01:43 +0530 Subject: [PATCH 11/39] chore(junit): reverting the junit.xml --- junit.xml | 632 +++++++++++++++++++++++++++--------------------------- 1 file changed, 316 insertions(+), 316 deletions(-) diff --git a/junit.xml b/junit.xml index 319cffbd123..304ccef7cc6 100644 --- a/junit.xml +++ b/junit.xml @@ -1,199 +1,149 @@ - - - + + + - + - + - + - + - + - + - - - + - - + + + - - + + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - + + + - - + + + - - + + + - - + + + - - + + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - - - + - + - - - + - - - + - - - + - - - + - - - + - - - - - - - - - - - - - - + + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -205,353 +155,403 @@ - + - + - - + + - - - + + + - - + + - + - + - + - + - + - + + + - + - + - + - + - + - + - + + + - + - + - - - + - - - + - - - + - - - + - + - + - + - + - + + + - + - + - - - + - - + + - + + + - + + + - - + + - - + + - - + + + + + + + + - - + + - - + + - - + + - + + + + - + + + - + + + - + - + + + - + + + - + + + - + + + - - + + - + + + - + + + - + - + - + - + - + - + - + - + - - + + + - - - - + + - + + + - - + + - + - + - + - + - - + + - + + + - + + + - + - - - - + + - + + + - + + + - + + + - + + + - + + + - + + + - + - - + + - - + + - + + + - + + + - + + + - + + + - - + + - + + + - + - + - - - + - + - + + + - - + + - + - + - + - - - + + - - - + + - - + + - + - + - - - + + - - - - + - - - - + - - - - + - - - + + - - - + + - - + + - + - + - - + + - - - - - - + + - - + + - + + + - + - + - - + + - + + + - - + + - + + + + + + + - + + + - + + + - + + + - + + + \ No newline at end of file From 958d06415801ad6263c36ca50171c92c74b22180 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Sun, 14 Apr 2019 15:00:53 +0530 Subject: [PATCH 12/39] docs(readme): adds contributors shield adds the shield for the total number of contributors --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3f25b9208ac..0afe9347c2e 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ [![Install Size](https://packagephobia.now.sh/badge?p=webpack-cli)](https://packagephobia.now.sh/result?p=webpack-cli) [![npm](https://img.shields.io/npm/dw/webpack-cli.svg)](https://www.npmjs.com/package/webpack-cli) [![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lernajs.io/) +[![GitHub contributors](https://img.shields.io/github/contributors/webpack/webpack-cli.svg)](https://github.com/webpack/webpack-cli/graphs/contributors) * [About](#about) From 68160577b14b7652f9fe36425c7fef8e10a42e98 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Sun, 14 Apr 2019 22:03:30 +0530 Subject: [PATCH 13/39] chore(deps): upgrade lerna to fix vulnerabilities & update webpack-dev-server (#823) * chore(deps): upgrade lerna to fix vulnerabilities Upgrade lerna to fix vulnerabilities ISSUES CLOSED: #822 * chore(cli): update webpack-dev-server update webpack-dev-server to the latest version --- package-lock.json | 388 +++++++++++++++++++++------------------------- package.json | 4 +- 2 files changed, 180 insertions(+), 212 deletions(-) diff --git a/package-lock.json b/package-lock.json index 741b984d2a2..3fa90818763 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1403,16 +1403,16 @@ } }, "@lerna/changed": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.13.1.tgz", - "integrity": "sha512-BRXitEJGOkoudbxEewW7WhjkLxFD+tTk4PrYpHLyCBk63pNTWtQLRE6dc1hqwh4emwyGncoyW6RgXfLgMZgryw==", + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.13.2.tgz", + "integrity": "sha512-mcmkxUMR0J4ZyRyVUrdDJl4ZsdHDgdA1xQcbdB4LZvAE/E2lNlPcEfAfbfs08VnRiqvFOqcczbzBq10hvSFg4w==", "dev": true, "requires": { "@lerna/collect-updates": "3.13.0", "@lerna/command": "3.13.1", "@lerna/listable": "3.13.0", "@lerna/output": "3.13.0", - "@lerna/version": "3.13.1" + "@lerna/version": "3.13.2" } }, "@lerna/check-working-tree": { @@ -1859,15 +1859,16 @@ } }, "@lerna/npm-publish": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.13.0.tgz", - "integrity": "sha512-y4WO0XTaf9gNRkI7as6P2ItVDOxmYHwYto357fjybcnfXgMqEA94c3GJ++jU41j0A9vnmYC6/XxpTd9sVmH9tA==", + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.13.2.tgz", + "integrity": "sha512-HMucPyEYZfom5tRJL4GsKBRi47yvSS2ynMXYxL3kO0ie+j9J7cb0Ir8NmaAMEd3uJWJVFCPuQarehyfTDZsSxg==", "dev": true, "requires": { "@lerna/run-lifecycle": "3.13.0", "figgy-pudding": "^3.5.1", "fs-extra": "^7.0.0", "libnpmpublish": "^1.1.1", + "npm-package-arg": "^6.1.0", "npmlog": "^4.1.2", "pify": "^3.0.0", "read-package-json": "^2.0.13" @@ -1975,15 +1976,14 @@ }, "dependencies": { "cosmiconfig": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.1.0.tgz", - "integrity": "sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.0.tgz", + "integrity": "sha512-nxt+Nfc3JAqf4WIWd0jXLjTJZmsPLrA9DDc4nRw2KFJQJK7DNooqSXrNI7tzLG50CF8axczly5UV929tBmh/7g==", "dev": true, "requires": { "import-fresh": "^2.0.0", "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "lodash.get": "^4.4.2", + "js-yaml": "^3.13.0", "parse-json": "^4.0.0" } }, @@ -2130,9 +2130,9 @@ } }, "strip-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.1.0.tgz", - "integrity": "sha512-TjxrkPONqO2Z8QDCpeE2j6n0M6EwxzyDgzEeGp+FbdvaJAt//ClYi6W5my+3ROlC/hZX2KACUwDfK49Ka5eDvg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" @@ -2141,9 +2141,9 @@ } }, "@lerna/publish": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.13.1.tgz", - "integrity": "sha512-KhCJ9UDx76HWCF03i5TD7z5lX+2yklHh5SyO8eDaLptgdLDQ0Z78lfGj3JhewHU2l46FztmqxL/ss0IkWHDL+g==", + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.13.2.tgz", + "integrity": "sha512-L8iceC3Z2YJnlV3cGbfk47NSh1+iOo1tD65z+BU3IYLRpPnnSf8i6BORdKV8rECDj6kjLYvL7//2yxbHy7shhA==", "dev": true, "requires": { "@lerna/batch-packages": "3.13.0", @@ -2155,7 +2155,7 @@ "@lerna/log-packed": "3.13.0", "@lerna/npm-conf": "3.13.0", "@lerna/npm-dist-tag": "3.13.0", - "@lerna/npm-publish": "3.13.0", + "@lerna/npm-publish": "3.13.2", "@lerna/output": "3.13.0", "@lerna/pack-directory": "3.13.1", "@lerna/prompt": "3.13.0", @@ -2163,7 +2163,7 @@ "@lerna/run-lifecycle": "3.13.0", "@lerna/run-parallel-batches": "3.13.0", "@lerna/validation-error": "3.13.0", - "@lerna/version": "3.13.1", + "@lerna/version": "3.13.2", "figgy-pudding": "^3.5.1", "fs-extra": "^7.0.0", "libnpmaccess": "^3.0.1", @@ -2292,9 +2292,9 @@ } }, "@lerna/version": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.13.1.tgz", - "integrity": "sha512-WpfKc5jZBBOJ6bFS4atPJEbHSiywQ/Gcd+vrwaEGyQHWHQZnPTvhqLuq3q9fIb9sbuhH5pSY6eehhuBrKqTnjg==", + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.13.2.tgz", + "integrity": "sha512-85AEn6Cx5p1VOejEd5fpTyeDCx6yejSJCgbILkx+gXhLhFg2XpFzLswMd+u71X7RAttWHvhzeKJAw4tWTXDvpQ==", "dev": true, "requires": { "@lerna/batch-packages": "3.13.0", @@ -2379,9 +2379,9 @@ } }, "@octokit/plugin-enterprise-rest": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-2.2.1.tgz", - "integrity": "sha512-Ssrh5D5uOqeS/Kjs6bbzn4ZaaaZQ2h6X/DgoDVv0Goa2ncpHwBN644hfYOL5ycigkpYbHKTjyb6cM49kPwQRPA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-2.2.2.tgz", + "integrity": "sha512-CTZr64jZYhGWNTDGlSJ2mvIlFsm9OEO3LqWn9I/gmoHI4jRBp4kpHoFYNemG4oA75zUAcmbuWblb7jjP877YZw==", "dev": true }, "@octokit/request": { @@ -2399,12 +2399,13 @@ } }, "@octokit/rest": { - "version": "16.18.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.18.1.tgz", - "integrity": "sha512-ozKUH4KCusmPQ6xHxF2q1IDVM5tPbmmAUP69yRLd98BH16mqOVwMkm6zLCUJPD03IVhG+YNHShJDc077CTkIWg==", + "version": "16.23.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.23.2.tgz", + "integrity": "sha512-ZxiZMaCuqBG/IsbgNRVfGwYsvBb5DjHuMGjJgOrinT+/b+1j1U7PiGyRkHDJdjTGA6N/PsMC2lP2ZybX9579iA==", "dev": true, "requires": { "@octokit/request": "2.4.2", + "atob-lite": "^2.0.0", "before-after-hook": "^1.4.0", "btoa-lite": "^1.0.0", "deprecation": "^1.0.1", @@ -3150,6 +3151,12 @@ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, + "atob-lite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", + "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=", + "dev": true + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -5000,16 +5007,16 @@ } }, "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, "requires": { "accepts": "~1.3.5", "bytes": "3.0.0", - "compressible": "~2.0.14", + "compressible": "~2.0.16", "debug": "2.6.9", - "on-headers": "~1.0.1", + "on-headers": "~1.0.2", "safe-buffer": "5.1.2", "vary": "~1.1.2" }, @@ -5977,17 +5984,17 @@ } }, "del": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", - "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.0.tgz", + "integrity": "sha512-C4kvKNlYrwXhKxz97BuohF8YoGgQ23Xm9lvoHmgT7JaPGprSEjk3+XFled74Yt/x0ZABUHg2D67covzAPUKx5Q==", "dev": true, "requires": { "globby": "^6.1.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "p-map": "^1.1.1", - "pify": "^3.0.0", - "rimraf": "^2.2.8" + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" }, "dependencies": { "globby": { @@ -6010,6 +6017,18 @@ "dev": true } } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true } } }, @@ -6992,9 +7011,9 @@ }, "dependencies": { "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -7461,8 +7480,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -7483,14 +7501,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7505,20 +7521,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -7635,8 +7648,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -7648,7 +7660,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7663,7 +7674,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7671,14 +7681,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7697,7 +7705,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -7778,8 +7785,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -7791,7 +7797,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -7877,8 +7882,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -7914,7 +7918,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7934,7 +7937,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7978,14 +7980,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -8849,9 +8849,9 @@ }, "dependencies": { "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -9185,12 +9185,12 @@ } }, "internal-ip": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.2.0.tgz", - "integrity": "sha512-ZY8Rk+hlvFeuMmG5uH1MXhhdeMntmIaxaInvAmzMq/SHV8rv4Kh+6GiQNNDQd0wZFrcO+FiTBo8lui/osKOyJw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", "dev": true, "requires": { - "default-gateway": "^4.0.1", + "default-gateway": "^4.2.0", "ipaddr.js": "^1.9.0" }, "dependencies": { @@ -9411,15 +9411,15 @@ } }, "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.0.0.tgz", + "integrity": "sha512-m5dHHzpOXEiv18JEORttBO64UgTEypx99vCxQLjbBvGhOJxnTNglYoFXxwo6AbsQb79sqqycQEHv2hWkHZAijA==", "dev": true }, "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.0.0.tgz", + "integrity": "sha512-6Vz5Gc9s/sDA3JBVu0FzWufm8xaBsqy1zn8Q6gmvGP6nSDMw78aS4poBNeatWjaRpTpxxLn1WOndAiOlk+qY8A==", "dev": true, "requires": { "is-path-inside": "^1.0.0" @@ -10129,9 +10129,9 @@ "dev": true }, "js-yaml": { - "version": "3.12.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", - "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -10295,14 +10295,14 @@ "dev": true }, "lerna": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.13.1.tgz", - "integrity": "sha512-7kSz8LLozVsoUNTJzJzy+b8TnV9YdviR2Ee2PwGZSlVw3T1Rn7kOAPZjEi+3IWnOPC96zMPHVmjCmzQ4uubalw==", + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.13.2.tgz", + "integrity": "sha512-2iliiFVAMNqaKsVSJ90p49dur93d5RlktotAJNp+uuHsCuIIAvwceqmSgDQCmWu4GkgAom+5uy//KV6F9t8fLA==", "dev": true, "requires": { "@lerna/add": "3.13.1", "@lerna/bootstrap": "3.13.1", - "@lerna/changed": "3.13.1", + "@lerna/changed": "3.13.2", "@lerna/clean": "3.13.1", "@lerna/cli": "3.13.0", "@lerna/create": "3.13.1", @@ -10312,9 +10312,9 @@ "@lerna/init": "3.13.1", "@lerna/link": "3.13.1", "@lerna/list": "3.13.1", - "@lerna/publish": "3.13.1", + "@lerna/publish": "3.13.2", "@lerna/run": "3.13.1", - "@lerna/version": "3.13.1", + "@lerna/version": "3.13.2", "import-local": "^1.0.0", "npmlog": "^4.1.2" }, @@ -11051,9 +11051,9 @@ } }, "macos-release": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.0.0.tgz", - "integrity": "sha512-iCM3ZGeqIzlrH7KxYK+fphlJpCCczyHXc+HhRVbEu9uNTCrzYJjvvtefzeKTCVHd5AP/aD/fzC80JZ4ZP+dQ/A==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.2.0.tgz", + "integrity": "sha512-iV2IDxZaX8dIcM7fG6cI46uNmHUxHE4yN+Z8tKHAW1TBPMZDIKHf/3L+YnOuj/FK9il14UaVdHmiQ1tsi90ltA==", "dev": true }, "make-dir": { @@ -13075,9 +13075,9 @@ "dev": true }, "opn": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", - "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", "dev": true, "requires": { "is-wsl": "^1.1.0" @@ -13155,12 +13155,12 @@ } }, "os-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.0.0.tgz", - "integrity": "sha512-7c74tib2FsdFbQ3W+qj8Tyd1R3Z6tuVRNNxXjJcZ4NgjIEQU9N/prVMqcW29XZPXGACqaXN3jq58/6hoaoXH6g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", + "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", "dev": true, "requires": { - "macos-release": "^2.0.0", + "macos-release": "^2.2.0", "windows-release": "^3.1.0" } }, @@ -14849,9 +14849,9 @@ "dev": true }, "querystringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz", - "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", "dev": true }, "quick-lru": { @@ -17324,9 +17324,9 @@ } }, "url-parse": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", - "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.6.tgz", + "integrity": "sha512-/B8AD9iQ01seoXmXf9z/MjLZQIdOoYl/+gvsQF6+mpnxaTfG9P7srYaiqaDMyKkR36XMXfhqSHss5MyFAO8lew==", "dev": true, "requires": { "querystringify": "^2.0.0", @@ -17673,9 +17673,9 @@ } }, "webpack-dev-middleware": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.6.1.tgz", - "integrity": "sha512-XQmemun8QJexMEvNFbD2BIg4eSKrmSIMrTfnl2nql2Sc6OGAYFyb8rwuYrCjl/IiEYYuyTEiimMscu7EXji/Dw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.6.2.tgz", + "integrity": "sha512-A47I5SX60IkHrMmZUlB0ZKSWi29TZTcPz7cha1Z75yYOsgWh/1AcPmQEbC8ZIbU3A1ytSv1PMU0PyPz2Lmz2jg==", "dev": true, "requires": { "memory-fs": "^0.4.1", @@ -17685,49 +17685,49 @@ }, "dependencies": { "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz", + "integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==", "dev": true } } }, "webpack-dev-server": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.2.1.tgz", - "integrity": "sha512-sjuE4mnmx6JOh9kvSbPYw3u/6uxCLHNWfhWaIPwcXWsvWOPN+nc5baq4i9jui3oOBRXGonK9+OI0jVkaz6/rCw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.3.1.tgz", + "integrity": "sha512-jY09LikOyGZrxVTXK0mgIq9y2IhCoJ05848dKZqX1gAGLU1YDqgpOT71+W53JH/wI4v6ky4hm+KvSyW14JEs5A==", "dev": true, "requires": { "ansi-html": "0.0.7", "bonjour": "^3.5.0", - "chokidar": "^2.0.0", - "compression": "^1.5.2", - "connect-history-api-fallback": "^1.3.0", + "chokidar": "^2.1.5", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", "debug": "^4.1.1", - "del": "^3.0.0", - "express": "^4.16.2", - "html-entities": "^1.2.0", + "del": "^4.1.0", + "express": "^4.16.4", + "html-entities": "^1.2.1", "http-proxy-middleware": "^0.19.1", "import-local": "^2.0.0", "internal-ip": "^4.2.0", "ip": "^1.1.5", - "killable": "^1.0.0", - "loglevel": "^1.4.1", - "opn": "^5.1.0", - "portfinder": "^1.0.9", + "killable": "^1.0.1", + "loglevel": "^1.6.1", + "opn": "^5.5.0", + "portfinder": "^1.0.20", "schema-utils": "^1.0.0", - "selfsigned": "^1.9.1", - "semver": "^5.6.0", - "serve-index": "^1.7.2", + "selfsigned": "^1.10.4", + "semver": "^6.0.0", + "serve-index": "^1.9.1", "sockjs": "0.3.19", "sockjs-client": "1.3.0", "spdy": "^4.0.0", - "strip-ansi": "^3.0.0", + "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", "url": "^0.11.0", - "webpack-dev-middleware": "^3.5.1", + "webpack-dev-middleware": "^3.6.2", "webpack-log": "^2.0.0", - "yargs": "12.0.2" + "yargs": "12.0.5" }, "dependencies": { "ansi-regex": { @@ -17736,11 +17736,25 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true + "chokidar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz", + "integrity": "sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } }, "debug": { "version": "4.1.1", @@ -17751,13 +17765,13 @@ "ms": "^2.1.1" } }, - "decamelize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", - "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { - "xregexp": "4.0.0" + "is-extglob": "^2.1.1" } }, "ms": { @@ -17766,6 +17780,18 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "semver": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "dev": true + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -17783,35 +17809,6 @@ "requires": { "has-flag": "^3.0.0" } - }, - "yargs": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", - "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^2.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^10.1.0" - } - }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } } } }, @@ -17914,35 +17911,12 @@ } }, "windows-release": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.1.0.tgz", - "integrity": "sha512-hBb7m7acFgQPQc222uEQTmdcGLeBmQLNLFIh0rDk3CwFOBrfjefLzEfEfmpMq8Af/n/GnFf3eYf203FY1PmudA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", + "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", "dev": true, "requires": { - "execa": "^0.10.0" - }, - "dependencies": { - "execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } + "execa": "^1.0.0" } }, "word-wrap": { @@ -18078,12 +18052,6 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, - "xregexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", - "dev": true - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index 8e0eeb180fd..a3d62ea17cc 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,7 @@ "jest": "^24.3.1", "jest-cli": "^24.3.1", "jest-junit": "^6.3.0", - "lerna": "^3.13.1", + "lerna": "^3.13.2", "lint-staged": "7.x.x", "nyc": "^13.3.0", "prettier-eslint-cli": "^4.7.1", @@ -175,7 +175,7 @@ "typedoc-plugin-monorepo": "^0.1.0", "typescript": "^3.3.1", "webpack": "4.x.x", - "webpack-dev-server": "^3.1.10" + "webpack-dev-server": "^3.3.1" }, "collective": { "type": "opencollective", From 6a0375a728888cf24736e631a3d52d2359d40085 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Thu, 18 Apr 2019 00:00:28 +0530 Subject: [PATCH 14/39] docs(packages): adds downloads/month shield adds the image shield for downloads in readme file --- packages/add/README.md | 2 ++ packages/generate-loader/README.md | 4 +++- packages/generate-plugin/README.md | 4 +++- packages/generators/README.md | 2 ++ packages/info/README.md | 2 ++ packages/init/README.md | 2 ++ packages/migrate/README.md | 4 +++- packages/remove/README.md | 4 +++- packages/serve/README.md | 4 +++- packages/update/README.md | 4 +++- packages/utils/README.md | 4 +++- packages/webpack-scaffold/README.md | 25 ++++++++++++++++--------- 12 files changed, 45 insertions(+), 16 deletions(-) diff --git a/packages/add/README.md b/packages/add/README.md index 0cb1b45b86c..cc13015724b 100644 --- a/packages/add/README.md +++ b/packages/add/README.md @@ -1,5 +1,7 @@ # webpack-cli add +[![npm](https://img.shields.io/npm/dm/@webpack-cli/add.svg)](https://www.npmjs.com/package/@webpack-cli/add) + ## Description This package contains the logic to add new properties in a webpack configuration file. It will run a generator that prompts the user for questions of which property to add to their webpack configuration file. diff --git a/packages/generate-loader/README.md b/packages/generate-loader/README.md index 26a9100e432..ed7e47ae96a 100644 --- a/packages/generate-loader/README.md +++ b/packages/generate-loader/README.md @@ -1,5 +1,7 @@ # webpack-cli generate-loader +[![npm](https://img.shields.io/npm/dm/@webpack-cli/generate-loader.svg)](https://www.npmjs.com/package/@webpack-cli/generate-loader) + ## Description This package contains the logic to initiate new loader projects. @@ -24,4 +26,4 @@ generateLoader(); ### CLI (via `webpack-cli`) ```bash npx webpack-cli generate-loader -``` \ No newline at end of file +``` diff --git a/packages/generate-plugin/README.md b/packages/generate-plugin/README.md index df400763c1d..29662905a17 100644 --- a/packages/generate-plugin/README.md +++ b/packages/generate-plugin/README.md @@ -1,5 +1,7 @@ # webpack-cli generate-plugin +[![npm](https://img.shields.io/npm/dm/@webpack-cli/generate-plugin.svg)](https://www.npmjs.com/package/@webpack-cli/generate-plugin) + ## Description This package contains the logic to initiate new plugin projects. @@ -23,4 +25,4 @@ generatePlugin(); ### CLI (via `webpack-cli`) ```bash npx webpack-cli generate-plugin -``` \ No newline at end of file +``` diff --git a/packages/generators/README.md b/packages/generators/README.md index 921217257f9..5139dcf3c4b 100644 --- a/packages/generators/README.md +++ b/packages/generators/README.md @@ -1,5 +1,7 @@ # webpack-cli generators +[![npm](https://img.shields.io/npm/dm/@webpack-cli/generators.svg)](https://www.npmjs.com/package/@webpack-cli/generators) + ## Description This package contains all webpack-cli related yeoman generators. diff --git a/packages/info/README.md b/packages/info/README.md index a1944e21808..03dcd9bd8d1 100644 --- a/packages/info/README.md +++ b/packages/info/README.md @@ -1,5 +1,7 @@ # webpack-cli info +[![npm](https://img.shields.io/npm/dm/@webpack-cli/info.svg)](https://www.npmjs.com/package/@webpack-cli/info) + ## Description This pacakge returns a set of information related to the local enviroment. diff --git a/packages/init/README.md b/packages/init/README.md index d2eacb9caa1..465966be148 100644 --- a/packages/init/README.md +++ b/packages/init/README.md @@ -1,5 +1,7 @@ # webpack-cli init +[![npm](https://img.shields.io/npm/dm/@webpack-cli/init.svg)](https://www.npmjs.com/package/@webpack-cli/init) + ## Description This package contains the logic to create a new webpack configuration. diff --git a/packages/migrate/README.md b/packages/migrate/README.md index 38fad56a13d..68a8ae342a9 100644 --- a/packages/migrate/README.md +++ b/packages/migrate/README.md @@ -1,5 +1,7 @@ # webpack-cli migrate +[![npm](https://img.shields.io/npm/dm/@webpack-cli/migrate.svg)](https://www.npmjs.com/package/@webpack-cli/migrate) + ## Description This package contains the logic to migrate a project from one version to the other. @@ -25,4 +27,4 @@ migrate(null, null, inputPath, outputPath); ### CLI (via `webpack-cli`) ```bash npx webpack-cli migrate -``` \ No newline at end of file +``` diff --git a/packages/remove/README.md b/packages/remove/README.md index 6af72b205f4..9ec0202d772 100644 --- a/packages/remove/README.md +++ b/packages/remove/README.md @@ -1,5 +1,7 @@ # webpack-cli remove +[![npm](https://img.shields.io/npm/dm/@webpack-cli/remove.svg)](https://www.npmjs.com/package/@webpack-cli/remove) + ## Description This package contains the logic to remove properties of a webpack configuration file. It will run a generator that prompts the user for questions of which property to remove in their webpack configuration file. @@ -23,4 +25,4 @@ remove(); ### CLI (via `webpack-cli`) ```bash npx webpack-cli remove -``` \ No newline at end of file +``` diff --git a/packages/serve/README.md b/packages/serve/README.md index a6612b6f9be..aab9613599c 100644 --- a/packages/serve/README.md +++ b/packages/serve/README.md @@ -1,5 +1,7 @@ # webpack-cli serve +[![npm](https://img.shields.io/npm/dm/@webpack-cli/serve.svg)](https://www.npmjs.com/package/@webpack-cli/serve) + ## Description This package contains the logic to run webpack-serve without using webpack-serve directly. @@ -23,4 +25,4 @@ serve(); ### CLI (via `webpack-cli`) ```bash npx webpack-cli serve -``` \ No newline at end of file +``` diff --git a/packages/update/README.md b/packages/update/README.md index 16f38f42326..dd038a61038 100644 --- a/packages/update/README.md +++ b/packages/update/README.md @@ -1,5 +1,7 @@ # webpack-cli update +[![npm](https://img.shields.io/npm/dm/@webpack-cli/update.svg)](https://www.npmjs.com/package/@webpack-cli/update) + ## Description This package contains the logic to update properties in a webpack configuration file. It will run a generator that prompts the user for questions of which property to update in their webpack configuration file. @@ -23,4 +25,4 @@ update(); ### CLI (via `webpack-cli`) ```bash npx webpack-cli update -``` \ No newline at end of file +``` diff --git a/packages/utils/README.md b/packages/utils/README.md index 33bc3f771f6..2ea21274d09 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -1,5 +1,7 @@ # webpack-cli utils (WIP, not yet published) +[![npm](https://img.shields.io/npm/dm/@webpack-cli/utils.svg)](https://www.npmjs.com/package/@webpack-cli/utils) + ## Description This package contains the utilities used across the webpack-cli repositories. @@ -26,4 +28,4 @@ npm i -D webpack-cli @webpack-cli/utils ```js const utils = require("@webpack-cli/utils"); // API yet to be exposed -``` \ No newline at end of file +``` diff --git a/packages/webpack-scaffold/README.md b/packages/webpack-scaffold/README.md index 90453cc188b..fcd01de288f 100755 --- a/packages/webpack-scaffold/README.md +++ b/packages/webpack-scaffold/README.md @@ -1,5 +1,7 @@ # webpack-scaffold +[![npm](https://img.shields.io/npm/dm/@webpack-cli/webpack-scaffold.svg)](https://www.npmjs.com/package/@webpack-cli/webpack-scaffold) + This is the utility suite for creating a webpack `scaffold`, it contains utility functions to help you work with [Inquirer](https://github.com/SBoudrias/Inquirer.js/) prompting and scaffolding. # Installation @@ -9,15 +11,20 @@ npm i -D webpack-cli @webpack-cli/webpack-scaffold ``` # API - -1. [parseValue()](#parsevalue) -2. [createArrowFunction()](#createarrowfunction) -3. [createRegularFunction()](#createregularfunction) -4. [createDynamicPromise()](#createdynamicpromise) -5. [createAssetFilterFunction()](#createassetfilterfunction) -6. [createExternalFunction()](#createexternalfunction) -7. [createRequire()](#createrequire) -8. 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 From dc941e6c0db4ec796b42f9269f695c81fa3fd626 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Sat, 20 Apr 2019 18:54:22 +0530 Subject: [PATCH 15/39] docs(contributing): fixes dead link (#835) link to the migration docs was invalid, hence fixed --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 8f937259c0c..1465d30614c 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -259,7 +259,7 @@ The expected result of the above command is to take the mentioned `webpack` conf It should be a valid new config and should keep intact all the features from the original config. The new config will be as readable as possible (may add some comments). -With [#40](https://github.com/webpack/webpack-cli/pull/40), we have been able to add basic scaffolding and do many of the conversions recommended in the [docs](https://webpack.js.org/guides/migrating/). +With [#40](https://github.com/webpack/webpack-cli/pull/40), we have been able to add basic scaffolding and do many of the conversions recommended in the [docs](https://webpack.js.org/migrate). ### How it's being done From 8c1db0317c20d29de14bf31527fdb5b5e7c0caf6 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Sat, 20 Apr 2019 22:38:42 +0530 Subject: [PATCH 16/39] chore(docs): removes scaffolding docs from the root removes the scaffolding docs from the root of the project folder --- SCAFFOLDING.md | 148 ------------------------------------------------- 1 file changed, 148 deletions(-) delete mode 100644 SCAFFOLDING.md diff --git a/SCAFFOLDING.md b/SCAFFOLDING.md deleted file mode 100644 index 855c5fb3442..00000000000 --- a/SCAFFOLDING.md +++ /dev/null @@ -1,148 +0,0 @@ -# Introduction - -Setting up webpack for the first time is hard. Writing advanced configurations to optimize performance is even harder. The `init` feature is designed to support people that want to create their own configuration or initializing other projects people create. - -## Creating a scaffold - -Before writing a `webpack-cli` scaffold, think about what you're trying to achieve. Do you want a "general" scaffold that could be used by any project or type of app? Do you want something very focused, like a scaffold that writes both your `webpack.config.js` and your framework code? It's also useful to think about the user experience for your scaffold. - -`webpack-cli` offers an experience that is interactive and you can prompt users for questions (like, "What is your entry point?") to help customize the output accordingly. - -### Writing a scaffold - -There are many resources where you can learn how to write a scaffold, you can start from: [How do I compose a -webpack-scaffold?](https://github.com/evenstensberg/webpack-scaffold-demo) - - -[`webpack-scaffold`](./packages/webpack-scaffold) is a utility suite for creating scaffolds. It contains functions that could be used to create a scaffold. - - -### Running a scaffold - -A scaffold can be executed using [`webpack-cli init`](./INIT.md): - -```js -webpack-cli init -``` - -#### Running a scaffold locally -When the scaffold package is in your local file system you should pass its path to `init`: - -```bash -webpack-cli init path/to/your/scaffold -``` - -Or you can create a global module and symlink to the local one: - -* Using npm - - ```bash - cd path/to/my-scaffold - npm link - webpack-cli init my-scaffold - ``` - -* Using yarn - - ```bash - cd path/to/my-scaffold - yarn link - webpack-cli init my-scaffold - -#### Running a scaffold from npm - -If the package is in npm, its name must begin with `webpack-scaffold` and can be used running: - -```js -webpack-cli init webpack-scaffold-yourpackage -``` - - -## API - -To create a `scaffold`, you must create a [`yeoman-generator`](http://yeoman.io/authoring/). Because of that, you can optionally extend your generator to include methods from the [Yeoman API](http://yeoman.io/learning/). It's worth noting that we support all the properties of a regular webpack configuration. In order for us to do this, there's a thing you need to remember: - -> Objects are made using strings, while strings are made using double strings. This means that in order for you to create a string, you have to wrap it inside another string for us to validate it correctly. - -### Required -- [opts.env.configuration](#optsenvconfiguration-required) -- [opts.env.configuration.myObj](#optsenvconfigurationmyObj-required) -- [myObj.webpackOptions](#myObjwebpackOptions-required) -- [writing()](#writing()-required) - -### Optional -- [myObj.merge](#myObjmerge-optional) -- [myObj.topScope](#myObjtopScope-optional) -- [myObj.configName](#myObjconfigName-optional) - -### `opts.env.configuration`(required) - -This is the entry point your configuration, initialize it inside the constructor of your generator in order for the CLI to work: - -```js -constructor(args, opts) { - super(args, opts); - opts.env.configuration = {}; -} -``` -### `opts.env.configuration.myObj` (required) - -This is your scaffold, you add here the options that the CLI will transform into a webpack configuration. You can have many different scaffolds named as you prefer, representing different configurations like `dev.config` or `prod.config`: - -```js -constructor(args, opts) { - super(args, opts); - opts.env.configuration = { - dev: {}, - prod: {} - }; -} -``` - -### `myObj.webpackOptions` (required) - -This object has the same format as a regular webpack configuration, so you declare here the properties that you want to scaffold, like `entry`, `output` and `context`. You can initialize this inside a yeoman method: - -```js -this.options.env.configuration.dev.webpackOptions = { - entry: '\'app.js\'', - output: {...} -}; -``` - -### `myObj.merge` (optional) - -If you want to use [`webpack-merge`](https://github.com/survivejs/webpack-merge), you can set the `merge` property of `myObj` to the name of the configuration you want to merge it with: - -```js -this.options.env.configuration.dev.merge = 'myConfig'; -``` - -### `myObj.topScope`(optional) - -The `topScope` property is where you write all the code needed by your configuration, like module imports and functions/variables definitions: - -```js -this.options.env.configuration.dev.topScope = [ - 'const webpack = require(\'webpack\');', - 'const path = require(\'path\');' -]; -``` - -### `myObj.configName`(optional) - -`configName` allows you to customize the name of your configuration file. For example you can name it `webpack.base.js` instead of the default `webpack.config.js`: - -```js -this.options.env.configuration.dev.configName = 'base'; -``` - -### `writing` (required) - -For the scaffolding instance to run, you need to write your configuration to a `.yo-rc.json` file. This could be done using one of the lifecycles in the yeoman generator, such as the `writing` method: - -```js -writing() { - this.config.set('configuration', myObj) -} -``` From 06b4929c130e30763b9b70d79ab6ae182f6d4fa9 Mon Sep 17 00:00:00 2001 From: Emanuele Date: Sat, 20 Apr 2019 23:26:58 +0100 Subject: [PATCH 17/39] Remove tslint in favour of eslint (#834) * chore: created eslint configs in each package - fixed typescript types - removed tslint commands - fixed tests * chore: removed comment * chore: removed lines that belong to tslint --- .eslintrc.js | 105 +-- .github/CONTRIBUTING.md | 4 +- .gitignore | 1 + bin/.eslintrc.js | 63 ++ bin/utils/prompt-command.js | 23 +- junit.xml | 557 ------------- package-lock.json | 152 ++-- package.json | 15 +- packages/add/.eslintrc | 11 + packages/add/index.ts | 12 +- packages/add/package-lock.json | 105 ++- packages/add/tsconfig.json | 2 +- packages/generate-loader/.eslintrc | 11 + packages/generate-loader/index.ts | 2 - packages/generate-loader/package-lock.json | 101 ++- packages/generate-loader/types/Yeoman.ts | 10 +- packages/generate-plugin/.eslintrc | 11 + packages/generate-plugin/index.ts | 2 - packages/generate-plugin/types/Yeoman.ts | 10 +- packages/generators/.eslintrc | 11 + packages/generators/__tests__/.eslintrc | 9 + .../loader-generator.test.ts} | 4 +- packages/generators/add-generator.ts | 779 ++++++++---------- packages/generators/addon-generator.ts | 47 +- packages/generators/init-generator.ts | 653 +++++++-------- packages/generators/remove-generator.ts | 162 ++-- packages/generators/tslint.json | 3 - packages/generators/types/index.ts | 107 +-- packages/generators/types/json-loader.d.ts | 1 + .../generators/types/yeoman-generator.d.ts | 50 +- packages/generators/utils/entry.ts | 151 ++-- packages/generators/utils/module.ts | 22 +- packages/generators/utils/plugins.ts | 2 +- packages/generators/utils/tooltip.ts | 10 +- packages/info/.eslintrc | 11 + packages/info/__tests__/.eslintrc | 7 + packages/info/__tests__/index.test.ts | 2 +- packages/info/index.ts | 8 +- packages/init/.eslintrc | 11 + packages/init/init.ts | 82 +- packages/init/package-lock.json | 2 +- packages/init/types/Transform.ts | 6 +- packages/init/types/index.ts | 2 +- packages/make/.eslintrc | 11 + packages/migrate/.eslintrc | 11 + packages/migrate/__tests__/.eslintrc | 7 + packages/migrate/bannerPlugin/bannerPlugin.ts | 27 +- .../commonsChunkPlugin/commonsChunkPlugin.ts | 337 ++++---- .../extractTextPlugin/extractTextPlugin.ts | 36 +- packages/migrate/index.ts | 356 ++++---- .../loaderOptionsPlugin.ts | 42 +- packages/migrate/loaders/loaders.ts | 272 +++--- packages/migrate/migrate.ts | 90 +- .../moduleConcatenationPlugin.ts | 23 +- .../namedModulesPlugin/namedModulesPlugin.ts | 19 +- .../noEmitOnErrorsPlugin.ts | 23 +- packages/migrate/outputPath/outputPath.ts | 61 +- packages/migrate/package-lock.json | 68 +- .../removeDeprecatedPlugins.ts | 57 +- .../removeJsonLoader/removeJsonLoader.ts | 28 +- packages/migrate/resolve/resolve.ts | 61 +- packages/migrate/types/NodePath.ts | 145 ++-- .../migrate/uglifyJsPlugin/uglifyJsPlugin.ts | 88 +- packages/remove/.eslintrc | 11 + packages/serve/.eslintrc | 11 + packages/serve/index.ts | 149 ++-- packages/update/.eslintrc | 11 + packages/utils/.eslintrc | 11 + packages/utils/__tests__/.eslintrc | 7 + packages/utils/__tests__/ast-utils.test.ts | 64 +- .../utils/__tests__/package-manager.test.ts | 4 +- .../utils/__tests__/resolve-packages.test.ts | 10 +- packages/utils/ast-utils.ts | 461 ++++++----- packages/utils/copy-utils.ts | 17 +- packages/utils/defineTest.ts | 144 ++-- packages/utils/modify-config-helper.ts | 121 +-- packages/utils/npm-exists.ts | 6 +- packages/utils/npm-packages-exists.ts | 76 +- packages/utils/package-lock.json | 63 +- packages/utils/package-manager.ts | 49 +- packages/utils/recursive-parser.ts | 59 +- packages/utils/resolve-packages.ts | 96 ++- packages/utils/scaffold.ts | 117 +-- packages/utils/types/NodePath.ts | 138 ++-- packages/utils/types/Yeoman.ts | 10 +- packages/utils/types/index.ts | 6 +- packages/utils/validate-identifier.ts | 101 +-- packages/webpack-scaffold/.eslintrc | 11 + packages/webpack-scaffold/__tests__/.eslintrc | 7 + packages/webpack-scaffold/index.ts | 70 +- packages/webpack-scaffold/package-lock.json | 6 +- tsconfig.packages.json | 2 +- tslint.json | 25 - 93 files changed, 3365 insertions(+), 3599 deletions(-) create mode 100644 bin/.eslintrc.js delete mode 100644 junit.xml create mode 100644 packages/add/.eslintrc create mode 100644 packages/generate-loader/.eslintrc create mode 100644 packages/generate-plugin/.eslintrc create mode 100644 packages/generators/.eslintrc create mode 100644 packages/generators/__tests__/.eslintrc rename packages/generators/{loader-generator.test.js => __tests__/loader-generator.test.ts} (84%) delete mode 100644 packages/generators/tslint.json create mode 100644 packages/info/.eslintrc create mode 100644 packages/info/__tests__/.eslintrc create mode 100644 packages/init/.eslintrc create mode 100644 packages/make/.eslintrc create mode 100644 packages/migrate/.eslintrc create mode 100644 packages/migrate/__tests__/.eslintrc create mode 100644 packages/remove/.eslintrc create mode 100644 packages/serve/.eslintrc create mode 100644 packages/update/.eslintrc create mode 100644 packages/utils/.eslintrc create mode 100644 packages/utils/__tests__/.eslintrc create mode 100644 packages/webpack-scaffold/.eslintrc create mode 100644 packages/webpack-scaffold/__tests__/.eslintrc delete mode 100644 tslint.json diff --git a/.eslintrc.js b/.eslintrc.js index b584e0b742f..0c8e2e4f974 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,31 +1,29 @@ module.exports = { - "root": true, - "plugins": ["node"], - "extends": ["eslint:recommended", "plugin:node/recommended"], - "env": { - "node": true, - "es6": true, - "jest": true + extends: ["eslint:recommended"], + env: { + node: true, + es6: true, + jest: true }, - "parserOptions": { "ecmaVersion": 2017, "sourceType": "module"}, - "rules": { + parserOptions: { ecmaVersion: 2017, sourceType: "module" }, + rules: { "no-useless-escape": "off", "quote-props": ["error", "as-needed"], "no-dupe-keys": "error", - "quotes": ["error", "double"], + quotes: ["error", "double"], "no-undef": "error", "no-extra-semi": "error", - "semi": "error", + semi: "error", "no-template-curly-in-string": "error", "no-caller": "error", - "yoda": "error", - "eqeqeq": "error", + yoda: "error", + eqeqeq: "error", "global-require": "off", "brace-style": "error", "key-spacing": "error", "space-in-parens": ["error", "never"], "space-infix-ops": "error", - "indent": ["error", "tab", { "SwitchCase": 1 }], + indent: ["error", "tab", { SwitchCase: 1 }], "no-extra-bind": "warn", "no-empty": "off", "no-multiple-empty-lines": "error", @@ -33,78 +31,31 @@ module.exports = { "no-process-exit": "off", "no-trailing-spaces": "error", "no-use-before-define": "off", - "no-unused-vars": ["error", { "args": "none" }], + "no-unused-vars": ["error", { args: "none" }], "no-unsafe-negation": "error", "no-loop-func": "warn", "space-before-function-paren": ["error", "never"], "space-before-blocks": "error", "object-curly-spacing": ["error", "always"], - "object-curly-newline": ["error", { "consistent": true }], - "keyword-spacing": ["error", { - "after": true, - "overrides": { - "const": { "after": true }, - "try": { "after": true }, - "throw": { "after": true }, - "case": { "after": true }, - "return": { "after": true }, - "finally": { "after": true }, - "do": { "after": true } - } - }], - "no-console": "off", - "valid-jsdoc": "error", - "node/no-unsupported-features": ["error", { "version": 6 }], - "node/no-deprecated-api": "error", - "node/no-missing-import": "error", - "node/no-missing-require": [ - "error", - { - "resolvePaths": ["./packages"], - "allowModules": [ - "webpack", - "@webpack-cli/generators", - "@webpack-cli/init", - "@webpack-cli/migrate", - "@webpack-cli/utils", - "@webpack-cli/generate-loader", - "@webpack-cli/generate-plugin", - "@webpack-cli/webpack-scaffold" - ] - } - ], - "node/no-unpublished-bin": "error", - "node/no-unpublished-require": [ + "object-curly-newline": ["error", { consistent: true }], + "keyword-spacing": [ "error", { - "allowModules": [ - "webpack", - "webpack-dev-server", - "@webpack-cli/generators", - "@webpack-cli/init", - "@webpack-cli/migrate", - "@webpack-cli/utils", - "@webpack-cli/generate-loader", - "@webpack-cli/generate-plugin", - "@webpack-cli/webpack-scaffold" - ] - } - ], - "node/no-extraneous-require": [ - "error", - { - "allowModules": [ - "@webpack-cli/migrate", - "@webpack-cli/generators", - "@webpack-cli/utils", - "@webpack-cli/generate-loader", - "@webpack-cli/generate-plugin", - "@webpack-cli/webpack-scaffold" - ] + after: true, + overrides: { + const: { after: true }, + try: { after: true }, + throw: { after: true }, + case: { after: true }, + return: { after: true }, + finally: { after: true }, + do: { after: true } + } } ], + "no-console": "off", + "valid-jsdoc": "error", "eol-last": ["error", "always"], - "newline-per-chained-call": "off", - "node/process-exit-as-throw": "error" + "newline-per-chained-call": "off" } }; diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 1465d30614c..cb1991ee88d 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -111,7 +111,7 @@ In case you are suggesting a new feature, we will match your idea with our curre * You can run the linters: ```bash - npm run lint && npm run tslint + npm run lint ``` ### Using yarn @@ -150,7 +150,7 @@ In case you are suggesting a new feature, we will match your idea with our curre * You can run the linters: ```bash - yarn lint && yarn tslint + yarn lint ``` ## Editor Config diff --git a/.gitignore b/.gitignore index ef696edb785..6fd2e644f89 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ yarn.lock # source maps of docs docs/**/*.map +junit.xml diff --git a/bin/.eslintrc.js b/bin/.eslintrc.js new file mode 100644 index 00000000000..b32868dab61 --- /dev/null +++ b/bin/.eslintrc.js @@ -0,0 +1,63 @@ +module.exports = { + root: true, + plugins: ["node"], + extends: ["../.eslintrc.js", "plugin:node/recommended"], + env: { + node: true, + es6: true, + jest: true + }, + parserOptions: { ecmaVersion: 2017, sourceType: "module" }, + rules: { + "node/no-unsupported-features": ["error", { version: 6 }], + "node/no-deprecated-api": "error", + "node/no-missing-import": "error", + "node/no-missing-require": [ + "error", + { + resolvePaths: ["./packages"], + allowModules: [ + "webpack", + "@webpack-cli/generators", + "@webpack-cli/init", + "@webpack-cli/migrate", + "@webpack-cli/utils", + "@webpack-cli/generate-loader", + "@webpack-cli/generate-plugin", + "@webpack-cli/webpack-scaffold" + ] + } + ], + "node/no-unpublished-bin": "error", + "node/no-unpublished-require": [ + "error", + { + allowModules: [ + "webpack", + "webpack-dev-server", + "@webpack-cli/generators", + "@webpack-cli/init", + "@webpack-cli/migrate", + "@webpack-cli/utils", + "@webpack-cli/generate-loader", + "@webpack-cli/generate-plugin", + "@webpack-cli/webpack-scaffold" + ] + } + ], + "node/no-extraneous-require": [ + "error", + { + allowModules: [ + "@webpack-cli/migrate", + "@webpack-cli/generators", + "@webpack-cli/utils", + "@webpack-cli/generate-loader", + "@webpack-cli/generate-plugin", + "@webpack-cli/webpack-scaffold" + ] + } + ], + "node/process-exit-as-throw": "error" + } +}; diff --git a/bin/utils/prompt-command.js b/bin/utils/prompt-command.js index 907434c6c71..20a99a1655f 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') { + const currentPackage = require(pathForCmd); + const func = currentPackage.default; + 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/junit.xml b/junit.xml deleted file mode 100644 index 304ccef7cc6..00000000000 --- a/junit.xml +++ /dev/null @@ -1,557 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3fa90818763..f72cab5b2a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2567,6 +2567,58 @@ "integrity": "sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz", + "integrity": "sha512-U224c29E2lo861TQZs6GSmyC0OYeRNg6bE9UVIiFBxN2MlA0nq2dCrgIVyyRbC05UOcrgf2Wk/CF2gGOPQKUSQ==", + "dev": true, + "requires": { + "@typescript-eslint/parser": "1.6.0", + "@typescript-eslint/typescript-estree": "1.6.0", + "requireindex": "^1.2.0", + "tsutils": "^3.7.0" + }, + "dependencies": { + "tsutils": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz", + "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.6.0.tgz", + "integrity": "sha512-VB9xmSbfafI+/kI4gUK3PfrkGmrJQfh0N4EScT1gZXSZyUxpsBirPL99EWZg9MmPG0pzq/gMtgkk7/rAHj4aQw==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "1.6.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.6.0.tgz", + "integrity": "sha512-A4CanUwfaG4oXobD5y7EXbsOHjCwn8tj1RDd820etpPAjH+Icjc2K9e/DQM1Hac5zH2BSy+u6bjvvF2wwREvYA==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, "@webassemblyjs/ast": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", @@ -4341,12 +4393,6 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -6607,6 +6653,23 @@ } } }, + "eslint-config-prettier": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.1.0.tgz", + "integrity": "sha512-zILwX9/Ocz4SV2vX7ox85AsrAgXV3f2o2gpIicdMIOra48WYqgUnWNH/cR/iHtmD2Vb3dLSC3LiEJnS05Gkw7w==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } + } + }, "eslint-plugin-es": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz", @@ -7480,7 +7543,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -7501,12 +7565,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 +7587,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 +7717,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -7660,6 +7730,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7674,6 +7745,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7681,12 +7753,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 +7779,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -7785,7 +7860,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -7797,6 +7873,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -7882,7 +7959,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -7918,6 +7996,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 +8016,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7980,12 +8060,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 } } }, @@ -15367,6 +15449,12 @@ } } }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -16950,36 +17038,6 @@ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", "dev": true }, - "tslint": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.14.0.tgz", - "integrity": "sha512-IUla/ieHVnB8Le7LdQFRGlVJid2T/gaJe5VkjzRVSRR6pA2ODYrnfR1hmxi+5+au9l50jBwpbBL34txgv4NnTQ==", - "dev": true, - "requires": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^3.2.0", - "glob": "^7.1.1", - "js-yaml": "^3.7.0", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", diff --git a/package.json b/package.json index a3d62ea17cc..7d4b80cf5ea 100644 --- a/package.json +++ b/package.json @@ -35,17 +35,16 @@ "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)/*.test.js\"", + "lint": "eslint \"./bin/*.js\" \"./test/**/*.js\" \"packages/**/!(node_modules)/*.ts\"", "postinstall": "node ./bin/opencollective.js", - "pretest": "npm run build && npm run lint && npm run tslint", + "pretest": "npm run build && npm run lint", "reportCoverage": "nyc report --reporter=json && codecov -f coverage/coverage-final.json --disable=gcov", "test": "nyc jest --maxWorkers=4 --reporters=default --reporters=jest-junit", "test:cli": "nyc jest test/ --maxWorkers=4 --reporters=default --reporters=jest-junit", "test:packages": "nyc jest packages/ --maxWorkers=4 --reporters=default --reporters=jest-junit", "test:ci": "nyc jest --maxWorkers=$(nproc) --reporters=default --reporters=jest-junit", "travis:integration": "npm run build && npm run test && npm run reportCoverage", - "travis:lint": "npm run build && npm run lint && npm run tslint", - "tslint": "tslint -c tslint.json \"packages/**/*.ts\"", + "travis:lint": "npm run build && npm run lint", "watch": "npm run build && tsc -w" }, "husky": { @@ -58,10 +57,6 @@ "{packages,bin}/**/!(__testfixtures__)/**.js": [ "eslint --fix", "git add" - ], - "{packages,bin}/**/!(__testfixtures__)/**.ts": [ - "tslint --fix", - "git add" ] }, "jest": { @@ -145,6 +140,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", "babel-preset-env": "^1.7.0", "babel-preset-jest": "^24.3.0", "bundlesize": "^0.17.0", @@ -154,6 +151,7 @@ "conventional-changelog-cli": "^2.0.11", "cz-customizable": "^5.3.0", "eslint": "^5.9.0", + "eslint-config-prettier": "^4.1.0", "eslint-plugin-node": "^8.0.0", "esm": "^3.2.14", "execa": "^1.0.0", @@ -170,7 +168,6 @@ "schema-utils": "^1.0.0", "ts-jest": "^23.10.5", "ts-node": "^7.0.1", - "tslint": "^5.11.0", "typedoc": "^0.13.0", "typedoc-plugin-monorepo": "^0.1.0", "typescript": "^3.3.1", diff --git a/packages/add/.eslintrc b/packages/add/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/add/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/add/index.ts b/packages/add/index.ts index bc5fe92f195..a63515c9347 100644 --- a/packages/add/index.ts +++ b/packages/add/index.ts @@ -12,11 +12,11 @@ import modifyConfigHelper from "@webpack-cli/utils/modify-config-helper"; const DEFAULT_WEBPACK_CONFIG_FILENAME = "webpack.config.js"; export default function add(...args: string[]): Function { - const filePaths = args.slice(3); - let configFile = DEFAULT_WEBPACK_CONFIG_FILENAME; - if (filePaths.length) { - configFile = filePaths[0]; - } + const filePaths = args.slice(3); + let configFile = DEFAULT_WEBPACK_CONFIG_FILENAME; + if (filePaths.length) { + configFile = filePaths[0]; + } - return modifyConfigHelper("add", defaultGenerator, configFile); + return modifyConfigHelper("add", defaultGenerator, configFile); } diff --git a/packages/add/package-lock.json b/packages/add/package-lock.json index 61a703534e8..dfebd320fe5 100644 --- a/packages/add/package-lock.json +++ b/packages/add/package-lock.json @@ -1,6 +1,6 @@ { "name": "@webpack-cli/add", - "version": "0.1.2", + "version": "0.1.5", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10,6 +10,109 @@ "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz", + "integrity": "sha512-U224c29E2lo861TQZs6GSmyC0OYeRNg6bE9UVIiFBxN2MlA0nq2dCrgIVyyRbC05UOcrgf2Wk/CF2gGOPQKUSQ==", + "dev": true, + "requires": { + "@typescript-eslint/parser": "1.6.0", + "@typescript-eslint/typescript-estree": "1.6.0", + "requireindex": "^1.2.0", + "tsutils": "^3.7.0" + } + }, + "@typescript-eslint/parser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.6.0.tgz", + "integrity": "sha512-VB9xmSbfafI+/kI4gUK3PfrkGmrJQfh0N4EScT1gZXSZyUxpsBirPL99EWZg9MmPG0pzq/gMtgkk7/rAHj4aQw==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "1.6.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.6.0.tgz", + "integrity": "sha512-A4CanUwfaG4oXobD5y7EXbsOHjCwn8tj1RDd820etpPAjH+Icjc2K9e/DQM1Hac5zH2BSy+u6bjvvF2wwREvYA==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, + "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 + }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tsutils": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz", + "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "typescript": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", diff --git a/packages/add/tsconfig.json b/packages/add/tsconfig.json index 8b1269a36b6..2a74d10580a 100644 --- a/packages/add/tsconfig.json +++ b/packages/add/tsconfig.json @@ -1,3 +1,3 @@ { - "extends": "../../tsconfig.packages.json" + "extends": "../../tsconfig.packages.json" } diff --git a/packages/generate-loader/.eslintrc b/packages/generate-loader/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/generate-loader/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/generate-loader/index.ts b/packages/generate-loader/index.ts index b56835cfc97..8f280fc6226 100644 --- a/packages/generate-loader/index.ts +++ b/packages/generate-loader/index.ts @@ -1,8 +1,6 @@ import LoaderGenerator from "@webpack-cli/generators/loader-generator"; import * as yeoman from "yeoman-environment"; -import { IYeoman } from "./types/Yeoman"; - /** * Runs a yeoman generator to create a new webpack loader project * @returns {void} diff --git a/packages/generate-loader/package-lock.json b/packages/generate-loader/package-lock.json index b9561b5e442..90c9c102e80 100644 --- a/packages/generate-loader/package-lock.json +++ b/packages/generate-loader/package-lock.json @@ -1,6 +1,6 @@ { "name": "@webpack-cli/generate-loader", - "version": "0.1.2", + "version": "0.1.5", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -24,6 +24,47 @@ "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz", + "integrity": "sha512-U224c29E2lo861TQZs6GSmyC0OYeRNg6bE9UVIiFBxN2MlA0nq2dCrgIVyyRbC05UOcrgf2Wk/CF2gGOPQKUSQ==", + "dev": true, + "requires": { + "@typescript-eslint/parser": "1.6.0", + "@typescript-eslint/typescript-estree": "1.6.0", + "requireindex": "^1.2.0", + "tsutils": "^3.7.0" + } + }, + "@typescript-eslint/parser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.6.0.tgz", + "integrity": "sha512-VB9xmSbfafI+/kI4gUK3PfrkGmrJQfh0N4EScT1gZXSZyUxpsBirPL99EWZg9MmPG0pzq/gMtgkk7/rAHj4aQw==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "1.6.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.6.0.tgz", + "integrity": "sha512-A4CanUwfaG4oXobD5y7EXbsOHjCwn8tj1RDd820etpPAjH+Icjc2K9e/DQM1Hac5zH2BSy+u6bjvvF2wwREvYA==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", @@ -384,6 +425,37 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -905,6 +977,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -1142,6 +1220,12 @@ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, + "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 + }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", @@ -1185,6 +1269,12 @@ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -1571,6 +1661,15 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" }, + "tsutils": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz", + "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "typescript": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", diff --git a/packages/generate-loader/types/Yeoman.ts b/packages/generate-loader/types/Yeoman.ts index 4c56a771c00..16615324c03 100644 --- a/packages/generate-loader/types/Yeoman.ts +++ b/packages/generate-loader/types/Yeoman.ts @@ -1,12 +1,12 @@ -interface IRunEnv extends Object { +interface RunEnv extends Object { on?: (event: string, callbackFn: Function) => void; } -export interface IYeoman extends Object { - registerStub?(generator: IGenerator, namespace: string): void; - run?(target: string, options?: object, done?: Function): IRunEnv; +export interface Yeoman extends Object { + registerStub?(generator: YeoGenerator, namespace: string): void; + run?(target: string, options?: object, done?: Function): RunEnv; } -export interface IGenerator extends Object { +export interface YeoGenerator extends Object { composeWith?: (path: string) => void; } diff --git a/packages/generate-plugin/.eslintrc b/packages/generate-plugin/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/generate-plugin/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/generate-plugin/index.ts b/packages/generate-plugin/index.ts index c5fab329c0a..50448da6713 100644 --- a/packages/generate-plugin/index.ts +++ b/packages/generate-plugin/index.ts @@ -1,8 +1,6 @@ import PluginGenerator from "@webpack-cli/generators/plugin-generator"; import * as yeoman from "yeoman-environment"; -import { IYeoman } from "./types/Yeoman"; - /** * Runs a yeoman generator to create a new webpack plugin project * @returns {void} diff --git a/packages/generate-plugin/types/Yeoman.ts b/packages/generate-plugin/types/Yeoman.ts index 4c56a771c00..1eab3f4b3d5 100644 --- a/packages/generate-plugin/types/Yeoman.ts +++ b/packages/generate-plugin/types/Yeoman.ts @@ -1,12 +1,12 @@ -interface IRunEnv extends Object { +interface RunEnv extends Object { on?: (event: string, callbackFn: Function) => void; } -export interface IYeoman extends Object { - registerStub?(generator: IGenerator, namespace: string): void; - run?(target: string, options?: object, done?: Function): IRunEnv; +export interface Yeoman extends Object { + registerStub?(generator: Generator, namespace: string): void; + run?(target: string, options?: object, done?: Function): RunEnv; } -export interface IGenerator extends Object { +export interface Generator extends Object { composeWith?: (path: string) => void; } diff --git a/packages/generators/.eslintrc b/packages/generators/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/generators/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/generators/__tests__/.eslintrc b/packages/generators/__tests__/.eslintrc new file mode 100644 index 00000000000..e3e3b0884ac --- /dev/null +++ b/packages/generators/__tests__/.eslintrc @@ -0,0 +1,9 @@ +{ + "root": true, + "extends": [ + "../.eslintrc" + ], + "rules": { + "@typescript-eslint/explicit-function-return-type": ["off"] + } +} diff --git a/packages/generators/loader-generator.test.js b/packages/generators/__tests__/loader-generator.test.ts similarity index 84% rename from packages/generators/loader-generator.test.js rename to packages/generators/__tests__/loader-generator.test.ts index 283f6bf551a..f8d6c4667c3 100644 --- a/packages/generators/loader-generator.test.js +++ b/packages/generators/__tests__/loader-generator.test.ts @@ -1,6 +1,4 @@ -"use strict"; - -const { makeLoaderName } = require("./loader-generator"); +import { makeLoaderName } from "../loader-generator"; describe("makeLoaderName", () => { it("should kebab-case loader name and append '-loader'", () => { diff --git a/packages/generators/add-generator.ts b/packages/generators/add-generator.ts index 134c10be8b4..e05da4d3c54 100644 --- a/packages/generators/add-generator.ts +++ b/packages/generators/add-generator.ts @@ -7,20 +7,13 @@ import * as path from "path"; import npmExists from "@webpack-cli/utils/npm-exists"; import { getPackageManager } from "@webpack-cli/utils/package-manager"; import PROP_TYPES from "@webpack-cli/utils/prop-types"; -import { - AutoComplete, - Confirm, - IInquirerInput, - Input, - List, -} from "@webpack-cli/webpack-scaffold"; +import { AutoComplete, Confirm, InquirerInput, Input, List } from "@webpack-cli/webpack-scaffold"; -import { ISchemaProperties, IWebpackOptions } from "./types"; +import { SchemaProperties, WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; -// tslint:disable:no-var-requires -const webpackDevServerSchema = require("webpack-dev-server/lib/options.json"); -const webpackSchema = require("./utils/optionsSchema.json"); +import webpackDevServerSchema from "webpack-dev-server/lib/options.json"; +import webpackSchema from "./utils/optionsSchema.json"; const PROPS: string[] = Array.from(PROP_TYPES.keys()); /** @@ -28,7 +21,7 @@ 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} string - string to be modified + * @param {String} str - string to be modified * @param {Number} index - index to replace from * @param {String} replace - string to replace starting from index * @@ -51,11 +44,13 @@ function replaceAt(str: string, index: number, replace: string): string { */ const traverseAndGetProperties = (arr: object[], prop: string): boolean => { let hasProp = false; - arr.forEach((p: object): void => { - if (p[prop]) { - hasProp = true; + arr.forEach( + (p: object): void => { + if (p[prop]) { + hasProp = true; + } } - }); + ); return hasProp; }; @@ -71,11 +66,7 @@ const traverseAndGetProperties = (arr: object[], prop: string): boolean => { */ const searchProps = (answers: object, input: string): Promise => { input = input || ""; - return Promise.resolve( - PROPS.filter((prop: string): boolean => - prop.toLowerCase().includes(input.toLowerCase()), - ), - ); + return Promise.resolve(PROPS.filter((prop: string): boolean => prop.toLowerCase().includes(input.toLowerCase()))); }; /** @@ -91,452 +82,414 @@ export default class AddGenerator extends Generator { private dependencies: string[]; private configuration: { config: { - configName?: string, - topScope?: string[], + configName?: string; + topScope?: string[]; item?: string; - webpackOptions?: IWebpackOptions, - }, + webpackOptions?: WebpackOptions; + }; }; - constructor(args, opts) { + public constructor(args, opts) { super(args, opts); this.dependencies = []; this.configuration = { config: { topScope: ["const webpack = require('webpack')"], - webpackOptions: {}, - }, + webpackOptions: {} + } }; const { registerPrompt } = this.env.adapter.promptModule; registerPrompt("autocomplete", autoComplete); } - public prompting() { - const done: (_?: void) => void | boolean = this.async(); + public prompting(): void { + const done: () => void | boolean = this.async(); let action: string; const self: this = this; - const manualOrListInput: (promptAction: string) => IInquirerInput = (promptAction: string) => + const manualOrListInput: (promptAction: string) => InquirerInput = (promptAction: string): InquirerInput => Input("actionAnswer", `What do you want to add to ${promptAction}?`); - let inputPrompt: IInquirerInput; + let inputPrompt: InquirerInput; // first index indicates if it has a deep prop, 2nd indicates what kind of + // TODO: this must be reviewed. It starts as an array of booleans but after that it get overridden + // Bye bye functional programming. + // eslint-disable-next-line const isDeepProp: any[] = [false, false]; return this.prompt([ - AutoComplete( - "actionType", - "What property do you want to add to?", - { - pageSize: 7, - source: searchProps, - suggestOnly: false, - }, - ), - ]) - .then((actionTypeAnswer: { - actionType: string, - }) => { - // Set initial prop, like devtool - this.configuration.config.webpackOptions[ - actionTypeAnswer.actionType - ] = null; - // update the action variable, we're using it later - action = actionTypeAnswer.actionType; + AutoComplete("actionType", "What property do you want to add to?", { + pageSize: 7, + source: searchProps, + suggestOnly: false }) - .then((_: void) => { - if (action === "entry") { - return this.prompt([ - Confirm("entryType", "Will your application have multiple bundles?", false), - ]) - .then((entryTypeAnswer: { - entryType: boolean, - }) => { - // Ask different questions for entry points - return entryQuestions(self, entryTypeAnswer); - }) - .then((entryOptions: { - entryType: boolean; - }) => { - this.configuration.config.webpackOptions.entry = entryOptions; - this.configuration.config.item = action; - }); + ]) + .then( + (actionTypeAnswer: { actionType: string }): void => { + // Set initial prop, like devtool + this.configuration.config.webpackOptions[actionTypeAnswer.actionType] = null; + // update the action variable, we're using it later + action = actionTypeAnswer.actionType; + } + ) + .then( + (): void => { + if (action === "entry") { + 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); + } + ) + .then( + (entryOptions: { entryType: boolean }): void => { + this.configuration.config.webpackOptions.entry = entryOptions; + this.configuration.config.item = action; + } + ); } else { if (action === "topScope") { - return this.prompt([ - Input("topScope", "What do you want to add to topScope?"), - ]) - .then((topScopeAnswer: { - topScope: string; - }) => { - this.configuration.config.topScope.push(topScopeAnswer.topScope); - done(); - }); + return this.prompt([Input("topScope", "What do you want to add to topScope?")]).then( + (topScopeAnswer: { topScope: string }): void => { + this.configuration.config.topScope.push(topScopeAnswer.topScope); + done(); + } + ); } } - const temp = action; - if (action === "resolveLoader") { - action = "resolve"; - } - const webpackSchemaProp: ISchemaProperties = webpackSchema.definitions[action]; - /* - * https://github.com/webpack/webpack/blob/next/schemas/WebpackOptions.json - * Find the properties directly in the properties prop, or the anyOf prop - */ - let defOrPropDescription: object = webpackSchemaProp - ? webpackSchemaProp.properties - : webpackSchema.properties[action].properties + const temp = action; + if (action === "resolveLoader") { + action = "resolve"; + } + const webpackSchemaProp: SchemaProperties = webpackSchema.definitions[action]; + /* + * https://github.com/webpack/webpack/blob/next/schemas/WebpackOptions.json + * Find the properties directly in the properties prop, or the anyOf prop + */ + let defOrPropDescription: object = webpackSchemaProp + ? webpackSchemaProp.properties + : webpackSchema.properties[action].properties ? webpackSchema.properties[action].properties : webpackSchema.properties[action].anyOf - ? webpackSchema.properties[action].anyOf.filter( - (p: { - properties?: object, - enum?: any[], - }) => p.properties || p.enum, - ) - : null; - if (Array.isArray(defOrPropDescription)) { - // Todo: Generalize these to go through the array, then merge enum with props if needed - const hasPropertiesProp: boolean = traverseAndGetProperties( - defOrPropDescription, - "properties", - ); - const hasEnumProp: boolean = traverseAndGetProperties( - defOrPropDescription, - "enum", - ); - /* as we know he schema only has two arrays that might hold our values, - * check them for either having arr.enum or arr.properties - */ - if (hasPropertiesProp) { - defOrPropDescription = - defOrPropDescription[0].properties || - defOrPropDescription[1].properties; - if (!defOrPropDescription) { - defOrPropDescription = defOrPropDescription[0].enum; - } - // TODO: manually implement stats and devtools like sourcemaps - } else if (hasEnumProp) { - const originalPropDesc: object = defOrPropDescription[0].enum; - // Array -> Object -> Merge objects into one for compat in manualOrListInput - defOrPropDescription = Object.keys(defOrPropDescription[0].enum) - .map((p: string): object => { - return Object.assign( - {}, - { - [originalPropDesc[p]]: "noop", - }, - ); - }) - .reduce((result: object, currentObject: object): object => { - for (const key in currentObject) { - if (currentObject.hasOwnProperty(key)) { - result[key] = currentObject[key]; + ? webpackSchema.properties[action].anyOf.filter( + (p: { properties?: object; enum?: string[] }): boolean => !!p.properties || !!p.enum + ) + : null; + if (Array.isArray(defOrPropDescription)) { + // Todo: Generalize these to go through the array, then merge enum with props if needed + const hasPropertiesProp: boolean = traverseAndGetProperties(defOrPropDescription, "properties"); + const hasEnumProp: boolean = traverseAndGetProperties(defOrPropDescription, "enum"); + /* as we know he schema only has two arrays that might hold our values, + * check them for either having arr.enum or arr.properties + */ + if (hasPropertiesProp) { + defOrPropDescription = + defOrPropDescription[0].properties || defOrPropDescription[1].properties; + if (!defOrPropDescription) { + defOrPropDescription = defOrPropDescription[0].enum; + } + // TODO: manually implement stats and devtools like sourcemaps + } else if (hasEnumProp) { + const originalPropDesc: object = defOrPropDescription[0].enum; + // Array -> Object -> Merge objects into one for compat in manualOrListInput + defOrPropDescription = Object.keys(defOrPropDescription[0].enum) + .map( + (p: string): object => { + return Object.assign( + {}, + { + [originalPropDesc[p]]: "noop" + } + ); } - } - return result; - }, {}); + ) + .reduce((result: object, currentObject: object): object => { + for (const key in currentObject) { + if (currentObject.hasOwnProperty(key)) { + result[key] = currentObject[key]; + } + } + return result; + }, {}); + } } - } - // WDS has its own schema, so we gonna need to check that too - const webpackDevserverSchemaProp: ISchemaProperties = - action === "devServer" ? webpackDevServerSchema : null; - // Watch has a boolean arg, but we need to append to it manually - if (action === "watch") { - defOrPropDescription = { - false: {}, - true: {}, - }; - } - if (action === "mode") { - defOrPropDescription = { - development: {}, - production: {}, - }; - } - action = temp; - if (action === "resolveLoader") { - defOrPropDescription = Object.assign(defOrPropDescription, { - moduleExtensions: {}, - }); - } - // If we've got a schema prop or devServer Schema Prop - if (defOrPropDescription || webpackDevserverSchemaProp) { - // Check for properties in definitions[action] or properties[action] - if (defOrPropDescription) { - if (action !== "devtool") { - // Add the option of adding an own variable if the user wants - defOrPropDescription = Object.assign(defOrPropDescription, { - other: {}, - }); + // WDS has its own schema, so we gonna need to check that too + const webpackDevserverSchemaProp: SchemaProperties = + action === "devServer" ? webpackDevServerSchema : null; + // Watch has a boolean arg, but we need to append to it manually + if (action === "watch") { + defOrPropDescription = { + false: {}, + true: {} + }; + } + if (action === "mode") { + defOrPropDescription = { + development: {}, + production: {} + }; + } + action = temp; + if (action === "resolveLoader") { + defOrPropDescription = Object.assign(defOrPropDescription, { + moduleExtensions: {} + }); + } + // If we've got a schema prop or devServer Schema Prop + if (defOrPropDescription || webpackDevserverSchemaProp) { + // Check for properties in definitions[action] or properties[action] + if (defOrPropDescription) { + if (action !== "devtool") { + // Add the option of adding an own variable if the user wants + defOrPropDescription = Object.assign(defOrPropDescription, { + other: {} + }); + } else { + // The schema doesn't have the source maps we can prompt, so add those + defOrPropDescription = Object.assign(defOrPropDescription, { + "cheap-eval-source-map": {}, + "cheap-module-eval-source-map": {}, + "cheap-module-source-map": {}, + "cheap-source-map": {}, + eval: {}, + "eval-source-map": {}, + "hidden-source-map": {}, + "inline-cheap-module-source-map": {}, + "inline-cheap-source-map": {}, + "inline-source-map": {}, + "nosources-source-map": {}, + "source-map": {} + }); + } + inputPrompt = List( + "actionAnswer", + `What do you want to add to ${action}?`, + Object.keys(defOrPropDescription) + ); + // We know we're gonna append some deep prop like module.rule + isDeepProp[0] = true; + } else if (webpackDevserverSchemaProp) { + // Append the custom property option + webpackDevserverSchemaProp.properties = Object.assign( + webpackDevserverSchemaProp.properties, + { + other: {} + } + ); + inputPrompt = List( + "actionAnswer", + `What do you want to add to ${action}?`, + Object.keys(webpackDevserverSchemaProp.properties) + ); + // We know we are in a devServer.prop scenario + isDeepProp[0] = true; } else { - // The schema doesn't have the source maps we can prompt, so add those - defOrPropDescription = Object.assign(defOrPropDescription, { - "cheap-eval-source-map": {}, - "cheap-module-eval-source-map": {}, - "cheap-module-source-map": {}, - "cheap-source-map": {}, - "eval": {}, - "eval-source-map": {}, - "hidden-source-map": {}, - "inline-cheap-module-source-map": {}, - "inline-cheap-source-map": {}, - "inline-source-map": {}, - "nosources-source-map": {}, - "source-map": {}, - }); + // manual input if non-existent + inputPrompt = manualOrListInput(action); } - inputPrompt = List( - "actionAnswer", - `What do you want to add to ${action}?`, - Object.keys(defOrPropDescription), - ); - // We know we're gonna append some deep prop like module.rule - isDeepProp[0] = true; - } else if (webpackDevserverSchemaProp) { - // Append the custom property option - webpackDevserverSchemaProp.properties = Object.assign( - webpackDevserverSchemaProp.properties, - { - other: {}, - }, - ); - inputPrompt = List( - "actionAnswer", - `What do you want to add to ${action}?`, - Object.keys(webpackDevserverSchemaProp.properties), - ); - // We know we are in a devServer.prop scenario - isDeepProp[0] = true; } else { - // manual input if non-existent inputPrompt = manualOrListInput(action); } - } else { - inputPrompt = manualOrListInput(action); - } - return this.prompt([ - inputPrompt, - ]); - }) - .then((answerToAction: { - actionAnswer: string, - }) => { - if (!answerToAction) { - done(); - return; + return this.prompt([inputPrompt]); } - /* - * Plugins got their own logic, - * find the names of each natively plugin and check if it matches - */ - if (action === "plugins") { - const pluginExist: string = glob - .sync([ - "node_modules/webpack/lib/*Plugin.js", - "node_modules/webpack/lib/**/*Plugin.js", - ]) - .map((p: string): string => - p - .split("/") - .pop() - .replace(".js", ""), - ) - .find( - (p: string): boolean => p.toLowerCase().indexOf(answerToAction.actionAnswer) >= 0, - ); - - if (pluginExist) { - this.configuration.config.item = pluginExist; - const pluginsSchemaPath: string = glob - .sync([ - "node_modules/webpack/schemas/plugins/*Plugin.json", - "node_modules/webpack/schemas/plugins/**/*Plugin.json", - ]) - .find( - (p: string): boolean => + ) + .then( + (answerToAction: { actionAnswer: string }): void => { + if (!answerToAction) { + done(); + return; + } + /* + * Plugins got their own logic, + * find the names of each natively plugin and check if it matches + */ + if (action === "plugins") { + const pluginExist: string = glob + .sync(["node_modules/webpack/lib/*Plugin.js", "node_modules/webpack/lib/**/*Plugin.js"]) + .map( + (p: string): string => p .split("/") .pop() - .replace(".json", "") - .toLowerCase() - .indexOf(answerToAction.actionAnswer) >= 0, - ); - if (pluginsSchemaPath) { - const constructorPrefix: string = - pluginsSchemaPath.indexOf("optimize") >= 0 - ? "webpack.optimize" - : "webpack"; - const resolvePluginsPath: string = path.resolve(pluginsSchemaPath); - const pluginSchema: object = resolvePluginsPath - ? require(resolvePluginsPath) - : null; - let pluginsSchemaProps: string[] = ["other"]; - if (pluginSchema) { - Object.keys(pluginSchema) - .filter((p: string): boolean => Array.isArray(pluginSchema[p])) - .forEach((p: string): void => { - Object.keys(pluginSchema[p]).forEach((n: string): void => { - if (pluginSchema[p][n].properties) { - pluginsSchemaProps = Object.keys( - pluginSchema[p][n].properties, + .replace(".js", "") + ) + .find((p: string): boolean => p.toLowerCase().indexOf(answerToAction.actionAnswer) >= 0); + + if (pluginExist) { + this.configuration.config.item = pluginExist; + const pluginsSchemaPath: string = glob + .sync([ + "node_modules/webpack/schemas/plugins/*Plugin.json", + "node_modules/webpack/schemas/plugins/**/*Plugin.json" + ]) + .find( + (p: string): boolean => + p + .split("/") + .pop() + .replace(".json", "") + .toLowerCase() + .indexOf(answerToAction.actionAnswer) >= 0 + ); + if (pluginsSchemaPath) { + const constructorPrefix: string = + pluginsSchemaPath.indexOf("optimize") >= 0 ? "webpack.optimize" : "webpack"; + const resolvePluginsPath: string = path.resolve(pluginsSchemaPath); + const pluginSchema: object = resolvePluginsPath ? require(resolvePluginsPath) : null; + let pluginsSchemaProps: string[] = ["other"]; + if (pluginSchema) { + Object.keys(pluginSchema) + .filter((p: string): boolean => Array.isArray(pluginSchema[p])) + .forEach( + (p: string): void => { + Object.keys(pluginSchema[p]).forEach( + (n: string): void => { + if (pluginSchema[p][n].properties) { + pluginsSchemaProps = Object.keys( + pluginSchema[p][n].properties + ); + } + } ); } - }); - }); - } + ); + } - return this.prompt([ - List( - "pluginsPropType", - `What property do you want to add ${pluginExist}?`, - pluginsSchemaProps, - ), - ]).then((pluginsPropAnswer: { - pluginsPropType: string, - }) => { return this.prompt([ - Input( - "pluginsPropTypeVal", - `What value should ${pluginExist}.${ - pluginsPropAnswer.pluginsPropType - } have?`, - ), - ]).then((valForProp: { - pluginsPropTypeVal: string, - }) => { - this.configuration.config.webpackOptions[action] = { - [`${constructorPrefix}.${pluginExist}`]: { - [pluginsPropAnswer.pluginsPropType]: - valForProp.pluginsPropTypeVal, - }, - }; - done(); - }); - }); + List( + "pluginsPropType", + `What property do you want to add ${pluginExist}?`, + pluginsSchemaProps + ) + ]).then( + (pluginsPropAnswer: { pluginsPropType: string }): Promise<{}> => { + return this.prompt([ + Input( + "pluginsPropTypeVal", + `What value should ${pluginExist}.${ + pluginsPropAnswer.pluginsPropType + } have?` + ) + ]).then( + (valForProp: { pluginsPropTypeVal: string }): void => { + this.configuration.config.webpackOptions[action] = { + [`${constructorPrefix}.${pluginExist}`]: { + [pluginsPropAnswer.pluginsPropType]: + valForProp.pluginsPropTypeVal + } + }; + done(); + } + ); + } + ); + } else { + this.configuration.config.webpackOptions[action] = `new webpack.${pluginExist}`; + done(); + } } else { - this.configuration.config.webpackOptions[ - action - ] = `new webpack.${pluginExist}`; - done(); + // If its not in webpack, check npm + npmExists(answerToAction.actionAnswer).then( + (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() + ); + this.configuration.config.topScope.push( + `const ${pluginName} = require("${answerToAction.actionAnswer}")` + ); + this.configuration.config.webpackOptions[action] = `new ${pluginName}`; + this.configuration.config.item = answerToAction.actionAnswer; + done(); + this.scheduleInstallTask(getPackageManager(), this.dependencies, { + "save-dev": true + }); + } else { + console.error( + answerToAction.actionAnswer, + "doesn't exist on NPM or is built in webpack, please check for any misspellings." + ); + process.exit(0); + } + } + ); } } else { - // If its not in webpack, check npm - npmExists(answerToAction.actionAnswer) - .then((p: string) => { - if (p) { - this.dependencies.push(answerToAction.actionAnswer); - const normalizePluginName = answerToAction.actionAnswer.replace( - "-webpack-plugin", - "Plugin", - ); - const pluginName = replaceAt( - normalizePluginName, - 0, - normalizePluginName.charAt(0).toUpperCase(), - ); - this.configuration.config.topScope.push( - `const ${pluginName} = require("${ - answerToAction.actionAnswer - }")`, - ); - this.configuration.config.webpackOptions[ - action - ] = `new ${pluginName}`; - this.configuration.config.item = answerToAction.actionAnswer; - done(); - this.scheduleInstallTask(getPackageManager(), this.dependencies, { - "save-dev": true, - }); - } else { - console.error( - answerToAction.actionAnswer, - "doesn't exist on NPM or is built in webpack, please check for any misspellings.", - ); - process.exit(0); + // If we're in the scenario with a deep-property + if (isDeepProp[0]) { + isDeepProp[1] = answerToAction.actionAnswer; + if ( + isDeepProp[1] !== "other" && + (action === "devtool" || action === "watch" || action === "mode") + ) { + this.configuration.config.item = action; + this.configuration.config.webpackOptions[action] = answerToAction.actionAnswer; + done(); + return; + } + // Either we are adding directly at the property, else we're in a prop.theOne scenario + const actionMessage = + isDeepProp[1] === "other" + ? `What do you want the key on ${action} to be? (press enter if you want it directly as a value on the property)` + : `What do you want the value of ${isDeepProp[1]} to be?`; + + this.prompt([Input("deepProp", actionMessage)]).then( + (deepPropAns: { deepProp: string }): void => { + // The other option needs to be validated of either being empty or not + if (isDeepProp[1] === "other") { + const othersDeepPropKey: string = deepPropAns.deepProp + ? `What do you want the value of ${deepPropAns.deepProp} to be?` // eslint-disable-line + : `What do you want to be the value of ${action} to be?`; + // Push the answer to the array we have created, so we can use it later + isDeepProp.push(deepPropAns.deepProp); + this.prompt([Input("innerProp", othersDeepPropKey)]).then( + (innerPropAns: { innerProp }): void => { + // Check length, if it has none, add the prop directly on the given action + if (isDeepProp[2].length === 0) { + this.configuration.config.item = action; + this.configuration.config.webpackOptions[action] = + innerPropAns.innerProp; + } else { + // If not, we're adding to something like devServer.myProp + this.configuration.config.item = action + "." + isDeepProp[2]; + this.configuration.config.webpackOptions[action] = { + [isDeepProp[2]]: innerPropAns.innerProp + }; + } + done(); + } + ); + } else { + // We got the schema prop, we've correctly prompted it, and can add it directly + this.configuration.config.item = `${action}.${isDeepProp[1]}`; + this.configuration.config.webpackOptions[action] = { + [isDeepProp[1]]: deepPropAns.deepProp + }; + done(); + } } - }); - } - } else { - // If we're in the scenario with a deep-property - if (isDeepProp[0]) { - isDeepProp[1] = answerToAction.actionAnswer; - if ( - isDeepProp[1] !== "other" && - (action === "devtool" || action === "watch" || action === "mode") - ) { + ); + } else { + // We're asking for input-only this.configuration.config.item = action; - this.configuration.config.webpackOptions[action] = - answerToAction.actionAnswer; + this.configuration.config.webpackOptions[action] = answerToAction.actionAnswer; done(); - return; } - // Either we are adding directly at the property, else we're in a prop.theOne scenario - const actionMessage = - isDeepProp[1] === "other" - ? `What do you want the key on ${ - action - } to be? (press enter if you want it directly as a value on the property)` - : `What do you want the value of ${isDeepProp[1]} to be?`; - - this.prompt([ - Input("deepProp", actionMessage), - ]).then( - (deepPropAns: { - deepProp: string, - }) => { - // The other option needs to be validated of either being empty or not - if (isDeepProp[1] === "other") { - const othersDeepPropKey: string = deepPropAns.deepProp - ? `What do you want the value of ${ - deepPropAns.deepProp - } to be?` // eslint-disable-line - : `What do you want to be the value of ${action} to be?`; - // Push the answer to the array we have created, so we can use it later - isDeepProp.push(deepPropAns.deepProp); - this.prompt([ - Input("innerProp", othersDeepPropKey), - ]).then( - (innerPropAns: { - innerProp, - }) => { - // Check length, if it has none, add the prop directly on the given action - if (isDeepProp[2].length === 0) { - this.configuration.config.item = action; - this.configuration.config.webpackOptions[action] = - innerPropAns.innerProp; - } else { - // If not, we're adding to something like devServer.myProp - this.configuration.config.item = - action + "." + isDeepProp[2]; - this.configuration.config.webpackOptions[action] = { - [isDeepProp[2]]: innerPropAns.innerProp, - }; - } - done(); - }, - ); - } else { - // We got the schema prop, we've correctly prompted it, and can add it directly - this.configuration.config.item = `${action}.${isDeepProp[1]}`; - this.configuration.config.webpackOptions[action] = { - [isDeepProp[1]]: deepPropAns.deepProp, - }; - done(); - } - }, - ); - } else { - // We're asking for input-only - this.configuration.config.item = action; - this.configuration.config.webpackOptions[action] = - answerToAction.actionAnswer; - done(); } } - }); + ); } - public writing() { + public writing(): void { this.config.set("configuration", this.configuration); } } diff --git a/packages/generators/addon-generator.ts b/packages/generators/addon-generator.ts index 7f83dddf104..d81c2d0b378 100644 --- a/packages/generators/addon-generator.ts +++ b/packages/generators/addon-generator.ts @@ -3,7 +3,8 @@ import * as path from "path"; import Generator = require("yeoman-generator"); import * as copyUtils from "@webpack-cli/utils/copy-utils"; -import { IInquirerScaffoldObject } from "@webpack-cli/webpack-scaffold"; +import { InquirerScaffoldObject } from "@webpack-cli/webpack-scaffold"; +import { YeoGenerator } from "../generate-loader/types/Yeoman"; /** * Creates a Yeoman Generator that generates a project conforming @@ -27,58 +28,58 @@ import { IInquirerScaffoldObject } from "@webpack-cli/webpack-scaffold"; * @returns {Generator} A class extending Generator */ export default function addonGenerator( - prompts: IInquirerScaffoldObject[], + prompts: InquirerScaffoldObject[], templateDir: string, copyFiles: string[], copyTemplateFiles: string[], - templateFn: Function, -) { + templateFn: Function +): YeoGenerator { return class AddOnGenerator extends Generator { - public props: IInquirerScaffoldObject; - private copy: (value: string, index: number, array: string[]) => void; - private copyTpl: (value: string, index: number, array: string[]) => void; + public props: InquirerScaffoldObject; + public copy: (value: string, index: number, array: string[]) => void; + public copyTpl: (value: string, index: number, array: string[]) => void; public prompting(): Promise<{}> { - return this.prompt(prompts) - .then((props: IInquirerScaffoldObject): void => { + return this.prompt(prompts).then( + (props: InquirerScaffoldObject): void => { this.props = props; - }); + } + ); } - public default() { + public default(): void { const currentDirName = path.basename(this.destinationPath()); if (currentDirName !== this.props.name) { this.log(` Your project must be inside a folder named ${this.props.name} I will create this folder for you. `); - mkdirp(this.props.name, (err: object) => { - console.error("Failed to create directory", err); - }); + mkdirp( + this.props.name, + (err: object): void => { + console.error("Failed to create directory", err); + } + ); const pathToProjectDir: string = this.destinationPath(this.props.name); this.destinationRoot(pathToProjectDir); } } - public writing() { + public writing(): void { this.copy = copyUtils.generatorCopy(this, templateDir); - this.copyTpl = copyUtils.generatorCopyTpl( - this, - templateDir, - templateFn(this), - ); + this.copyTpl = copyUtils.generatorCopyTpl(this, templateDir, templateFn(this)); copyFiles.forEach(this.copy); copyTemplateFiles.forEach(this.copyTpl); } - public install() { + public install(): void { this.npmInstall(["webpack-defaults", "bluebird"], { - "save-dev": true, + "save-dev": true }); } - public end() { + public end(): void { this.spawnCommand("npm", ["run", "defaults"]); } }; diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts index 90207de3c61..c33e038a087 100644 --- a/packages/generators/init-generator.ts +++ b/packages/generators/init-generator.ts @@ -3,13 +3,9 @@ import * as logSymbols from "log-symbols"; import Generator = require("yeoman-generator"); import { getPackageManager } from "@webpack-cli/utils/package-manager"; -import { - Confirm, - Input, - List, -} from "@webpack-cli/webpack-scaffold"; +import { Confirm, Input, List } from "@webpack-cli/webpack-scaffold"; -import { IWebpackOptions } from "./types"; +import { WebpackOptions } from "./types"; import entryQuestions from "./utils/entry"; import getBabelPlugin from "./utils/module"; import getDefaultPlugins from "./utils/plugins"; @@ -30,32 +26,33 @@ export default class InitGenerator extends Generator { private dependencies: string[]; private configuration: { config: { - configName?: string, - topScope?: string[], - webpackOptions?: IWebpackOptions, - }, + configName?: string; + topScope?: string[]; + webpackOptions?: WebpackOptions; + }; }; - constructor(args, opts) { + 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.dependencies = [ + "webpack", + "webpack-cli", + "terser-webpack-plugin", + "babel-plugin-syntax-dynamic-import" + ]); this.configuration = { config: { topScope: [], - webpackOptions: {}, - }, + webpackOptions: {} + } }; } - public prompting() { - const done: (_?: void) => void | boolean = this.async(); + // eslint-disable-next-line + public prompting(): any { + const done: () => void | boolean = this.async(); const self: this = this; let regExpForStyles: string; let ExtractUseProps: object[]; @@ -65,389 +62,361 @@ export default class InitGenerator extends Generator { 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", + 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", + "\n\n" ); this.configuration.config.webpackOptions.module = { - rules: [], + rules: [] }; this.configuration.config.topScope.push( "const webpack = require('webpack')", "const path = require('path')", - "\n", + "\n" ); - return this.prompt([ - Confirm("entryType", "Will your application have multiple bundles?", false), - ]) - .then((entryTypeAnswer: { - entryType: boolean; - }) => { - // Ask different questions for entry points - return entryQuestions(self, entryTypeAnswer); - }) - .then((entryOptions: object | string) => { - if (typeof entryOptions === "string" && entryOptions.length > 0) { + 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); + } + ) + .then( + (entryOptions: object | string): Promise<{}> => { + if (typeof entryOptions === "string" && entryOptions.length > 0) { + return this.prompt([ + Input("outputType", "In which folder do you want to store your generated bundles? (dist):") + ]); + } + if (entryOptions !== '""') { + this.configuration.config.webpackOptions.entry = entryOptions; + } return this.prompt([ - Input( - "outputType", - "In which folder do you want to store your generated bundles? (dist):", - ), + Input("outputType", "In which folder do you want to store your generated bundles? (dist):") ]); } - if (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((outputTypeAnswer: { - outputType: 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( + (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 + }')`; + } } - if (!this.usingDefaults && outputTypeAnswer.outputType.length) { - this.configuration.config.webpackOptions.output.path = - `path.resolve(__dirname, '${outputTypeAnswer.outputType}')`; + ) + .then( + (): void => { + 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?")]); } - }) - .then((_: void) => { - this.isProd = this.usingDefaults ? true : false; - this.configuration.config.configName = this.isProd ? "prod" : "config"; - if (!this.isProd) { - this.configuration.config.webpackOptions.mode = "'development'"; + ) + .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"); + } } - this.configuration.config.webpackOptions.plugins = this.isProd ? [] : getDefaultPlugins(); - return this.prompt([ - Confirm("babelConfirm", "Will you be using ES2015?"), - ]); - }) - .then((babelConfirmAnswer: { - babelConfirm: boolean; - }) => { - if (babelConfirmAnswer.babelConfirm) { - this.configuration.config.webpackOptions.module.rules.push( - getBabelPlugin(), - ); - this.dependencies.push( - "babel-loader", - "@babel/core", - "@babel/preset-env", - ); + ) + .then( + (): void => { + return this.prompt([ + List("stylingType", "Will you use one of the below CSS solutions?", [ + "No", + "CSS", + "SASS", + "LESS", + "PostCSS" + ]) + ]); } - }) - .then((_: void) => { - return this.prompt([ - List("stylingType", "Will you use one of the below CSS solutions?", [ - "No", - "CSS", - "SASS", - "LESS", - "PostCSS", - ]), - ]); - }) - .then((stylingTypeAnswer: { - stylingType: string; - }) => { - 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, + ) + .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, + { + loader: "'sass-loader'", + options: { + sourceMap: true + } + } + ); + } else { + ExtractUseProps.push( + { + loader: "'style-loader'" }, - }, - ); - } 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: "'css-loader'" }, - }, - { - loader: "'less-loader'", - options: { - sourceMap: true, + { + 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 + } }, - }, - ); - } else { - 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, - }, - }, + { + 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" ); - } - 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, + 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 () { + { + loader: "'postcss-loader'", + options: { + plugins: `function () { return [ precss, autoprefixer ]; - }`, + }` + } + } + ); + } else { + ExtractUseProps.push( + { + loader: "'style-loader'" }, - }, - ); - } else { - ExtractUseProps.push( - { - loader: "'style-loader'", - }, - { - loader: "'css-loader'", - options: { - importLoaders: 1, - sourceMap: true, + { + loader: "'css-loader'", + options: { + importLoaders: 1, + sourceMap: true + } }, - }, - { - loader: "'postcss-loader'", - options: { - plugins: `function () { + { + 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'", + }` + } + } + ); + } + 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, + sourceMap: true + } + }); + } else { + ExtractUseProps.push( + { + loader: "'style-loader'", + options: { + sourceMap: true + } }, - }, - { - loader: "'css-loader'", - }, - ); - } - break; - default: - regExpForStyles = null; - } - }) - .then((_: void) => { - 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)", - ), - ]); + { + loader: "'css-loader'" + } + ); + } + break; + default: + regExpForStyles = null; + } } - }) - .then((extractPluginAnswer: { - extractPlugin: string; - }) => { - if (regExpForStyles) { + ) + .then( + (): void => { if (this.isProd) { - const cssBundleName: string = extractPluginAnswer.extractPlugin; - this.configuration.config.topScope.push(tooltip.cssPlugin()); - this.dependencies.push("mini-css-extract-plugin"); + // 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.push( - // TODO: use [contenthash] after it is supported - `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })`, - ); - } else { - this.configuration.config.webpackOptions.plugins.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", - }); + ExtractUseProps.unshift({ + loader: "MiniCssExtractPlugin.loader" + }); - const moduleRulesObj = { - test: regExpForStyles, - use: ExtractUseProps, - }; + 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", - ); - } else { - const moduleRulesObj: { - test: string; - use: object[]; - } = { - 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" + ); + } else { + const moduleRulesObj: { + test: string; + use: object[]; + } = { + test: regExpForStyles, + use: ExtractUseProps + }; - this.configuration.config.webpackOptions.module.rules.push( - moduleRulesObj, - ); + this.configuration.config.webpackOptions.module.rules.push(moduleRulesObj); + } } - } - // 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[\\\\/]/", + // 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(); - }); + chunks: "'async'", + minChunks: 1, + minSize: 30000, + // for production name is recommended to be off + name: !this.isProd + } + }; + done(); + } + ); } - public installPlugins() { + public installPlugins(): void { if (this.isProd) { - this.dependencies = this.dependencies.filter( - (p: string): boolean => p !== "terser-webpack-plugin", - ); + 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", + "\n" ); } const packager = getPackageManager(); const opts: { - dev?: boolean, - "save-dev"?: boolean, + dev?: boolean; + "save-dev"?: boolean; } = packager === "yarn" ? { dev: true } : { "save-dev": true }; this.scheduleInstallTask(packager, this.dependencies, opts); } - public writing() { + public writing(): void { this.config.set("configuration", this.configuration); } } diff --git a/packages/generators/remove-generator.ts b/packages/generators/remove-generator.ts index d81bdeeaf94..a1ab387b847 100644 --- a/packages/generators/remove-generator.ts +++ b/packages/generators/remove-generator.ts @@ -4,7 +4,7 @@ import Generator = require("yeoman-generator"); import PROP_TYPES from "@webpack-cli/utils/prop-types"; import { List } from "@webpack-cli/webpack-scaffold"; -import { IWebpackOptions } from "./types"; +import { WebpackOptions } from "./types"; /** * @@ -18,19 +18,19 @@ import { IWebpackOptions } from "./types"; export default class RemoveGenerator extends Generator { private configuration: { config: { - configName?: string, - topScope?: string[], - webpackOptions?: IWebpackOptions, - }, + configName?: string; + topScope?: string[]; + webpackOptions?: WebpackOptions; + }; }; - private webpackOptions: IWebpackOptions | string; + private webpackOptions: WebpackOptions | string; - constructor(args, opts) { + public constructor(args, opts) { super(args, opts); this.configuration = { config: { - webpackOptions: {}, - }, + webpackOptions: {} + } }; let configPath = path.resolve(process.cwd(), "webpack.config.js"); @@ -49,90 +49,96 @@ export default class RemoveGenerator extends Generator { public getModuleLoadersNames(): string[] { if (typeof this.webpackOptions === "object") { if (this.webpackOptions.module && this.webpackOptions.module.rules) { - return this.webpackOptions.module.rules.map((rule: { - loader: string; - }) => rule ? rule.loader : null); + return this.webpackOptions.module.rules.map( + (rule: { loader: string }): string | null => (rule ? rule.loader : null) + ); } } } - public prompting() { - const done: (_?: void) => void | boolean = this.async(); + public prompting(): Promise<{}> { + const done: () => void | boolean = this.async(); let propValue: object | string | boolean; - return this.prompt([ - List( - "propType", - "Which property do you want to remove?", - Array.from(this.getPropTypes()), - ), - ]) - .then(({ propType }: { propType: string }): Promise<{}> => { - if (!PROP_TYPES.has(propType)) { - console.error("Invalid webpack config prop"); - return; - } + return this.prompt([List("propType", "Which property do you want to remove?", Array.from(this.getPropTypes()))]) + .then( + ({ propType }: { propType: string }): Promise<{}> => { + if (!PROP_TYPES.has(propType)) { + console.error("Invalid webpack config prop"); + return; + } - propValue = this.webpackOptions[propType]; - if (typeof propValue === "object") { - if (Array.isArray(propValue)) { - return this.prompt([ - List( - "keyType", - `Which key do you want to remove from ${propType}?`, - Array.from(propValue), - ), - ]).then(({ keyType }: { keyType: string }): void => { - this.configuration.config.webpackOptions[propType] = [ keyType ]; - }); - } else { - return this.prompt([ - List( - "keyType", - `Which key do you want to remove from ${propType}?`, - Array.from(Object.keys(propValue)), - ), - ]) - .then(({ keyType }: { keyType: string }): Promise<{}> => { - if (propType === "module" && keyType === "rules") { - return this.prompt([ - List( - "rule", - "Which loader do you want to remove?", - Array.from(this.getModuleLoadersNames()), - ), - ]) - .then(({ rule }: { rule: string }): void => { - if (typeof this.webpackOptions === "object") { - const loaderIndex: number = this.getModuleLoadersNames().indexOf(rule); - const loader: object = this.webpackOptions.module.rules[loaderIndex]; - this.configuration.config.webpackOptions.module = { - rules: [ loader ], - }; + propValue = this.webpackOptions[propType]; + if (typeof propValue === "object") { + if (Array.isArray(propValue)) { + return this.prompt([ + List( + "keyType", + `Which key do you want to remove from ${propType}?`, + Array.from(propValue) + ) + ]).then( + ({ keyType }: { keyType: string }): void => { + this.configuration.config.webpackOptions[propType] = [keyType]; + } + ); + } else { + return this.prompt([ + List( + "keyType", + `Which key do you want to remove from ${propType}?`, + Array.from(Object.keys(propValue)) + ) + ]).then( + ({ keyType }: { keyType: string }): Promise<{}> => { + if (propType === "module" && keyType === "rules") { + return this.prompt([ + List( + "rule", + "Which loader do you want to remove?", + Array.from(this.getModuleLoadersNames()) + ) + ]).then( + ({ rule }: { rule: string }): void => { + if (typeof this.webpackOptions === "object") { + const loaderIndex: number = this.getModuleLoadersNames().indexOf( + rule + ); + const loader: object = this.webpackOptions.module.rules[ + loaderIndex + ]; + this.configuration.config.webpackOptions.module = { + rules: [loader] + }; + } } - }); - } else { - // remove the complete prop object if there is only one key - if (Object.keys(this.webpackOptions[propType]).length <= 1) { - this.configuration.config.webpackOptions[propType] = null; + ); } else { - this.configuration.config.webpackOptions[propType] = { - [keyType]: null, - }; + // remove the complete prop object if there is only one key + if (Object.keys(this.webpackOptions[propType]).length <= 1) { + this.configuration.config.webpackOptions[propType] = null; + } else { + this.configuration.config.webpackOptions[propType] = { + [keyType]: null + }; + } } } - }); + ); + } + } else { + this.configuration.config.webpackOptions[propType] = null; } - } else { - this.configuration.config.webpackOptions[propType] = null; } - }) - .then((_: void): void => { - done(); - }); + ) + .then( + (): void => { + done(); + } + ); } - public writing() { + public writing(): void { this.config.set("configuration", this.configuration); } } diff --git a/packages/generators/tslint.json b/packages/generators/tslint.json deleted file mode 100644 index 0946f20963a..00000000000 --- a/packages/generators/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../tslint.json" -} diff --git a/packages/generators/types/index.ts b/packages/generators/types/index.ts index 1adc7ee911c..449dc0cc477 100644 --- a/packages/generators/types/index.ts +++ b/packages/generators/types/index.ts @@ -1,11 +1,11 @@ -export interface ISchemaProperties { +export interface SchemaProperties { additionalProperties?: boolean; definitions?: object; properties?: object; type?: string; } -interface IWebpackResolve { +interface WebpackResolve { alias?: object; aliasFields?: string[]; cachePredicate?: Function; @@ -27,7 +27,7 @@ interface IWebpackResolve { type IRuleSetCondition = RegExp | string | Function | object; -export interface IWebpackOptions { +export interface WebpackOptions { amd?: string; bail?: boolean; cache?: boolean | object; @@ -47,10 +47,12 @@ export interface IWebpackOptions { headers?: object; logLevel?: string; clientLogLevel?: string; - overlay?: boolean | { - errors?: boolean; - warnings?: boolean; - }; + overlay?: + | boolean + | { + errors?: boolean; + warnings?: boolean; + }; progress?: boolean; key?: string | Buffer; cert?: string | Buffer; @@ -69,10 +71,12 @@ export interface IWebpackOptions { openPage?: string; compress?: boolean; proxy?: object[] | Function[]; - historyApiFallback?: boolean | { - rewrites?: object[]; - disableDotRule?: boolean; - }; + historyApiFallback?: + | boolean + | { + rewrites?: object[]; + disableDotRule?: boolean; + }; staticOptions?: object; setup?: Function; before?: Function; @@ -97,25 +101,7 @@ export interface IWebpackOptions { exprContextRegExp?: boolean | RegExp; exprContextRequest?: string; noParse?: string | string[] | Function | RegExp | RegExp[]; - rules?: Array<{ - enforce?: "pre" | "post"; - exclude?: IRuleSetCondition; - include?: IRuleSetCondition; - issuer?: IRuleSetCondition; - loader?: string | Function | object; - loaders?: Function[] | object[]; - options?: object; - parser?: object; - sideEffects?: boolean; - type?: string; - resource?: IRuleSetCondition; - resourceQuery?: IRuleSetCondition; - compiler?: IRuleSetCondition; - rules?: object[]; - use?: object | object[] | Function; - test?: IRuleSetCondition; - - }>; + rules?: Rule[]; unknownContextCritical?: boolean; unknownContextRecursive?: boolean; unknownContextRegExp?: boolean | RegExp; @@ -127,15 +113,19 @@ export interface IWebpackOptions { strictExportPresence?: boolean; strictThisContextOnImports?: boolean; }; - node?: false | true | string | { - console?: boolean | string; - process?: boolean | string; - global?: boolean; - __filename?: boolean | string; - __dirname?: boolean | string; - Buffer?: boolean | string; - setImmediate?: boolean | string; - }; + node?: + | false + | true + | string + | { + console?: boolean | string; + process?: boolean | string; + global?: boolean; + __filename?: boolean | string; + __dirname?: boolean | string; + Buffer?: boolean | string; + setImmediate?: boolean | string; + }; output?: { auxiliaryComment?: string | object; chunkFilename?: string; @@ -199,19 +189,21 @@ export interface IWebpackOptions { }; }; parallelism?: number; - performance?: false | { - assetFilter?: Function; - hints?: false | string; - maxEntrypointSize?: number; - maxAssetSize?: number; - }; - plugins?: object[] | Function[] | string[] | string | any; + performance?: + | false + | { + assetFilter?: Function; + hints?: false | string; + maxEntrypointSize?: number; + maxAssetSize?: number; + }; + plugins?: object[] | Function[] | string[] | string; profile?: boolean; recordsInputPath?: string; recordsOutputPath?: string; recordsPath?: string; - resolve?: IWebpackResolve; - resolveLoader?: IWebpackResolve; + resolve?: WebpackResolve; + resolveLoader?: WebpackResolve; stats?: string | boolean | object; target?: string | Function; watch?: boolean; @@ -221,3 +213,22 @@ export interface IWebpackOptions { poll?: boolean | number; }; } + +interface Rule { + enforce?: "pre" | "post"; + exclude?: IRuleSetCondition; + include?: IRuleSetCondition; + issuer?: IRuleSetCondition; + loader?: string | Function | object; + loaders?: Function[] | object[]; + options?: object; + parser?: object; + sideEffects?: boolean; + type?: string; + resource?: IRuleSetCondition; + resourceQuery?: IRuleSetCondition; + compiler?: IRuleSetCondition; + rules?: object[]; + use?: object | object[] | Function; + test?: IRuleSetCondition; +} diff --git a/packages/generators/types/json-loader.d.ts b/packages/generators/types/json-loader.d.ts index 0cb4cf5f44b..36396113911 100644 --- a/packages/generators/types/json-loader.d.ts +++ b/packages/generators/types/json-loader.d.ts @@ -1,4 +1,5 @@ declare module "*.json" { + // eslint-disable-next-line const value: any; export default value; } diff --git a/packages/generators/types/yeoman-generator.d.ts b/packages/generators/types/yeoman-generator.d.ts index bc2425c458f..3ca7dd82c1a 100644 --- a/packages/generators/types/yeoman-generator.d.ts +++ b/packages/generators/types/yeoman-generator.d.ts @@ -4,7 +4,7 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /// -interface IYeoman { +interface Yeoman { public config: { set: (setProperty: string, setValue: object) => void; }; @@ -12,8 +12,8 @@ interface IYeoman { adapter: { promptModule: { registerPrompt: (promptName: string, promptModule: object) => void; - }, - }, + }; + }; }; public props: { name: string; @@ -24,16 +24,15 @@ interface IYeoman { public run(target: string, options?: object, done?: Function): IRunEnv; public scheduleInstallTask(packager: string, dependencies: string[], options?: object): void; public on(event: string, listener: Function): this; - public async(): (_?: void) => void | boolean; + public async(): () => void | boolean; public prompt(opt: IPromptOptions[]): Promise<>; public log(message: string): void; public npmInstall(packages?: string[] | string, options?: object, cb?: Function): Promise<>; - public spawnCommand(name: string, args?: string[], options?: Object): void; + public spawnCommand(name: string, args?: string[], options?: object): void; } declare module "yeoman-generator" { - - class YeomanGeneratorBase extends IYeoman { + class YeomanGeneratorBase implements Yeoman { public config: { set: (setProperty: string, setValue: object) => void; }; @@ -41,8 +40,8 @@ declare module "yeoman-generator" { adapter: { promptModule: { registerPrompt: (promptName: string, promptModule: object) => void; - }, - }, + }; + }; }; public props: { name: string; @@ -50,39 +49,42 @@ declare module "yeoman-generator" { public composeWith(namespace: string, options?: object, settings?: IComposeSetting): YeomanGeneratorBase; public destinationRoot(rootPath?: string): string; public destinationPath(...path: string[]): string; - public run(target: string, options?: object, done?: Function): IRunEnv; + public run(target: string, options?: object, done?: Function): RunEnv; public scheduleInstallTask(packager: string, dependencies: string[], options?: object): void; public on(event: string, listener: Function): this; - public async(): (_?: void) => void | boolean; - public prompt(opt: IPromptOptions[]): Promise<>; + public async(): () => void | boolean; + public prompt(opt: PromptOptions[]): Promise<>; public log(message: string): void; public npmInstall(packages?: string[] | string, options?: object, cb?: Function): Promise<>; - public spawnCommand(name: string, args?: string[], options?: Object): void; + public spawnCommand(name: string, args?: string[], options?: object): void; } - interface IRunEnv extends Object { + interface RunEnv extends object { on: (event: string, callbackFn: Function) => void; } - interface IPromptOptions { + interface PromptOptions { type?: string; name: string; - message: string | ((answers: Object) => string); - choices?: string[] | ((answers: Object) => string); - default?: string | number | boolean | string[] | number[] - | ((answers: Object) => (string | number | boolean | string[] | number[])); - validate?: ((input: string) => boolean | string); - when?: ((answers: Object) => boolean) | boolean; + message: string | ((answers: object) => string); + choices?: string[] | ((answers: object) => string); + default?: + | string + | number + | boolean + | string[] + | number[] + | ((answers: object) => string | number | boolean | string[] | number[]); + validate?: (input: string) => boolean | string; + when?: ((answers: object) => boolean) | boolean; store?: boolean; filter?: (name: string) => string; } - // tslint:disable-next-line class NamedBase extends YeomanGeneratorBase implements INamedBase { - constructor(args: string | string[], options: object); + public constructor(args: string | string[], options: object); } - // tslint:disable-next-line class Base extends NamedBase implements IBase { public static extend(protoProps: IQueueProps): YeomanGeneratorBase; } diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts index aae92f38be1..f65af71cde8 100644 --- a/packages/generators/utils/entry.ts +++ b/packages/generators/utils/entry.ts @@ -2,7 +2,7 @@ import { InputValidate } from "@webpack-cli/webpack-scaffold"; import validate from "./validate"; -interface IEntry extends IYeoman { +interface Entry extends Yeoman { usingDefaults?: boolean; } @@ -15,9 +15,12 @@ interface IEntry extends IYeoman { * @returns {Object} An Object that holds the answers given by the user, later used to scaffold */ -export default function entry(self: IEntry, answer: { - entryType: boolean; -}): Promise<{}> { +export default function entry( + self: Entry, + answer: { + entryType: boolean; + } +): Promise<{}> { let entryIdentifiers: string[]; let result: Promise<{}>; if (answer.entryType) { @@ -26,82 +29,90 @@ export default function entry(self: IEntry, answer: { InputValidate( "multipleEntries", "Type the names you want for your modules (entry files), separated by comma [example: app,vendor]", - validate, - ), + validate + ) ]) - .then((multipleEntriesAnswer: { - multipleEntries: string, - }) => { - const webpackEntryPoint: object = {}; - entryIdentifiers = multipleEntriesAnswer.multipleEntries.split(","); + .then( + (multipleEntriesAnswer: { multipleEntries: string }): Promise => { + const webpackEntryPoint: object = {}; + entryIdentifiers = multipleEntriesAnswer.multipleEntries.split(","); - function forEachPromise(entries: string[], fn: (entryProp: string) => Promise<{} | void>) { - return entries.reduce((promise: Promise<{}>, prop: string) => { - const trimmedProp: string = prop.trim(); + function forEachPromise( + entries: string[], + fn: (entryProp: string) => Promise<{} | void> + ): Promise { + return entries.reduce((promise: Promise<{}>, prop: string): Promise => { + const trimmedProp: string = prop.trim(); - return promise.then((n: object) => { - if (n) { - Object.keys(n).forEach((val: string): void => { + return promise.then( + (n: object): Promise => { + if (n) { + Object.keys(n).forEach( + (val: string): void => { + if ( + n[val].charAt(0) !== "(" && + n[val].charAt(0) !== "[" && + !n[val].includes("function") && + !n[val].includes("path") && + !n[val].includes("process") + ) { + n[val] = `\'${n[val].replace(/"|'/g, "").concat(".js")}\'`; + } + 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}"? [example: ./src/${entryProp}]`, + validate + ) + ]) + ).then( + (entryPropAnswer: object): object => { + Object.keys(entryPropAnswer).forEach( + (val: string): void => { if ( - n[val].charAt(0) !== "(" && - n[val].charAt(0) !== "[" && - !n[val].includes("function") && - !n[val].includes("path") && - !n[val].includes("process") + 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")}\'`; + entryPropAnswer[val] = `\'${entryPropAnswer[val].replace(/"|'/g, "")}\'`; } - 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}"? [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") - ) { - entryPropAnswer[val] = `\'${entryPropAnswer[val].replace(/"|'/g, "")}\'`; + webpackEntryPoint[val] = entryPropAnswer[val]; + } + ); + return webpackEntryPoint; } - webpackEntryPoint[val] = entryPropAnswer[val]; - }); - return webpackEntryPoint; - }); - }); + ); + } + ); } 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; + .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; } - return singularEntry; - }); + ); } return result; } diff --git a/packages/generators/utils/module.ts b/packages/generators/utils/module.ts index 50c4b0deeea..25b846723f1 100644 --- a/packages/generators/utils/module.ts +++ b/packages/generators/utils/module.ts @@ -1,36 +1,36 @@ -interface IModule extends Object { +interface Module extends Object { include: string[]; loader: string; options: { plugins: string[]; - presets: Array>; + presets: Preset[][]; }; test: string; } +type Preset = string | object; + /** * * 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 */ -export default function(): IModule { +export default function(): Module { return { include: ["path.resolve(__dirname, 'src')"], loader: "'babel-loader'", options: { - plugins: [ - "'syntax-dynamic-import'", - ], + plugins: ["'syntax-dynamic-import'"], presets: [ [ "'@babel/preset-env'", { - "'modules'": false, - }, - ], - ], + "'modules'": false + } + ] + ] }, - test: `${new RegExp(/\.js$/)}`, + test: `${new RegExp(/\.js$/)}` }; } diff --git a/packages/generators/utils/plugins.ts b/packages/generators/utils/plugins.ts index f94029dea51..6dedb1fab9e 100644 --- a/packages/generators/utils/plugins.ts +++ b/packages/generators/utils/plugins.ts @@ -6,6 +6,6 @@ * that consists of terser-webpack-plugin */ -export default function(_?: void): string[] { +export default function(): string[] { return ["new TerserPlugin()"]; } diff --git a/packages/generators/utils/tooltip.ts b/packages/generators/utils/tooltip.ts index 27580eee7ad..cd9dba4e7ec 100644 --- a/packages/generators/utils/tooltip.ts +++ b/packages/generators/utils/tooltip.ts @@ -7,7 +7,7 @@ */ export default { - cssPlugin: (_?: void): string => { + cssPlugin: (): string => { return `/* * We've enabled MiniCssExtractPlugin for you. This allows your app to * use css modules that will be moved into a separate CSS file instead of inside @@ -18,7 +18,7 @@ export default { */`; }, - splitChunks: (_?: void): string => { + splitChunks: (): string => { return `/* * SplitChunksPlugin is enabled by default and replaced * deprecated CommonsChunkPlugin. It automatically identifies modules which @@ -33,7 +33,7 @@ export default { */`; }, - postcss: (_?: void): string => { + postcss: (): string => { return `/* * We've enabled Postcss, autoprefixer and precss for you. This allows your app * to lint CSS, support variables and mixins, transpile future CSS syntax, @@ -50,7 +50,7 @@ export default { */`; }, - terser: (_?: void): string => { + terser: (): string => { return `/* * We've enabled TerserPlugin for you! This minifies your app * in order to load faster and run less javascript. @@ -58,5 +58,5 @@ export default { * https://github.com/webpack-contrib/terser-webpack-plugin * */`; - }, + } }; diff --git a/packages/info/.eslintrc b/packages/info/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/info/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/info/__tests__/.eslintrc b/packages/info/__tests__/.eslintrc new file mode 100644 index 00000000000..5d4340a351d --- /dev/null +++ b/packages/info/__tests__/.eslintrc @@ -0,0 +1,7 @@ +{ + "root": true, + "extends": ["../.eslintrc"], + "rules": { + "@typescript-eslint/explicit-function-return-type": ["off"] + } +} diff --git a/packages/info/__tests__/index.test.ts b/packages/info/__tests__/index.test.ts index fca23773708..7ddb1dae791 100644 --- a/packages/info/__tests__/index.test.ts +++ b/packages/info/__tests__/index.test.ts @@ -8,7 +8,7 @@ describe("info", () => { Browsers: ["Chrome", "Firefox", "Safari"], System: ["OS", "CPU"], npmGlobalPackages: ["webpack", "webpack-cli"], - npmPackages: "*webpack*", + npmPackages: "*webpack*" }; expect(returnedInformation).toEqual(expectedInformation); diff --git a/packages/info/index.ts b/packages/info/index.ts index 43db20f6234..68c69c9ddf8 100644 --- a/packages/info/index.ts +++ b/packages/info/index.ts @@ -5,16 +5,18 @@ import * as process from "process"; * Prints debugging information for webpack issue reporting */ -export function information() { +// TODO: define proper interface +// eslint-disable-next-line +export function information(): any { return { Binaries: ["Node", "Yarn", "npm"], Browsers: ["Chrome", "Firefox", "Safari"], System: ["OS", "CPU"], npmGlobalPackages: ["webpack", "webpack-cli"], - npmPackages: "*webpack*", + npmPackages: "*webpack*" }; } -export default async function info() { +export default async function info(): Promise { process.stdout.write(await envinfo.run(information())); } diff --git a/packages/init/.eslintrc b/packages/init/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/init/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/init/init.ts b/packages/init/init.ts index 1b60fe34c7e..b4063cd15e9 100644 --- a/packages/init/init.ts +++ b/packages/init/init.ts @@ -7,9 +7,9 @@ import propTypes from "@webpack-cli/utils/prop-types"; import astTransform from "@webpack-cli/utils/recursive-parser"; import runPrettier from "@webpack-cli/utils/run-prettier"; -import { INode } from "@webpack-cli/utils/types/NodePath"; -import { IError } from "./types"; -import { IConfiguration, IWebpackProperties } from "./types/Transform"; +import { Node } from "@webpack-cli/utils/types/NodePath"; +import { Error } from "./types"; +import { Configuration, WebpackProperties } from "./types/Transform"; /** * @@ -21,9 +21,8 @@ import { IConfiguration, IWebpackProperties } from "./types/Transform"; * @returns {Array} - An array with the transformations to be run */ -const mapOptionsToTransform = (config: IConfiguration): string[] => - Object.keys(config.webpackOptions) - .filter((key: string): boolean => propTypes.has(key)); +const mapOptionsToTransform = (config: Configuration): string[] => + Object.keys(config.webpackOptions).filter((key: string): boolean => propTypes.has(key)); /** * @@ -35,53 +34,56 @@ const mapOptionsToTransform = (config: IConfiguration): string[] => * and writes the file */ -export default function runTransform(webpackProperties: IWebpackProperties, action: string): void { +export default function runTransform(webpackProperties: WebpackProperties, action: string): void { // webpackOptions.name sent to nameTransform if match - const webpackConfig: string[] = - Object - .keys(webpackProperties) - .filter((p: string): boolean => p !== "configFile" && p !== "configPath"); + const webpackConfig: string[] = Object.keys(webpackProperties).filter( + (p: string): boolean => p !== "configFile" && p !== "configPath" + ); const initActionNotDefined = (action && action !== "init") || false; - webpackConfig.forEach((scaffoldPiece: string): Promise => { - const config: IConfiguration = webpackProperties[scaffoldPiece]; - const transformations = mapOptionsToTransform(config); - const ast = j( - initActionNotDefined - ? webpackProperties.configFile - : "module.exports = {}", - ); - const transformAction: string | null = action || null; + webpackConfig.forEach( + (scaffoldPiece: string): Promise => { + const config: Configuration = webpackProperties[scaffoldPiece]; + const transformations = mapOptionsToTransform(config); + const ast = j(initActionNotDefined ? webpackProperties.configFile : "module.exports = {}"); + const transformAction: string | null = action || null; - return pEachSeries(transformations, (f: string): boolean | INode => { - return astTransform(j, ast, config.webpackOptions[f], transformAction, f); - }) - .then((value: string[]): void | PromiseLike => { - let configurationName = "webpack.config.js"; - if (config.configName) { - configurationName = `webpack.${config.configName}.js`; + return pEachSeries( + transformations, + (f: string): boolean | Node => { + return astTransform(j, ast, config.webpackOptions[f], transformAction, f); } + ) + .then( + (): void | PromiseLike => { + let configurationName = "webpack.config.js"; + if (config.configName) { + configurationName = `webpack.${config.configName}.js`; + } - const outputPath = initActionNotDefined - ? webpackProperties.configPath - : path.join(process.cwd(), configurationName); + const outputPath = initActionNotDefined + ? webpackProperties.configPath + : path.join(process.cwd(), configurationName); - const source: string = ast.toSource({ - quote: "single", - }); + const source: string = ast.toSource({ + quote: "single" + }); - runPrettier(outputPath, source); - }) - .catch((err: IError) => { - console.error(err.message ? err.message : err); - }); - }); + 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!`; if (initActionNotDefined && webpackProperties.config.item) { successMessage = `Congratulations! ${webpackProperties.config.item} has been ${action}ed!`; - } process.stdout.write("\n" + chalk.green(`${successMessage}\n`)); } diff --git a/packages/init/package-lock.json b/packages/init/package-lock.json index fede4727f12..1695fbbf370 100644 --- a/packages/init/package-lock.json +++ b/packages/init/package-lock.json @@ -1,6 +1,6 @@ { "name": "@webpack-cli/init", - "version": "0.1.3", + "version": "0.1.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/init/types/Transform.ts b/packages/init/types/Transform.ts index 89622b85f62..d117d93d558 100644 --- a/packages/init/types/Transform.ts +++ b/packages/init/types/Transform.ts @@ -1,14 +1,14 @@ -export interface IWebpackProperties extends Object { +export interface WebpackProperties extends Object { configFile: string; configPath: string; - webpackOptions: IConfiguration; + webpackOptions: Configuration; config: { item: string; configName: string; }; } -export interface IConfiguration extends Object { +export interface Configuration extends Object { configName: string; webpackOptions: object; topScope: string[]; diff --git a/packages/init/types/index.ts b/packages/init/types/index.ts index c0f13602567..9480d6ce9b0 100644 --- a/packages/init/types/index.ts +++ b/packages/init/types/index.ts @@ -1,3 +1,3 @@ -export interface IError { +export interface Error { message?: string; } diff --git a/packages/make/.eslintrc b/packages/make/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/make/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/migrate/.eslintrc b/packages/migrate/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/migrate/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/migrate/__tests__/.eslintrc b/packages/migrate/__tests__/.eslintrc new file mode 100644 index 00000000000..5d4340a351d --- /dev/null +++ b/packages/migrate/__tests__/.eslintrc @@ -0,0 +1,7 @@ +{ + "root": true, + "extends": ["../.eslintrc"], + "rules": { + "@typescript-eslint/explicit-function-return-type": ["off"] + } +} diff --git a/packages/migrate/bannerPlugin/bannerPlugin.ts b/packages/migrate/bannerPlugin/bannerPlugin.ts index 5d369f57ec9..422e1d40dd1 100644 --- a/packages/migrate/bannerPlugin/bannerPlugin.ts +++ b/packages/migrate/bannerPlugin/bannerPlugin.ts @@ -1,6 +1,6 @@ import * as utils from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; /** * @@ -12,24 +12,19 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode): INode { - return utils - .findPluginsByName(j, ast, ["webpack.BannerPlugin"]) - .forEach((path: INode): void => { - const args: INode[] = path.value.arguments; // any node +export default function(j: JSCodeshift, ast: Node): Node { + return utils.findPluginsByName(j, ast, ["webpack.BannerPlugin"]).forEach( + (path: Node): void => { + const args: Node[] = (path.value as Node).arguments; // any node // If the first argument is a literal replace it with object notation // See https://webpack.js.org/guides/migrating/#bannerplugin-breaking-change if (args && args.length > 1 && args[0].type === j.Literal.name) { // and remove the first argument - path.value.arguments = [path.value.arguments[1]]; - utils.createOrUpdatePluginByName( - j, - path.parent, - "webpack.BannerPlugin", - { - banner: args[0].value, - }, - ); + (path.value as Node).arguments = [(path.value as Node).arguments[1]]; + utils.createOrUpdatePluginByName(j, path.parent, "webpack.BannerPlugin", { + banner: args[0].value + }); } - }); + } + ); } diff --git a/packages/migrate/commonsChunkPlugin/commonsChunkPlugin.ts b/packages/migrate/commonsChunkPlugin/commonsChunkPlugin.ts index ea86fb371ba..62bc6a090e2 100644 --- a/packages/migrate/commonsChunkPlugin/commonsChunkPlugin.ts +++ b/packages/migrate/commonsChunkPlugin/commonsChunkPlugin.ts @@ -4,10 +4,47 @@ import { createProperty, findAndRemovePluginByName, findPluginsByName, - findRootNodesByName, + findRootNodesByName } from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; + +// merge test entry prop and function expression. case 6[x] +// TODO: set the proper type once moved to @types/jscodeshift +// eslint-disable-next-line +const mergeTestPropArrowFunction = (j, chunkKey, testFunc): any => { + return j.property( + "init", + createIdentifierOrLiteral(j, "test"), + j.arrowFunctionExpression( + [j.identifier("module")], + j.blockStatement([ + j.ifStatement( + j.callExpression( + j.memberExpression( + j.callExpression(j.memberExpression(j.identifier("module"), j.identifier("getChunks")), []), + j.identifier("some"), + false + ), + [ + j.arrowFunctionExpression( + [j.identifier("chunk")], + j.binaryExpression( + "===", + j.memberExpression(j.identifier("chunk"), j.identifier("name")), + j.literal(chunkKey) + ) + ) + ] + ), + j.returnStatement(j.literal(true)) + ), + j.variableDeclaration("const", [j.variableDeclarator(j.identifier("fn"), testFunc)]), + j.returnStatement(j.callExpression(j.identifier("fn"), [j.identifier("module")])) + ]) + ) + ); +}; /** * @@ -18,20 +55,15 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @param {Node} ast - jscodeshift ast to transform * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode): INode { - const splitChunksProps: INode[] = []; - const cacheGroupsProps: INode[] = []; +export default function(j: JSCodeshift, ast: Node): Node { + const splitChunksProps: Node[] = []; + const cacheGroupsProps: Node[] = []; const optimizationProps: object = {}; - let commonCacheGroupsProps: INode[] = [ - createProperty(j, "chunks", "initial"), - createProperty(j, "enforce", true), - ]; + let commonCacheGroupsProps: Node[] = [createProperty(j, "chunks", "initial"), createProperty(j, "enforce", true)]; // find old options - const CommonsChunkPlugin: INode = findPluginsByName(j, ast, [ - "webpack.optimize.CommonsChunkPlugin", - ]); + const CommonsChunkPlugin: Node = findPluginsByName(j, ast, ["webpack.optimize.CommonsChunkPlugin"]); if (!CommonsChunkPlugin.size()) { return ast; @@ -39,64 +71,66 @@ export default function(j: IJSCodeshift, ast: INode): INode { // cache group options based on keys let cacheGroup: object = {}; - let cacheGroups: INode[] = []; + let cacheGroups: Node[] = []; // iterate each CommonsChunkPlugin instance CommonsChunkPlugin.forEach( - (path: INode): void => { - const CCPProps: INode[] = path.value.arguments[0].properties; + (path: Node): void => { + const CCPProps: Node[] = (path.value as Node).arguments[0].properties; // reset chunks from old props cacheGroup = {}; cacheGroups = []; - commonCacheGroupsProps = [ - createProperty(j, "chunks", "initial"), - createProperty(j, "enforce", true), - ]; + commonCacheGroupsProps = [createProperty(j, "chunks", "initial"), createProperty(j, "enforce", true)]; let chunkKey: string; - let chunkCount: number = 0; + let chunkCount = 0; // iterate CCP props and map SCP props CCPProps.forEach( - (p: INode): void => { + (p: Node): void => { const propKey: string = p.key.name; switch (propKey) { case "names": - p.value.elements.forEach(({ value: chunkValue }): void => { - if (chunkValue === "runtime") { - optimizationProps["runtimeChunk"] = j.objectExpression([ // tslint:disable-line - createProperty(j, "name", chunkValue), - ]); - } else { - if (!Array.isArray(cacheGroup[chunkValue])) { - cacheGroup[chunkValue] = []; - } + (p.value as Node).elements.forEach( + ({ value: chunkValue }): void => { + if (chunkValue === "runtime") { + optimizationProps["runtimeChunk"] = j.objectExpression([ + createProperty(j, "name", chunkValue) + ]); + } else { + if (!Array.isArray(cacheGroup[chunkValue as string])) { + cacheGroup[chunkValue as string] = []; + } - findRootNodesByName(j, ast, "entry").forEach( - ({ value: { value: { properties: entries }} }, - ): void => { - chunkCount = entries.length; - entries.forEach(({ key: { name: entryName }}): void => { - if (entryName === chunkValue) { - cacheGroup[chunkValue].push( - createProperty(j, "test", entryName), + findRootNodesByName(j, ast, "entry").forEach( + ({ value }): void => { + const { properties: entries } = (value as Node).value as Node; + chunkCount = entries.length; + entries.forEach( + ({ key: { name: entryName } }): void => { + if (entryName === chunkValue) { + cacheGroup[chunkValue as string].push( + createProperty(j, "test", entryName) + ); + } + } ); } - }); - }); + ); + } } - }); + ); break; - case "name": - const nameKey = p.value.value; + case "name": { + const nameKey = (p.value as Node).value as string; if (nameKey === "runtime") { - optimizationProps["runtimeChunk"] = j.objectExpression([ // tslint:disable-line - createProperty(j, "name", nameKey), + optimizationProps["runtimeChunk"] = j.objectExpression([ + createProperty(j, "name", nameKey) ]); } else { chunkKey = nameKey; @@ -106,19 +140,21 @@ export default function(j: IJSCodeshift, ast: INode): INode { } findRootNodesByName(j, ast, "entry").forEach( - ({ value: { value: { properties: entries }} }, - ): void => { - chunkCount = entries.length; - entries.forEach(({ key: { name: entryName }}): void => { - if (entryName === nameKey) { - cacheGroup[nameKey].push( - createProperty(j, "test", entryName), - ); - } - }); - }); + ({ value }): void => { + const { properties: entries } = (value as Node).value as Node; + chunkCount = entries.length; + entries.forEach( + ({ key: { name: entryName } }): void => { + if (entryName === nameKey) { + cacheGroup[nameKey].push(createProperty(j, "test", entryName)); + } + } + ); + } + ); } break; + } case "filename": if (chunkKey) { @@ -126,7 +162,7 @@ export default function(j: IJSCodeshift, ast: INode): INode { cacheGroup[chunkKey] = []; } cacheGroup[chunkKey].push( - createProperty(j, propKey, p.value.value), + createProperty(j, propKey, (p.value as Node).value as string) ); } break; @@ -135,9 +171,7 @@ export default function(j: IJSCodeshift, ast: INode): INode { if (!Array.isArray(cacheGroup[chunkKey])) { cacheGroup[chunkKey] = []; } - cacheGroup[chunkKey].push( - createProperty(j, "chunks", "async"), - ); + cacheGroup[chunkKey].push(createProperty(j, "chunks", "async")); break; case "minSize": @@ -145,177 +179,104 @@ export default function(j: IJSCodeshift, ast: INode): INode { cacheGroup[chunkKey] = []; } cacheGroup[chunkKey].push( - j.property("init", createIdentifierOrLiteral(j, propKey), p.value), + j.property("init", createIdentifierOrLiteral(j, propKey), p.value as Node) ); break; - case "minChunks" : - const { value: pathValue }: INode = p; + case "minChunks": { + const { value: pathValue }: Node = p; // minChunk is a function if ( - pathValue.type === "ArrowFunctionExpression" || - pathValue.type === "FunctionExpression" + (pathValue as Node).type === "ArrowFunctionExpression" || + (pathValue as Node).type === "FunctionExpression" ) { if (!Array.isArray(cacheGroup[chunkKey])) { cacheGroup[chunkKey] = []; } - cacheGroup[chunkKey] = cacheGroup[chunkKey].map((prop) => - prop.key.name === "test" ? mergeTestPropArrowFunction(j, chunkKey, pathValue) : prop); + // eslint-disable-next-line + cacheGroup[chunkKey] = cacheGroup[chunkKey].map( + (prop): any => + prop.key.name === "test" + ? mergeTestPropArrowFunction(j, chunkKey, pathValue) + : prop + ); } break; + } } - }, + } ); - Object.keys(cacheGroup).forEach((chunkName: string): void => { - let chunkProps: INode[] = [ - createProperty(j, "name", chunkName), - ]; + Object.keys(cacheGroup).forEach( + (chunkName: string): void => { + let chunkProps: Node[] = [createProperty(j, "name", chunkName)]; - const chunkPropsToAdd = cacheGroup[chunkName]; - const chunkPropsKeys = chunkPropsToAdd.map((prop) => prop.key.name); + const chunkPropsToAdd = cacheGroup[chunkName]; + const chunkPropsKeys = chunkPropsToAdd.map((prop): string => prop.key.name); - commonCacheGroupsProps = - commonCacheGroupsProps.filter((commonProp) => !chunkPropsKeys.includes(commonProp.key.name)); + commonCacheGroupsProps = commonCacheGroupsProps.filter( + (commonProp): boolean => !chunkPropsKeys.includes(commonProp.key.name) + ); - chunkProps.push(...commonCacheGroupsProps); + chunkProps.push(...commonCacheGroupsProps); - if (chunkCount > 1) { - chunkProps.push( - j.property( - "init", - createIdentifierOrLiteral(j, "minChunks"), - createIdentifierOrLiteral(j, chunkCount), - ), + if (chunkCount > 1) { + chunkProps.push( + j.property( + "init", + createIdentifierOrLiteral(j, "minChunks"), + createIdentifierOrLiteral(j, chunkCount) + ) + ); + } + + const chunkPropsContainTest = chunkPropsToAdd.some( + (prop): boolean => prop.key.name === "test" && prop.value.type === "Literal" ); - } - const chunkPropsContainTest = - chunkPropsToAdd.some((prop) => prop.key.name === "test" && prop.value.type === "Literal"); + if (chunkPropsContainTest) { + chunkProps = chunkProps.filter((prop): boolean => prop.key.name !== "minChunks"); + } - if (chunkPropsContainTest) { - chunkProps = chunkProps.filter((prop) => prop.key.name !== "minChunks"); - } + if (chunkPropsToAdd && Array.isArray(chunkPropsToAdd) && chunkPropsToAdd.length > 0) { + chunkProps.push(...chunkPropsToAdd); + } - if ( - chunkPropsToAdd && - Array.isArray(chunkPropsToAdd) && - chunkPropsToAdd.length > 0 - ) { - chunkProps.push(...chunkPropsToAdd); + cacheGroups.push( + j.property("init", createIdentifierOrLiteral(j, chunkName), j.objectExpression([...chunkProps])) + ); } - - cacheGroups.push( - j.property( - "init", - createIdentifierOrLiteral(j, chunkName), - j.objectExpression([...chunkProps]), - ), - ); - }); + ); if (cacheGroups.length > 0) { cacheGroupsProps.push(...cacheGroups); } - }, + } ); // Remove old plugin - const root: INode = findAndRemovePluginByName( - j, - ast, - "webpack.optimize.CommonsChunkPlugin", - ); + const root: Node = findAndRemovePluginByName(j, ast, "webpack.optimize.CommonsChunkPlugin"); - const rootProps: INode[] = [...splitChunksProps]; + const rootProps: Node[] = [...splitChunksProps]; if (cacheGroupsProps.length > 0) { rootProps.push( - j.property( - "init", - createIdentifierOrLiteral(j, "cacheGroups"), - j.objectExpression([...cacheGroupsProps]), - ), + j.property("init", createIdentifierOrLiteral(j, "cacheGroups"), j.objectExpression([...cacheGroupsProps])) ); } // Add new optimizations splitChunks option if (root) { - addOrUpdateConfigObject( - j, - root, - "optimizations", - "splitChunks", - j.objectExpression([...rootProps]), - ); + addOrUpdateConfigObject(j, root, "optimizations", "splitChunks", j.objectExpression([...rootProps])); - Object.keys(optimizationProps).forEach((key: string): void => { - addOrUpdateConfigObject( - j, - root, - "optimizations", - key, - optimizationProps[key], - ); - }); + Object.keys(optimizationProps).forEach( + (key: string): void => { + addOrUpdateConfigObject(j, root, "optimizations", key, optimizationProps[key]); + } + ); } return ast; } - -// merge test entry prop and function expression. case 6[x] -const mergeTestPropArrowFunction = (j, chunkKey, testFunc) => { - return j.property( - "init", - createIdentifierOrLiteral(j, "test"), - j.arrowFunctionExpression( - [j.identifier("module")], - j.blockStatement([ - j.ifStatement( - j.callExpression( - j.memberExpression( - j.callExpression( - j.memberExpression( - j.identifier("module"), - j.identifier("getChunks"), - ), - [], - ), - j.identifier("some"), - false, - ), - [j.arrowFunctionExpression( - [j.identifier("chunk")], - j.binaryExpression( - "===", - j.memberExpression( - j.identifier("chunk"), - j.identifier("name"), - ), - j.literal(chunkKey), - ), - )], - ), - j.returnStatement( - j.literal(true), - ), - ), - j.variableDeclaration( - "const", - [j.variableDeclarator( - j.identifier("fn"), - testFunc, - )], - ), - j.returnStatement( - j.callExpression( - j.identifier("fn"), - [j.identifier("module")], - ), - ), - ]), - ), - ); -}; diff --git a/packages/migrate/extractTextPlugin/extractTextPlugin.ts b/packages/migrate/extractTextPlugin/extractTextPlugin.ts index bf0cf39d937..fcc3931a394 100644 --- a/packages/migrate/extractTextPlugin/extractTextPlugin.ts +++ b/packages/migrate/extractTextPlugin/extractTextPlugin.ts @@ -1,6 +1,6 @@ import * as utils from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; /** * @@ -12,12 +12,12 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @returns {Boolean} isPluginInvocation - whether `node` is the invocation of the plugin denoted by `pluginName` */ -function findInvocation(j: IJSCodeshift, path: INode, pluginName: string): boolean { - let found: boolean = false; +function findInvocation(j: JSCodeshift, path: Node, pluginName: string): boolean { + let found = false; found = j(path) .find(j.MemberExpression) - .filter((p: INode): boolean => p.get("object").value.name === pluginName) + .filter((p: Node): boolean => (p.get("object").value as Node).name === pluginName) .size() > 0; return found; } @@ -31,30 +31,28 @@ function findInvocation(j: IJSCodeshift, path: INode, pluginName: string): boole * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode): void | INode { - const changeArguments = (path: INode): INode => { - const args: INode[] = path.value.arguments; +export default function(j: JSCodeshift, ast: Node): void | Node { + const changeArguments = (path: Node): Node => { + const args: Node[] = (path.value as Node).arguments; - const literalArgs: INode[] = args.filter((p: INode): boolean => utils.isType(p, "Literal")); + const literalArgs: Node[] = args.filter((p: Node): boolean => utils.isType(p, "Literal")); if (literalArgs && literalArgs.length > 1) { const newArgs: object = j.objectExpression( - literalArgs.map((p: INode, index: number): INode => - utils.createProperty(j, index === 0 ? "fallback" : "use", p.value), - ), + literalArgs.map( + (p: Node, index: number): Node => utils.createProperty(j, index === 0 ? "fallback" : "use", p.value as Node) + ) ); - path.value.arguments = [newArgs]; + (path.value as Node).arguments = [newArgs]; } return path; }; - const name: string = utils.findVariableToPlugin( - j, - ast, - "extract-text-webpack-plugin", - ); - if (!name) { return ast; } + const name: string = utils.findVariableToPlugin(j, ast, "extract-text-webpack-plugin"); + if (!name) { + return ast; + } return ast .find(j.CallExpression) - .filter((p: INode): boolean => findInvocation(j, p, name)) + .filter((p: Node): boolean => findInvocation(j, p, name)) .forEach(changeArguments); } diff --git a/packages/migrate/index.ts b/packages/migrate/index.ts index 2a34c453438..09e6bcee346 100644 --- a/packages/migrate/index.ts +++ b/packages/migrate/index.ts @@ -10,19 +10,20 @@ import { validate, WebpackOptionsValidationError } from "webpack"; import runPrettier from "@webpack-cli/utils/run-prettier"; import { transformations } from "./migrate"; -import { IJSCodeshift, INode } from "./types/NodePath"; +import { Node } from "./types/NodePath"; +import jscodeshift from "jscodeshift"; declare var process: { cwd: Function; webpackModule: { validate: Function; - /* tslint:disable */ WebpackOptionsValidationError: { - new: (errors: string[]) => { + new: ( + errors: string[] + ) => { message: string; }; }; - /* tslint:enable */ }; stdout: { write: Function; @@ -30,6 +31,167 @@ declare var process: { exitCode: number; }; +/** + * + * Runs migration on a given configuration using AST's and promises + * to sequentially transform a configuration file. + * + * @param {String} currentConfigPath - input path for config + * @param {String} outputConfigPath - output path for config + * @returns {Promise} Runs the migration using a promise that + * will throw any errors during each transform or output if the + * user decides to abort the migration + */ + +function runMigration(currentConfigPath: string, outputConfigPath: string): Promise | void { + const recastOptions: object = { + quote: "single" + }; + + const tasks: Listr = new Listr([ + { + task: (ctx: Node): string | void | Listr | Promise<{}> => + new pLazy( + ( + resolve: (value?: object) => void, + reject: (reason?: string | object, err?: object) => void + ): void => { + fs.readFile( + currentConfigPath, + "utf8", + (err: object, content: string): void => { + if (err) { + reject(err); + } + try { + ctx.source = content; + ctx.ast = jscodeshift(content); + resolve(); + } catch (err) { + reject("Error generating AST", err); + } + } + ); + } + ), + title: "Reading webpack config" + }, + { + task: (ctx: Node): string | void | Listr | Promise<{}> => { + return new Listr( + Object.keys(transformations).map( + ( + key: string + ): { + task: () => string; + title: string; + } => { + const transform: Function = transformations[key]; + return { + task: (): string => transform(ctx.ast, ctx.source), + title: key + }; + } + ) + ); + }, + title: "Migrating config to newest version" + } + ]); + + tasks + .run() + .then( + (ctx: Node): void | Promise => { + const result: string = ctx.ast.toSource(recastOptions); + const diffOutput: diff.IDiffResult[] = diff.diffLines(ctx.source, result); + + diffOutput.forEach( + (diffLine: diff.IDiffResult): void => { + if (diffLine.added) { + process.stdout.write(chalk.green(`+ ${diffLine.value}`)); + } else if (diffLine.removed) { + process.stdout.write(chalk.red(`- ${diffLine.value}`)); + } + } + ); + + return inquirer + .prompt([ + { + default: "Y", + message: "Are you sure these changes are fine?", + name: "confirmMigration", + type: "confirm" + } + ]) + .then( + (answers: { confirmMigration: boolean }): Promise<{}> => { + if (answers.confirmMigration) { + return inquirer.prompt([ + { + default: "Y", + message: + "Do you want to validate your configuration? " + + "(If you're using webpack merge, validation isn't useful)", + name: "confirmValidation", + type: "confirm" + } + ]); + } else { + console.error(chalk.red("✖ Migration aborted")); + } + } + ) + .then( + (answer: { confirmValidation: boolean }): void => { + if (!answer) { + return; + } + + runPrettier( + outputConfigPath, + result, + (err: object): void => { + if (err) { + throw err; + } + } + ); + + if (answer.confirmValidation) { + const webpackOptionsValidationErrors: string[] = validate(require(outputConfigPath)); + + if (webpackOptionsValidationErrors.length) { + console.error(chalk.red("\n✖ Your configuration validation wasn't successful \n")); + console.error( + new WebpackOptionsValidationError(webpackOptionsValidationErrors).message + ); + } + } + + console.info(chalk.green(`\n✔︎ New webpack config file is at ${outputConfigPath}.`)); + console.info( + chalk.green( + "✔︎ Heads up! Updating to the latest version could contain breaking changes." + ) + ); + + console.info(chalk.green("✔︎ Plugin and loader dependencies may need to be updated.")); + } + ); + } + ) + .catch( + (err: object): void => { + const errMsg = "\n ✖ ︎Migration aborted due to some errors: \n"; + console.error(chalk.red(errMsg)); + console.error(err); + process.exitCode = 1; + } + ); +} + /** * * Runs migration on a given configuration using AST's and promises @@ -62,179 +224,25 @@ export default function migrate(...args: string[]): void | Promise { "Do you want to use your existing webpack " + "configuration?", name: "confirmPath", - type: "confirm", - }, + type: "confirm" + } ]) - .then((ans: { - confirmPath: boolean; - }): void | Promise => { - if (!ans.confirmPath) { - console.error(chalk.red("✖ ︎Migration aborted due no output path")); - return; + .then( + (ans: { confirmPath: boolean }): void | Promise => { + if (!ans.confirmPath) { + console.error(chalk.red("✖ ︎Migration aborted due no output path")); + return; + } + outputConfigPath = path.resolve(process.cwd(), filePaths[0]); + return runMigration(currentConfigPath, outputConfigPath); } - outputConfigPath = path.resolve(process.cwd(), filePaths[0]); - return runMigration(currentConfigPath, outputConfigPath); - }) - .catch((err: object): void => { - console.error(err); - }); + ) + .catch( + (err: object): void => { + console.error(err); + } + ); } outputConfigPath = path.resolve(process.cwd(), filePaths[1]); return runMigration(currentConfigPath, outputConfigPath); } - -/** - * - * Runs migration on a given configuration using AST's and promises - * to sequentially transform a configuration file. - * - * @param {String} currentConfigPath - input path for config - * @param {String} outputConfigPath - output path for config - * @returns {Promise} Runs the migration using a promise that - * will throw any errors during each transform or output if the - * user decides to abort the migration - */ - -function runMigration(currentConfigPath: string, outputConfigPath: string): Promise | void { - const recastOptions: object = { - quote: "single", - }; - - const tasks: Listr = new Listr([ - { - task: (ctx: INode): string | void | Listr | Promise<{}> => - new pLazy(( - resolve: (value?: object) => void, - reject: (reason?: string | object, err?: object) => void, - ) => { - fs.readFile(currentConfigPath, "utf8", (err: object, content: string) => { - if (err) { - reject(err); - } - try { - const jscodeshift: IJSCodeshift = require("jscodeshift"); - ctx.source = content; - ctx.ast = jscodeshift(content); - resolve(); - } catch (err) { - reject("Error generating AST", err); - } - }); - }), - title: "Reading webpack config", - }, - { - task: (ctx: INode): string | void | Listr | Promise => { - return new Listr( - Object.keys(transformations).map((key: string): { - task: (_?: void) => string; - title: string; - } => { - const transform: Function = transformations[key]; - return { - task: (_?: void) => transform(ctx.ast, ctx.source), - title: key, - }; - }), - ); - }, - title: "Migrating config to newest version", - }, - ]); - - tasks - .run() - .then((ctx: INode): void | Promise => { - const result: string = ctx.ast.toSource(recastOptions); - const diffOutput: diff.IDiffResult[] = diff.diffLines(ctx.source, result); - - diffOutput.forEach((diffLine: diff.IDiffResult): void => { - if (diffLine.added) { - process.stdout.write(chalk.green(`+ ${diffLine.value}`)); - } else if (diffLine.removed) { - process.stdout.write(chalk.red(`- ${diffLine.value}`)); - } - }); - - return inquirer - .prompt([ - { - default: "Y", - message: "Are you sure these changes are fine?", - name: "confirmMigration", - type: "confirm", - }, - ]) - .then((answers: { - confirmMigration: boolean; - }): Promise<{}> => { - if (answers.confirmMigration) { - return inquirer.prompt([ - { - default: "Y", - message: - "Do you want to validate your configuration? " + - "(If you're using webpack merge, validation isn't useful)", - name: "confirmValidation", - type: "confirm", - }, - ]); - } else { - console.error(chalk.red("✖ Migration aborted")); - } - }) - .then((answer: { - confirmValidation: boolean; - }): void => { - if (!answer) { return; } - - runPrettier(outputConfigPath, result, (err: object): void => { - if (err) { - throw err; - } - }); - - if (answer.confirmValidation) { - const webpackOptionsValidationErrors: string[] = validate( - require(outputConfigPath), - ); - - if (webpackOptionsValidationErrors.length) { - console.error( - chalk.red( - "\n✖ Your configuration validation wasn't successful \n", - ), - ); - console.error( - new WebpackOptionsValidationError( - webpackOptionsValidationErrors, - ).message, - ); - } - } - - console.info( - chalk.green( - `\n✔︎ New webpack config file is at ${outputConfigPath}.`, - ), - ); - console.info( - chalk.green( - "✔︎ Heads up! Updating to the latest version could contain breaking changes.", - ), - ); - - console.info( - chalk.green( - "✔︎ Plugin and loader dependencies may need to be updated.", - ), - ); - }); - }) - .catch((err: object): void => { - const errMsg = "\n ✖ ︎Migration aborted due to some errors: \n"; - console.error(chalk.red(errMsg)); - console.error(err); - process.exitCode = 1; - }); -} diff --git a/packages/migrate/loaderOptionsPlugin/loaderOptionsPlugin.ts b/packages/migrate/loaderOptionsPlugin/loaderOptionsPlugin.ts index 681ff9579cd..b16a927d46b 100644 --- a/packages/migrate/loaderOptionsPlugin/loaderOptionsPlugin.ts +++ b/packages/migrate/loaderOptionsPlugin/loaderOptionsPlugin.ts @@ -1,14 +1,10 @@ import isEmpty = require("lodash/isEmpty"); -import { - createOrUpdatePluginByName, - findPluginsByName, - safeTraverse, -} from "@webpack-cli/utils/ast-utils"; +import { createOrUpdatePluginByName, findPluginsByName, safeTraverse } from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; -interface ILoaderOptions { +interface LoaderOptions { debug?: boolean; minimize?: boolean; } @@ -23,18 +19,18 @@ interface ILoaderOptions { * */ -export default function(j: IJSCodeshift, ast: INode): INode { - const loaderOptions: ILoaderOptions = {}; +export default function(j: JSCodeshift, ast: Node): Node { + const loaderOptions: LoaderOptions = {}; // If there is debug: true, set debug: true in the plugin if (ast.find(j.Identifier, { name: "debug" }).size()) { loaderOptions.debug = true; - ast - .find(j.Identifier, { name: "debug" }) - .forEach((p: INode): void => { + ast.find(j.Identifier, { name: "debug" }).forEach( + (p: Node): void => { p.parent.prune(); - }); + } + ); } // If there is UglifyJsPlugin, set minimize: true @@ -44,18 +40,12 @@ export default function(j: IJSCodeshift, ast: INode): INode { return ast .find(j.ArrayExpression) - .filter( - (path: INode): boolean => - safeTraverse(path, ["parent", "value", "key", "name"]) === "plugins", - ) - .forEach((path: INode): void => { - if (!isEmpty(loaderOptions)) { - createOrUpdatePluginByName( - j, - path, - "webpack.LoaderOptionsPlugin", - loaderOptions, - ); + .filter((path: Node): boolean => safeTraverse(path, ["parent", "value", "key", "name"]) === "plugins") + .forEach( + (path: Node): void => { + if (!isEmpty(loaderOptions)) { + createOrUpdatePluginByName(j, path, "webpack.LoaderOptionsPlugin", loaderOptions); + } } - }); + ); } diff --git a/packages/migrate/loaders/loaders.ts b/packages/migrate/loaders/loaders.ts index e3b5b920fbb..0f5452c2ac1 100644 --- a/packages/migrate/loaders/loaders.ts +++ b/packages/migrate/loaders/loaders.ts @@ -1,6 +1,6 @@ import * as utils from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; /** * @@ -13,7 +13,7 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode): INode { +export default function(j: JSCodeshift, ast: Node): Node { /** * Creates an Array expression out of loaders string * @@ -54,46 +54,46 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} path - object expression ast with array expression instead of loaders string */ - const createArrayExpressionFromArray = (path: INode): INode => { - const value: INode = path.value; + const createArrayExpressionFromArray = (path: Node): Node => { + const value: Node = (path.value as Node); // Find paths with `loaders` keys in the given Object - const paths: INode[] = value.properties.filter((prop: INode): boolean => - prop.key.name.startsWith("loader"), - ); + const paths: Node[] = value.properties.filter((prop: Node): boolean => prop.key.name.startsWith("loader")); // For each pair of key and value - paths.forEach((pair: INode): void => { - // Replace 'loaders' Identifier with 'use' - pair.key.name = "use"; - // If the value is an Array - if (pair.value.type === j.ArrayExpression.name) { - // replace its elements - const pairValue: INode = pair.value; - pair.value = j.arrayExpression( - pairValue.elements.map((arrElement: INode): INode => { - // 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), - ]); - } - // otherwise keep the existing element - return arrElement; - }), - ); - // If the value is String of loaders like 'style!css' - } else if (pair.value.type === j.Literal.name) { - // Replace it with Array expression of loaders - const literalValue: INode = pair.value; - pair.value = j.arrayExpression( - literalValue.value.split("!").map((loader: string): INode => { - return j.objectExpression([ - utils.createProperty(j, "loader", loader), - ]); - }), - ); + paths.forEach( + (pair: Node): void => { + // Replace 'loaders' Identifier with 'use' + pair.key.name = "use"; + // If the value is an Array + if ((pair.value as Node).type === j.ArrayExpression.name) { + // replace its elements + const pairValue = pair.value as Node; + pair.value = j.arrayExpression( + pairValue.elements.map( + (arrElement: 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))]); + } + // otherwise keep the existing element + return arrElement; + } + ) + ); + // If the value is String of loaders like 'style!css' + } else if ((pair.value as Node).type === j.Literal.name) { + // Replace it with Array expression of loaders + const literalValue = pair.value as Node; + pair.value = j.arrayExpression( + (literalValue.value as string).split("!").map( + (loader: string): Node => { + return j.objectExpression([utils.createProperty(j, "loader", loader)]); + } + ) + ); + } } - }); + ); return path; }; @@ -105,26 +105,24 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} objectExpression - an new object expression ast containing the query parameters */ - const createLoaderWithQuery = (p: INode): INode => { - const properties: INode[] = p.value.properties; + const createLoaderWithQuery = (p: Node): Node => { + const properties: Node[] = (p.value as Node).properties; const loaderValue: string = properties.reduce( - (val: string, prop: INode): string => (prop.key.name === "loader" ? prop.value.value : val), - "", + (val: string, prop: Node): string => (prop.key.name === "loader" ? (prop.value as Node).value as string: val), + "" ); const loader: string = loaderValue.split("?")[0]; const query: string = loaderValue.split("?")[1]; - const options: INode[] = query.split("&").map((option: string): INode => { - const param: string[] = option.split("="); - const key: string = param[0]; - const val: string | boolean = param[1] || true; // No value in query string means it is truthy value - return j.objectProperty(j.identifier(key), utils.createLiteral(j, val)); - }); - const loaderProp: INode = utils.createProperty(j, "loader", loader); - const queryProp: INode = j.property( - "init", - j.identifier("options"), - j.objectExpression(options), + const options: Node[] = query.split("&").map( + (option: string): Node => { + const param: string[] = option.split("="); + const key: string = param[0]; + const val: string | boolean = param[1] || true; // No value in query string means it is truthy value + return j.objectProperty(j.identifier(key), utils.createLiteral(j, val)); + } ); + const loaderProp: Node = utils.createProperty(j, "loader", loader); + const queryProp: Node = j.property("init", j.identifier("options"), j.objectExpression(options)); return j.objectExpression([loaderProp, queryProp]); }; @@ -136,11 +134,10 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Boolean} hasLoaderQueryString - whether the loader object contains a query string */ - const findLoaderWithQueryString = (p: INode): boolean => { - return p.value.properties.reduce((predicate: boolean, prop: INode): boolean => { + 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.value.indexOf("?") > -1) || + (utils.safeTraverse(prop, ["value", "value", "indexOf"]) && ((prop.value as Node).value as string).indexOf("?") > -1) || predicate ); }, false); @@ -155,16 +152,9 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Boolean} isLoadersProp - whether the identifier is the `loaders` prop in the `module` object */ - const checkForLoader = (path: INode): boolean => - path.value.name === "loaders" && - utils.safeTraverse(path, [ - "parent", - "parent", - "parent", - "node", - "key", - "name", - ]) === "module"; + const checkForLoader = (path: Node): boolean => + (path.value as Node).name === "loaders" && + utils.safeTraverse(path, ["parent", "parent", "parent", "node", "key", "name"]) === "module"; /** * Puts pre- or postLoader into `loaders` object and adds the appropriate `enforce` property @@ -173,32 +163,36 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} p - object expression with a `loaders` object and appropriate `enforce` properties */ - const fitIntoLoaders = (p: INode): INode => { - let loaders: INode = null; - p.value.properties.map((prop: INode): void => { - const keyName = prop.key.name; - if (keyName === "loaders") { - loaders = prop.value; + const fitIntoLoaders = (p: Node): Node => { + let loaders: Node = null; + (p.value as Node).properties.map( + (prop: Node): void => { + const keyName = prop.key.name; + if (keyName === "loaders") { + loaders = prop.value as Node; + } } - }); - p.value.properties.map((prop: INode): void => { - const keyName = prop.key.name; - if (keyName !== "loaders") { - const enforceVal: string = keyName === "preLoaders" ? "pre" : "post"; - prop.value.elements.map((elem: INode): void => { - elem.properties.push(utils.createProperty(j, "enforce", enforceVal)); - if (loaders && loaders.type === "ArrayExpression") { - loaders.elements.push(elem); - } else { - prop.key.name = "loaders"; - } - }); + ); + (p.value as Node).properties.map( + (prop: Node): void => { + const keyName = prop.key.name; + if (keyName !== "loaders") { + const enforceVal: string = keyName === "preLoaders" ? "pre" : "post"; + (prop.value as Node).elements.map( + (elem: Node): void => { + elem.properties.push(utils.createProperty(j, "enforce", enforceVal)); + if (loaders && loaders.type === "ArrayExpression") { + loaders.elements.push(elem); + } else { + prop.key.name = "loaders"; + } + } + ); + } } - }); + ); if (loaders) { - p.value.properties = p.value.properties.filter( - (prop: INode): 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; }; @@ -209,10 +203,10 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} ast - jscodeshift ast */ - const prepostLoaders = (_?: void): INode => + const prepostLoaders = (): Node => ast .find(j.ObjectExpression) - .filter((p: INode): boolean => utils.findObjWithOneOfKeys(p, ["preLoaders", "postLoaders"])) + .filter((p: Node): boolean => utils.findObjWithOneOfKeys(p, ["preLoaders", "postLoaders"])) .forEach(fitIntoLoaders); /** @@ -221,11 +215,11 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} ast - jscodeshift ast */ - const loadersToRules = (_?: void): INode => + const loadersToRules = (): Node => ast .find(j.Identifier) .filter(checkForLoader) - .forEach((p: INode): string => (p.value.name = "rules")); + .forEach((p: Node): string => ((p.value as Node).name = "rules")); /** * Convert `loader` and `loaders` to Array of {Rule.Use} @@ -233,19 +227,13 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} ast - jscodeshift ast */ - const loadersToArrayExpression = (_?: void): INode | void => + const loadersToArrayExpression = (): Node | void => ast .find(j.ObjectExpression) - .filter((path: INode): boolean => utils.findObjWithOneOfKeys(path, ["loader", "loaders"])) + .filter((path: Node): boolean => utils.findObjWithOneOfKeys(path, ["loader", "loaders"])) .filter( - (path: INode): boolean => - utils.safeTraverse(path, [ - "parent", - "parent", - "node", - "key", - "name", - ]) === "rules", + (path: Node): boolean => + utils.safeTraverse(path, ["parent", "parent", "node", "key", "name"]) === "rules" ) .forEach(createArrayExpressionFromArray); @@ -271,10 +259,10 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} ast - jscodeshift ast */ - const loaderWithQueryParam = (_?: void): INode => + const loaderWithQueryParam = (): Node => ast .find(j.ObjectExpression) - .filter((p: INode): boolean => utils.findObjWithOneOfKeys(p, ["loader"])) + .filter((p: Node): boolean => utils.findObjWithOneOfKeys(p, ["loader"])) .filter(findLoaderWithQueryString) .replaceWith(createLoaderWithQuery); @@ -295,10 +283,10 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} ast - jscodeshift ast */ - const loaderWithQueryProp = (_?: void): INode => + const loaderWithQueryProp = (): Node => ast .find(j.Identifier) - .filter((p: INode): boolean => p.value.name === "query") + .filter((p: Node): boolean => (p.value as Node).name === "query") .replaceWith(j.identifier("options")); /** @@ -308,18 +296,22 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} ast - jscodeshift ast */ - const addLoaderSuffix = (_?: void): INode => - ast.find(j.ObjectExpression).forEach((path: INode): void => { - path.value.properties.forEach((prop: INode): void => { - if ( - prop.key.name === "loader" && - utils.safeTraverse(prop, ["value", "value"]) && - !prop.value.value.endsWith("-loader") - ) { - prop.value = j.literal(prop.value.value + "-loader"); - } - }); - }); + const addLoaderSuffix = (): Node => + ast.find(j.ObjectExpression).forEach( + (path: Node): void => { + (path.value as Node).properties.forEach( + (prop: Node): void => { + if ( + prop.key.name === "loader" && + 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"); + } + } + ); + } + ); /** * @@ -329,26 +321,28 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} objectExpression - an use object expression ast containing the options and loader */ - const fitOptionsToUse = (p: INode): INode => { - let options: INode = null; - p.value.properties.forEach((prop: INode): void => { - const keyName: string = prop.key.name; - if (keyName === "options") { - options = prop; + const fitOptionsToUse = (p: Node): Node => { + let options: Node = null; + (p.value as Node).properties.forEach( + (prop: Node): void => { + const keyName: string = prop.key.name; + if (keyName === "options") { + options = prop; + } } - }); + ); if (options) { - p.value.properties = p.value.properties.filter( - (prop: INode): 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.properties.forEach((prop: INode): void => { - const keyName = prop.key.name; - if (keyName === "use") { - prop.value.elements[0].properties.push(options); + (p.value as Node).properties.forEach( + (prop: Node): void => { + const keyName = prop.key.name; + if (keyName === "use") { + (prop.value as Node).elements[0].properties.push(options); + } } - }); + ); } return p; @@ -360,10 +354,10 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {Node} ast - jscodeshift ast */ - const moveOptionsToUse = (_?: void): INode => + const moveOptionsToUse = (): Node => ast .find(j.ObjectExpression) - .filter((p: INode): boolean => utils.findObjWithOneOfKeys(p, ["use"])) + .filter((p: Node): boolean => utils.findObjWithOneOfKeys(p, ["use"])) .forEach(fitOptionsToUse); const transforms = [ @@ -373,7 +367,7 @@ export default function(j: IJSCodeshift, ast: INode): INode { loaderWithQueryParam, loaderWithQueryProp, addLoaderSuffix, - moveOptionsToUse, + moveOptionsToUse ]; transforms.forEach((t: Function): void => t()); diff --git a/packages/migrate/migrate.ts b/packages/migrate/migrate.ts index 09baf1b087d..bfed7bee56d 100644 --- a/packages/migrate/migrate.ts +++ b/packages/migrate/migrate.ts @@ -11,13 +11,12 @@ import noEmitOnErrorsPluginTransform from "./noEmitOnErrorsPlugin/noEmitOnErrors import removeDeprecatedPluginsTransform from "./removeDeprecatedPlugins/removeDeprecatedPlugins"; import removeJsonLoaderTransform from "./removeJsonLoader/removeJsonLoader"; import resolveTransform from "./resolve/resolve"; -import { INode } from "./types/NodePath"; import uglifyJsPluginTransform from "./uglifyJsPlugin/uglifyJsPlugin"; -interface ITransformsObject { +interface TransformsObject { bannerPluginTransform: object; commonsChunkPluginTransform?: object; - extractTextPluginTransform: object; /* tslint:disable */ + extractTextPluginTransform: object; loaderOptionsPluginTransform: object; loadersTransform: object; noEmitOnErrorsPluginTransform: object; @@ -27,8 +26,7 @@ interface ITransformsObject { uglifyJsPluginTransform: object; } -/* tslint:disable object-literal-sort-keys */ -const transformsObject: ITransformsObject = { +const transformsObject: TransformsObject = { loadersTransform, resolveTransform, removeJsonLoaderTransform, @@ -38,10 +36,10 @@ const transformsObject: ITransformsObject = { extractTextPluginTransform, noEmitOnErrorsPluginTransform, removeDeprecatedPluginsTransform, - commonsChunkPluginTransform, + commonsChunkPluginTransform }; -interface ILazyTransformObject { +interface LazyTransformObject { loadersTransform?: (ast: object, source: string) => pLazy<{}>; resolveTransform?: (ast: object, source: string) => pLazy<{}>; removeJsonLoaderTransform?: (ast: object, source: string) => pLazy<{}>; @@ -53,16 +51,6 @@ interface ILazyTransformObject { removeDeprecatedPluginsTransform?: (ast: object, source: string) => pLazy<{}>; commonsChunkPluginTransform?: (ast: object, source: string) => pLazy<{}>; } -/* tslint:enable object-literal-sort-keys */ - -export const transformations: ILazyTransformObject = - Object - .keys(transformsObject) - .reduce((res: object, key: string): ILazyTransformObject => { - res[key] = (ast: object, source: string) => - transformSingleAST(ast, source, transformsObject[key]); - return res; - }, {}); /** * @@ -78,23 +66,29 @@ export const transformations: ILazyTransformObject = export const transformSingleAST = ( ast: object, source: string, - transformFunction: (jscodeshift: object, ast: object, source: string) => object) - : pLazy<{}> => { - - return new pLazy(( - resolve: (value?: {} | PromiseLike<{}>) => void, - reject: (reason?: object) => void, - ): void => { - setTimeout((_?: void): void => { - try { - resolve(transformFunction(jscodeshift, ast, source)); - } catch (err) { - reject(err); - } - }, 0); - }); + transformFunction: (jscodeshift: object, ast: object, source: string) => object +): pLazy<{}> => { + return new pLazy( + (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: object) => void): void => { + setTimeout((): void => { + try { + resolve(transformFunction(jscodeshift, ast, source)); + } catch (err) { + reject(err); + } + }, 0); + } + ); }; +export const transformations: LazyTransformObject = Object.keys(transformsObject).reduce( + (res: object, key: string): LazyTransformObject => { + res[key] = (ast: object, source: string): object => transformSingleAST(ast, source, transformsObject[key]); + return res; + }, + {} +); + /** * * Transforms a given piece of source code by applying selected transformations to the AST. @@ -111,24 +105,26 @@ export const transformSingleAST = ( export const transform = ( source: string, transforms?: Iterable>, - options?: object) - : Promise => { - - const ast: INode = jscodeshift(source); + options?: object +): Promise => { + const ast = jscodeshift(source); const recastOptions: object = Object.assign( { - quote: "single", + quote: "single" }, - options, + options ); - transforms = - transforms || Object.keys(transformations).map((k: string): Function => transformations[k]); + transforms = transforms || Object.keys(transformations).map((k: string): Function => transformations[k]); - return pEachSeries(transforms, (f: Function) => f(ast, source)) - .then((value: Function[]): string | PromiseLike => { - return ast.toSource(recastOptions); - }) - .catch((err: object) => { - console.error(err); - }); + return pEachSeries(transforms, (f: Function): void => f(ast, source)) + .then( + (): string | PromiseLike => { + return ast.toSource(recastOptions); + } + ) + .catch( + (err: object): void => { + console.error(err); + } + ); }; diff --git a/packages/migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.ts b/packages/migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.ts index 21750bc8663..658d2c1359f 100644 --- a/packages/migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.ts +++ b/packages/migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.ts @@ -1,9 +1,6 @@ -import { - addOrUpdateConfigObject, - findAndRemovePluginByName, -} from "@webpack-cli/utils/ast-utils"; +import { addOrUpdateConfigObject, findAndRemovePluginByName } from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; /** * @@ -14,23 +11,13 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @param {Node} ast - jscodeshift ast to transform * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode): INode { +export default function(j: JSCodeshift, ast: Node): Node { // Remove old plugin - const root: INode = findAndRemovePluginByName( - j, - ast, - "webpack.optimize.ModuleConcatenationPlugin", - ); + const root: Node = findAndRemovePluginByName(j, ast, "webpack.optimize.ModuleConcatenationPlugin"); // Add new optimizations option if (root) { - addOrUpdateConfigObject( - j, - root, - "optimizations", - "concatenateModules", - j.booleanLiteral(true), - ); + addOrUpdateConfigObject(j, root, "optimizations", "concatenateModules", j.booleanLiteral(true)); } return ast; diff --git a/packages/migrate/namedModulesPlugin/namedModulesPlugin.ts b/packages/migrate/namedModulesPlugin/namedModulesPlugin.ts index 98c7e2ceb9c..34faab3cd4b 100644 --- a/packages/migrate/namedModulesPlugin/namedModulesPlugin.ts +++ b/packages/migrate/namedModulesPlugin/namedModulesPlugin.ts @@ -1,9 +1,6 @@ -import { - addOrUpdateConfigObject, - findAndRemovePluginByName, -} from "@webpack-cli/utils/ast-utils"; +import { addOrUpdateConfigObject, findAndRemovePluginByName } from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; /** * @@ -14,19 +11,13 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @param {Node} ast - jscodeshift ast to transform * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode): INode { +export default function(j: JSCodeshift, ast: Node): Node { // Remove old plugin - const root: INode = findAndRemovePluginByName(j, ast, "webpack.NamedModulesPlugin"); + const root: Node = findAndRemovePluginByName(j, ast, "webpack.NamedModulesPlugin"); // Add new optimizations option if (root) { - addOrUpdateConfigObject( - j, - root, - "optimizations", - "namedModules", - j.booleanLiteral(true), - ); + addOrUpdateConfigObject(j, root, "optimizations", "namedModules", j.booleanLiteral(true)); } return ast; diff --git a/packages/migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.ts b/packages/migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.ts index c45ce923185..567d688a47c 100644 --- a/packages/migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.ts +++ b/packages/migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.ts @@ -1,8 +1,5 @@ -import { - addOrUpdateConfigObject, - findAndRemovePluginByName, -} from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { addOrUpdateConfigObject, findAndRemovePluginByName } from "@webpack-cli/utils/ast-utils"; +import { JSCodeshift, Node } from "../types/NodePath"; /** * @@ -13,23 +10,13 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @param {Node} ast - jscodeshift ast to transform * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode): INode { +export default function(j: JSCodeshift, ast: Node): Node { // Remove old plugin - const root: INode = findAndRemovePluginByName( - j, - ast, - "webpack.NoEmitOnErrorsPlugin", - ); + const root: Node = findAndRemovePluginByName(j, ast, "webpack.NoEmitOnErrorsPlugin"); // Add new optimizations option if (root) { - addOrUpdateConfigObject( - j, - root, - "optimizations", - "noEmitOnErrors", - j.booleanLiteral(true), - ); + addOrUpdateConfigObject(j, root, "optimizations", "noEmitOnErrors", j.booleanLiteral(true)); } return ast; diff --git a/packages/migrate/outputPath/outputPath.ts b/packages/migrate/outputPath/outputPath.ts index 5e88223d808..e3d1c0bd087 100644 --- a/packages/migrate/outputPath/outputPath.ts +++ b/packages/migrate/outputPath/outputPath.ts @@ -1,6 +1,20 @@ import * as utils from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +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], + ); + + return convertedPath; +} /** * @@ -10,18 +24,17 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @param {Node} ast - jscodeshift ast to transform * @returns {Node} ast - jscodeshift ast */ - -export default function(j: IJSCodeshift, ast: INode): INode | void { - const literalOutputPath: INode = ast +export default function(j: JSCodeshift, ast: Node): Node | void { + const literalOutputPath: Node = ast .find(j.ObjectExpression) .filter( - (p: INode): boolean => + (p: Node): boolean => utils.safeTraverse(p, ["parentPath", "value", "key", "name"]) === "output", ) .find(j.Property) .filter( - (p: INode): boolean => + (p: Node): boolean => utils.safeTraverse(p, ["value", "key", "name"]) === "path" && utils.safeTraverse(p, ["value", "value", "type"]) === "Literal", ); @@ -29,18 +42,20 @@ export default function(j: IJSCodeshift, ast: INode): INode | void { if (literalOutputPath) { let pathVarName = "path"; let isPathPresent = false; - const pathDeclaration: INode = ast + const pathDeclaration: Node = ast .find(j.VariableDeclarator) .filter( - (p: INode): boolean => + (p: Node): boolean => utils.safeTraverse(p, ["value", "init", "callee", "name"]) === "require", ) .filter( - (p: INode): boolean => + (p: Node): boolean => utils.safeTraverse(p, ["value", "init", "arguments"]) && - p.value.init.arguments.reduce( - (isPresent: boolean, a: INode): boolean => { + // 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, @@ -50,23 +65,23 @@ export default function(j: IJSCodeshift, ast: INode): INode | void { if (pathDeclaration) { isPathPresent = true; pathDeclaration.forEach( - (p: INode): void => { - pathVarName = utils.safeTraverse(p, ["value", "id", "name"]); + (p: Node): void => { + pathVarName = utils.safeTraverse(p, ["value", "id", "name"]) as string; }, ); } const finalPathName = pathVarName; literalOutputPath .find(j.Literal) - .replaceWith((p: INode): INode => replaceWithPath(j, p, finalPathName)); + .replaceWith((p: Node): Node => replaceWithPath(j, p, finalPathName)); if (!isPathPresent) { - const pathRequire: INode = utils.getRequire(j, "path", "path"); + const pathRequire: Node = utils.getRequire(j, "path", "path"); return ast .find(j.Program) .replaceWith( - (p: INode): INode => - j.program([].concat(pathRequire).concat(p.value.body)), + (p: Node): Node => + j.program([].concat(pathRequire).concat((p.value as Node).body)), ); } } @@ -74,15 +89,3 @@ export default function(j: IJSCodeshift, ast: INode): INode | void { return ast; } -function replaceWithPath( - j: IJSCodeshift, - p: INode, - pathVarName: string, -): INode { - const convertedPath: INode = j.callExpression( - j.memberExpression(j.identifier(pathVarName), j.identifier("join"), false), - [j.identifier("__dirname"), p.value], - ); - - return convertedPath; -} diff --git a/packages/migrate/package-lock.json b/packages/migrate/package-lock.json index 4c6b238c144..c70bc03abc9 100644 --- a/packages/migrate/package-lock.json +++ b/packages/migrate/package-lock.json @@ -1,6 +1,6 @@ { "name": "@webpack-cli/migrate", - "version": "0.1.3", + "version": "0.1.5", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -67,7 +67,7 @@ }, "@types/listr": { "version": "0.13.0", - "resolved": "http://registry.npmjs.org/@types/listr/-/listr-0.13.0.tgz", + "resolved": "https://registry.npmjs.org/@types/listr/-/listr-0.13.0.tgz", "integrity": "sha512-8DOy0JCGwwAf76xmU0sRzSZCWKSPPA9djRcTYTsyqBPnMdGOjZ5tjmNswC4J9mgKZudte2tuTo1l14R1/t5l/g==", "dev": true, "requires": { @@ -100,7 +100,7 @@ }, "@types/rx": { "version": "4.1.1", - "resolved": "http://registry.npmjs.org/@types/rx/-/rx-4.1.1.tgz", + "resolved": "https://registry.npmjs.org/@types/rx/-/rx-4.1.1.tgz", "integrity": "sha1-WY/JSla67ZdfGUV04PVy/Y5iekg=", "dev": true, "requires": { @@ -488,7 +488,7 @@ }, "ansi-escapes": { "version": "3.1.0", - "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" }, "ansi-regex": { @@ -840,7 +840,7 @@ }, "array-equal": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, @@ -991,7 +991,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { "ansi-styles": "^2.2.1", @@ -1011,7 +1011,7 @@ }, "supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } @@ -1245,7 +1245,7 @@ }, "babel-plugin-istanbul": { "version": "4.1.6", - "resolved": "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==", "dev": true, "requires": { @@ -1308,7 +1308,7 @@ }, "babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" }, "babel-plugin-syntax-trailing-function-commas": { @@ -1943,7 +1943,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { @@ -1980,7 +1980,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { @@ -2023,7 +2023,7 @@ }, "buffer": { "version": "4.9.1", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { @@ -2458,7 +2458,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { @@ -2640,7 +2640,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { @@ -2653,7 +2653,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { @@ -2894,7 +2894,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { @@ -3152,7 +3152,7 @@ }, "expand-range": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "requires": { "fill-range": "^2.1.0" @@ -4381,7 +4381,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -4434,7 +4434,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -4504,7 +4504,7 @@ }, "is-generator-fn": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", "dev": true }, @@ -5412,7 +5412,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { "ansi-styles": "^2.2.1", @@ -5441,7 +5441,7 @@ }, "supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } @@ -5551,7 +5551,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { "ansi-styles": "^2.2.1", @@ -5571,7 +5571,7 @@ }, "supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } @@ -5849,7 +5849,7 @@ }, "mute-stream": { "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "resolved": "http://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, "nan": { @@ -6327,7 +6327,7 @@ }, "path-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", "dev": true }, @@ -7151,7 +7151,7 @@ }, "resolve": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true }, @@ -7864,7 +7864,7 @@ }, "sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, @@ -7929,7 +7929,7 @@ }, "stream-browserify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "dev": true, "requires": { @@ -8008,7 +8008,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { @@ -8284,7 +8284,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -8547,7 +8547,7 @@ }, "vm-browserify": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", "dev": true, "requires": { @@ -8715,7 +8715,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -8735,7 +8735,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { diff --git a/packages/migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.ts b/packages/migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.ts index 01030eb7686..e7f7518bdad 100644 --- a/packages/migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.ts +++ b/packages/migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.ts @@ -2,7 +2,7 @@ import chalk from "chalk"; import * as utils from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; /** * @@ -14,37 +14,34 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode) { - // List of deprecated plugins to remove - // each item refers to webpack.optimize.[NAME] construct - const deprecatedPlugingsList: string[] = [ - "webpack.optimize.OccurrenceOrderPlugin", - "webpack.optimize.DedupePlugin", - ]; +export default function(j: JSCodeshift, ast: Node): Node { + // List of deprecated plugins to remove + // each item refers to webpack.optimize.[NAME] construct + const deprecatedPlugingsList: string[] = [ + "webpack.optimize.OccurrenceOrderPlugin", + "webpack.optimize.DedupePlugin" + ]; - return utils.findPluginsByName(j, ast, deprecatedPlugingsList).forEach( - (path: INode): void => { - // For now we only support the case where plugins are defined in an Array - const arrayPath: INode = utils.safeTraverse(path, ["parent", "value"]); + return utils.findPluginsByName(j, ast, deprecatedPlugingsList).forEach( + (path: Node): void => { + // For now we only support the case where plugins are defined in an Array + const arrayPath = utils.safeTraverse(path, ["parent", "value"]) as Node; - if (arrayPath && utils.isType(arrayPath, "ArrayExpression")) { - // Check how many plugins are defined and - // if there is only last plugin left remove `plugins: []` node - const arrayElementsPath: INode[] = utils.safeTraverse(arrayPath, [ - "elements", - ]); - if (arrayElementsPath && arrayElementsPath.length === 1) { - j(path.parent.parent).remove(); - } else { - j(path).remove(); - } - } else { - console.error(` + if (arrayPath && utils.isType(arrayPath, "ArrayExpression")) { + // Check how many plugins are defined and + // if there is only last plugin left remove `plugins: []` node + // + const arrayElementsPath = utils.safeTraverse(arrayPath, ["elements"]) as Node[]; + if (arrayElementsPath && arrayElementsPath.length === 1) { + j(path.parent.parent).remove(); + } else { + j(path).remove(); + } + } else { + console.error(` ${chalk.red("Please remove deprecated plugins manually. ")} -See ${chalk.underline( - "https://webpack.js.org/guides/migrating/", - )} for more information.`); +See ${chalk.underline("https://webpack.js.org/guides/migrating/")} for more information.`); + } } - }, - ); + ); } diff --git a/packages/migrate/removeJsonLoader/removeJsonLoader.ts b/packages/migrate/removeJsonLoader/removeJsonLoader.ts index 88d7a4fae5f..1fcd9c379cb 100644 --- a/packages/migrate/removeJsonLoader/removeJsonLoader.ts +++ b/packages/migrate/removeJsonLoader/removeJsonLoader.ts @@ -1,6 +1,8 @@ import * as utils from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; + +type TransformCallback = (astNode: Node) => void; /** * @@ -11,7 +13,7 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode): INode { +export default function(j: JSCodeshift, ast: Node): Node { /** * * Remove the loader with name `name` from the given NodePath @@ -21,14 +23,16 @@ export default function(j: IJSCodeshift, ast: INode): INode { * @returns {void} */ - function removeLoaderByName(path: INode, name: string): void { - const loadersNode: INode = path.value.value; + function removeLoaderByName(path: Node, name: string): void { + const loadersNode = (path.value as Node).value as Node; switch (loadersNode.type) { case j.ArrayExpression.name: { - const loaders: string[] = loadersNode.elements.map((p: INode): string => { - return utils.safeTraverse(p, ["properties", "0", "value", "value"]); - }); + const loaders: Node[] = loadersNode.elements.map( + (p: Node): Node => { + return utils.safeTraverse(p, ["properties", "0", "value", "value"]) as Node; + } + ); const loaderIndex: number = loaders.indexOf(name); if (loaders.length && loaderIndex > -1) { @@ -55,19 +59,19 @@ export default function(j: IJSCodeshift, ast: INode): INode { } } - function removeLoaders(astNode: INode) { + function removeLoaders(astNode: Node): void { astNode .find(j.Property, { key: { name: "use" } }) - .forEach((path: INode): void => removeLoaderByName(path, "json-loader")); + .forEach((path: Node): void => removeLoaderByName(path, "json-loader")); astNode .find(j.Property, { key: { name: "loader" } }) - .forEach((path: INode): void => removeLoaderByName(path, "json-loader")); + .forEach((path: Node): void => removeLoaderByName(path, "json-loader")); } - const transforms: Array<(astNode: INode) => void> = [removeLoaders]; + const transforms: TransformCallback[] = [removeLoaders]; - transforms.forEach((t: (astNode: INode) => void): void => t(ast)); + transforms.forEach((t: TransformCallback): void => t(ast)); return ast; } diff --git a/packages/migrate/resolve/resolve.ts b/packages/migrate/resolve/resolve.ts index c79f5cca4c3..be60e4e69b0 100644 --- a/packages/migrate/resolve/resolve.ts +++ b/packages/migrate/resolve/resolve.ts @@ -1,4 +1,4 @@ -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; /** * @@ -9,22 +9,19 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @returns {Node} ast - jscodeshift ast */ -export default function transformer(j: IJSCodeshift, ast: INode): INode { - - const getRootVal = (p: INode): INode => { - return p.node.value.properties.filter((prop: INode): boolean => prop.key.name === "root")[0]; +export default function transformer(j: JSCodeshift, ast: Node): Node { + const getRootVal = (p: Node): Node => { + return (p.node.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "root")[0]; }; - const getRootIndex = (p: INode): number => { - return p.node.value.properties.reduce((rootIndex: number, prop: INode, index: number): number => { + const getRootIndex = (p: Node): number => { + return (p.node.value as Node).properties.reduce((rootIndex: number, prop: Node, index: number): number => { return prop.key.name === "root" ? index : rootIndex; }, -1); }; - const isModulePresent = (p: INode): INode | false => { - const modules: INode[] = p.node.value.properties.filter( - (prop: INode): boolean => prop.key.name === "modules", - ); + const isModulePresent = (p: Node): Node | false => { + const modules: Node[] = (p.node.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "modules"); return modules.length > 0 && modules[0]; }; @@ -38,46 +35,42 @@ export default function transformer(j: IJSCodeshift, ast: INode): INode { * @returns {Node} ast - ast node */ - const createModuleArray = (p: INode): INode => { - - const rootVal: INode = getRootVal(p); + const createModuleArray = (p: Node): Node => { + const rootVal: Node = getRootVal(p); - let modulesVal: INode[] = null; + let modulesVal: Node[] = null; - if (rootVal.value.type === "ArrayExpression") { - modulesVal = rootVal.value.elements; + if ((rootVal.value as Node).type === "ArrayExpression") { + modulesVal = (rootVal.value as Node).elements; } else { - modulesVal = [rootVal.value]; + modulesVal = [rootVal.value as Node]; } - let module: INode | false = isModulePresent(p); + let module: Node | false = isModulePresent(p); if (!module) { - module = j.property( - "init", - j.identifier("modules"), - j.arrayExpression(modulesVal), - ); - p.node.value.properties = p.node.value.properties.concat([module]); + module = j.property("init", j.identifier("modules"), j.arrayExpression(modulesVal)); + (p.node.value as Node).properties = (p.node.value as Node).properties.concat([module]); } else { - module.value.elements = module.value.elements.concat(modulesVal); + (module.value as Node).elements = (module.value as Node).elements.concat(modulesVal); } const rootIndex: number = getRootIndex(p); - p.node.value.properties.splice(rootIndex, 1); + (p.node.value as Node).properties.splice(rootIndex, 1); return p; }; return ast .find(j.Property) - .filter((p: INode): boolean => { - return ( - p.node.key.name === "resolve" && - p.node.value.properties.filter((prop: INode): boolean => prop.key.name === "root") - .length === 1 - ); - }) + .filter( + (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 + ); + } + ) .forEach(createModuleArray); } diff --git a/packages/migrate/types/NodePath.ts b/packages/migrate/types/NodePath.ts index e40bdf3cba8..1b828378ddb 100644 --- a/packages/migrate/types/NodePath.ts +++ b/packages/migrate/types/NodePath.ts @@ -1,100 +1,99 @@ -export interface INode extends Object { +export interface Node extends Object { id?: { name: string; }; - arguments?: INode[]; - body?: INode[]; - elements?: INode[]; + arguments?: Node[]; + body?: Node[]; + elements?: Node[]; expression?: { left: { - computed: boolean, - object: INode, - property: INode, - type: string, - }, - operator: string, - right: INode, - type: string, + computed: boolean; + object: Node; + property: Node; + type: string; + }; + operator: string; + right: Node; + type: string; + value?: string; }; - filter?: (p: (p: INode) => boolean) => INode; - find?: (objectExpression: object, filterExpression?: object) => INode; - forEach?: (p: (p: INode) => void) => INode; - get?: (property: string) => INode; - remove?: (_?: void) => void; - nodes?: (_?: void) => INode[]; - pop?: (_?: void) => INode; + filter?: (p: (p: Node) => boolean) => Node; + find?: (objectExpression: object, filterExpression?: object) => Node; + forEach?: (p: (p: Node) => void) => Node; + get?: (property: string) => Node; + remove?: () => void; + nodes?: () => Node[]; + pop?: () => Node; key?: { name: string; - value: INode | string; + value: Node | string; }; - node?: INode; + node?: Node; name?: string; object?: object; - parent?: INode; - properties?: INode[]; - property?: INode; + parent?: Node; + properties?: Node[]; + property?: Node; prune?: Function; - replaceWith?: (objectExpression: object) => INode; - size?: (_?: void) => number; + replaceWith?: (objectExpression: object) => Node; + size?: () => number; type?: string; - value?: INode | string | any; - toSource?: (object: { - quote?: string, - }) => string; + value?: Node | string | Node[]; + toSource?: ( + object: { + quote?: string; + } + ) => string; source?: string; - ast?: INode; - rules?: IModuleRule[]; - __paths?: INode[]; + ast?: Node; + rules?: ModuleRule[]; + + declarations?: Node[]; + + __paths?: Node[]; } -interface IModuleRule { +interface ModuleRule { loader?: string; } -interface IExpressionObject { +interface ExpressionObject { name?: string; } -export interface IJSCodeshift extends Object { - (source?: INode | string): INode; - withParser?: (parser: string) => IJSCodeshift; - identifier?: (key: string) => INode; - literal?: (key: valueType) => INode; - memberExpression?: (node1: INode, node2: INode, bool?: boolean) => INode; - objectProperty?: (key: INode, property: valueType) => INode; - objectExpression?: (properties: INode[]) => INode; - newExpression?: (expression: INode, args: INode[]) => INode; - callExpression?: (expression: INode, args: INode[]) => INode; - variableDeclarator?: (key: INode, args: INode) => INode; - variableDeclaration?: (key: string, args: INode[]) => INode; - arrayExpression?: (args?: INode[]) => INode; - property?: (type: string, key: INode, value: INode) => INode; - program?: (nodes: INode[]) => INode; - booleanLiteral?: (bool: boolean) => INode; - arrowFunctionExpression?: (params: INode[], body: INode, exp: INode) => INode; - blockStatement?: (body: INode[]) => INode; - ifStatement?: (test: INode, consequent: INode, alternate?: INode) => INode; - returnStatement?: (arg: INode) => INode; - binaryExpression?: (operator: string, left: INode, right: INode) => INode; - - Property?: IExpressionObject; - NewExpression?: IExpressionObject; - CallExpression?: IExpressionObject; - VariableDeclarator?: IExpressionObject; - Identifier?: IExpressionObject; - Literal?: IExpressionObject; - ArrayExpression?: IExpressionObject; - MemberExpression?: IExpressionObject; - FunctionExpression?: IExpressionObject; - ObjectExpression?: IExpressionObject; - BlockStatement?: IExpressionObject; - Program?: IExpressionObject; - ArrowFunctionExpression?: IExpressionObject; +export interface JSCodeshift extends Object { + (source?: Node | string): Node; + withParser?: (parser: string) => JSCodeshift; + identifier?: (key: string) => Node; + literal?: (key: valueType) => Node; + memberExpression?: (node1: Node, node2: Node, bool?: boolean) => Node; + objectProperty?: (key: Node, property: valueType) => Node; + objectExpression?: (properties: Node[]) => Node; + newExpression?: (expression: Node, args: Node[]) => Node; + callExpression?: (expression: Node, args: Node[]) => Node; + variableDeclarator?: (key: Node, args: Node) => Node; + variableDeclaration?: (key: string, args: Node[]) => Node; + arrayExpression?: (args?: Node[]) => Node; + property?: (type: string, key: Node, value: Node) => Node; + program?: (nodes: Node[]) => Node; + booleanLiteral?: (bool: boolean) => Node; + Property?: ExpressionObject; + NewExpression?: ExpressionObject; + CallExpression?: ExpressionObject; + VariableDeclarator?: ExpressionObject; + Identifier?: ExpressionObject; + Literal?: ExpressionObject; + ArrayExpression?: ExpressionObject; + MemberExpression?: ExpressionObject; + FunctionExpression?: ExpressionObject; + ObjectExpression?: ExpressionObject; + BlockStatement?: ExpressionObject; + Program?: ExpressionObject; filters?: { VariableDeclarator: { - requiresModule: Function, - }, + requiresModule: Function; + }; }; } -export type valueType = string | number | boolean | any[] | INode | null; +export type valueType = string | number | boolean | Node | null; diff --git a/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts b/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts index ef74dec417f..71980715a60 100644 --- a/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts +++ b/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts @@ -3,10 +3,10 @@ import { findPluginsArrayAndRemoveIfEmpty, findPluginsByName, getRequire, - safeTraverse, + safeTraverse } from "@webpack-cli/utils/ast-utils"; -import { IJSCodeshift, INode } from "../types/NodePath"; +import { JSCodeshift, Node } from "../types/NodePath"; /** * @@ -23,36 +23,33 @@ import { IJSCodeshift, INode } from "../types/NodePath"; * @returns {Node} ast - jscodeshift ast */ -export default function(j: IJSCodeshift, ast: INode): INode { - +export default function(j: JSCodeshift, ast: Node): Node { let pluginVariableAssignment: string = null; - const searchForRequirePlugin: INode = ast + const searchForRequirePlugin: Node = ast .find(j.VariableDeclarator) - .filter( - j.filters.VariableDeclarator.requiresModule("uglifyjs-webpack-plugin"), - ); + .filter(j.filters.VariableDeclarator.requiresModule("uglifyjs-webpack-plugin")); /** * Look for a variable declaration which requires uglifyjs-webpack-plugin * saves the name of this variable. */ - searchForRequirePlugin.forEach((node: INode): void => { - pluginVariableAssignment = node.value.id.name; - }); + searchForRequirePlugin.forEach( + (node: Node): void => { + pluginVariableAssignment = (node.value as Node).id.name; + } + ); - pluginVariableAssignment = !pluginVariableAssignment - ? "webpack.optimize.UglifyJsPlugin" - : pluginVariableAssignment; + pluginVariableAssignment = !pluginVariableAssignment ? "webpack.optimize.UglifyJsPlugin" : pluginVariableAssignment; - findPluginsByName(j, ast, [pluginVariableAssignment]) - .forEach((node: INode): void => { + findPluginsByName(j, ast, [pluginVariableAssignment]).forEach( + (node: Node): void => { let expressionContent: object = null; - const configBody: INode = safeTraverse(node, ["parent", "parent", "parent"]); + const configBody = safeTraverse(node, ["parent", "parent", "parent"]); // options passed to plugin - const pluginOptions: INode[] = node.value.arguments; + const pluginOptions: Node[] = (node.value as Node).arguments; /** * check if there are any options passed to UglifyWebpackPlugin @@ -61,70 +58,55 @@ export default function(j: IJSCodeshift, ast: INode): INode { */ if (pluginOptions.length) { /* - * If user is using UglifyJsPlugin directly from webpack - * transformation must: - * - remove it - * - add require for terser-webpack-plugin - * - add to minimizer - */ + * If user is using UglifyJsPlugin directly from webpack + * transformation must: + * - remove it + * - add require for terser-webpack-plugin + * - add to minimizer + */ if (pluginVariableAssignment) { // remove require for uglify-webpack-plugin searchForRequirePlugin.remove(); // create require for terser-webpack-plugin - const pathRequire: INode = getRequire( - j, - "TerserPlugin", - "terser-webpack-plugin", - ); + const pathRequire: Node = getRequire(j, "TerserPlugin", "terser-webpack-plugin"); // prepend to source code. - ast - .find(j.Program) - .replaceWith((p: INode): INode => - j.program([].concat(pathRequire).concat(p.value.body)), - ); + ast.find(j.Program).replaceWith( + (p: Node): Node => j.program([].concat(pathRequire).concat((p.value as Node).body)) + ); expressionContent = j.property( "init", j.identifier("minimizer"), - j.arrayExpression([ - j.newExpression(j.identifier("TerserPlugin"), [pluginOptions[0]]), - ]), + j.arrayExpression([j.newExpression(j.identifier("TerserPlugin"), [pluginOptions[0]])]) ); } else { - expressionContent = j.property( - "init", - j.identifier("minimizer"), - j.arrayExpression([node.value]), - ); + expressionContent = j.property("init", j.identifier("minimizer"), j.arrayExpression([node.value as Node])); } } else { - searchForRequirePlugin.forEach((n: INode): void => j(n).remove()); + searchForRequirePlugin.forEach((n: Node): void => j(n).remove()); } const minimizeProperty = createProperty(j, "minimize", "true"); // creates optimization property at the body of the config. if (expressionContent) { - configBody.value.properties.push( + ((configBody as Node).value as Node).properties.push( j.property( "init", j.identifier("optimization"), - j.objectExpression([minimizeProperty, expressionContent]), - ), + j.objectExpression([minimizeProperty, expressionContent]) + ) ); } else { - configBody.value.properties.push( - j.property( - "init", - j.identifier("optimization"), - j.objectExpression([minimizeProperty]), - ), + ((configBody as Node).value as Node).properties.push( + j.property("init", j.identifier("optimization"), j.objectExpression([minimizeProperty])) ); } // remove the old Uglify plugin from Plugins array. j(node).remove(); - }); + } + ); findPluginsArrayAndRemoveIfEmpty(j, ast); diff --git a/packages/remove/.eslintrc b/packages/remove/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/remove/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/serve/.eslintrc b/packages/serve/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/serve/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/serve/index.ts b/packages/serve/index.ts index 950ae78d3b7..8ae5a867368 100644 --- a/packages/serve/index.ts +++ b/packages/serve/index.ts @@ -17,7 +17,7 @@ import { List } from "@webpack-cli/webpack-scaffold"; const spawnNPMWithArg = (cmd: string): SpawnSyncReturns => spawn.sync("npm", ["install", "webpack-dev-server", cmd], { - stdio: "inherit", + stdio: "inherit" }); /** @@ -30,7 +30,7 @@ const spawnNPMWithArg = (cmd: string): SpawnSyncReturns => const spawnYarnWithArg = (cmd: string): SpawnSyncReturns => spawn.sync("yarn", ["add", "webpack-dev-server", cmd], { - stdio: "inherit", + stdio: "inherit" }); /** @@ -51,40 +51,34 @@ const getRootPathModule = (dep: string): string => path.resolve(process.cwd(), d * @returns {Function} invokes the devServer API */ -export default function serve(...args: string[]) { +export default function serve(): Promise { const packageJSONPath = getRootPathModule("package.json"); if (!packageJSONPath) { - console.error( - "\n", - chalk.red("✖ Could not find your package.json file"), - "\n", - ); + console.error("\n", chalk.red("✖ Could not find your package.json file"), "\n"); process.exit(1); } + // TODO: to refactor this dynamic require and use import() + // eslint-disable-next-line const packageJSON: object = require(packageJSONPath); /* * We gotta do this, cause some configs might not have devdep, * dep or optional dep, so we'd need sanity checks for each - */ + */ const hasDevServerDep: string[] = packageJSON - ? Object.keys(packageJSON).filter((p: string) => packageJSON[p]["webpack-dev-server"]) + ? Object.keys(packageJSON).filter((p: string): boolean => packageJSON[p]["webpack-dev-server"]) : []; if (hasDevServerDep.length) { - const WDSPath: string = getRootPathModule( - "node_modules/webpack-dev-server/bin/webpack-dev-server.js", - ); + const WDSPath: string = getRootPathModule("node_modules/webpack-dev-server/bin/webpack-dev-server.js"); if (!WDSPath) { console.error( "\n", - chalk.red( - "✖ Could not find the webpack-dev-server dependency in node_modules root path", - ), + chalk.red("✖ Could not find the webpack-dev-server dependency in node_modules root path") ); console.info( chalk.bold.green(" ✔︎"), "Try this command:", - chalk.bold.green("rm -rf node_modules && npm install"), + chalk.bold.green("rm -rf node_modules && npm install") ); process.exit(1); } @@ -92,14 +86,12 @@ export default function serve(...args: string[]) { } else { process.stdout.write( "\n" + - chalk.bold( - "✖ We didn't find any webpack-dev-server dependency in your project,", - ) + + chalk.bold("✖ We didn't find any webpack-dev-server dependency in your project,") + "\n" + chalk.bold.green(" 'webpack serve'") + " " + chalk.bold("requires you to have it installed ") + - "\n\n", + "\n\n" ); return inquirer .prompt([ @@ -107,65 +99,68 @@ export default function serve(...args: string[]) { default: "Y", message: "Do you want to install it? (default: Y)", name: "confirmDevserver", - type: "confirm", - }, + type: "confirm" + } ]) - .then((answer: { - confirmDevserver: boolean, - }) => { - if (answer.confirmDevserver) { - return inquirer - .prompt( - List( - "confirmDepType", - "What kind of dependency do you want it to be under? (default: devDependency)", - ["devDependency", "optionalDependency", "dependency"], - ), - ) - .then((depTypeAns: { - confirmDepType: string; - }) => { - const packager: string = getRootPathModule("package-lock.json") - ? "npm" - : "yarn"; - let spawnAction: (_?: void) => SpawnSyncReturns; - if (depTypeAns.confirmDepType === "devDependency") { - if (packager === "yarn") { - spawnAction = (_?: void) => spawnYarnWithArg("--dev"); - } else { - spawnAction = (_?: void) => spawnNPMWithArg("--save-dev"); - } - } - if (depTypeAns.confirmDepType === "dependency") { - if (packager === "yarn") { - spawnAction = (_?: void) => spawnYarnWithArg(" "); - } else { - spawnAction = (_?: void) => spawnNPMWithArg("--save"); + .then( + (answer: { confirmDevserver: boolean }): Promise => { + if (answer.confirmDevserver) { + return inquirer + .prompt( + List( + "confirmDepType", + "What kind of dependency do you want it to be under? (default: devDependency)", + ["devDependency", "optionalDependency", "dependency"] + ) + ) + .then( + (depTypeAns: { confirmDepType: string }): Promise => { + const packager: string = getRootPathModule("package-lock.json") ? "npm" : "yarn"; + let spawnAction: () => SpawnSyncReturns; + if (depTypeAns.confirmDepType === "devDependency") { + if (packager === "yarn") { + spawnAction = (): SpawnSyncReturns => spawnYarnWithArg("--dev"); + } else { + spawnAction = (): SpawnSyncReturns => spawnNPMWithArg("--save-dev"); + } + } + if (depTypeAns.confirmDepType === "dependency") { + if (packager === "yarn") { + spawnAction = (): SpawnSyncReturns => spawnYarnWithArg(" "); + } else { + spawnAction = (): SpawnSyncReturns => spawnNPMWithArg("--save"); + } + } + if (depTypeAns.confirmDepType === "optionalDependency") { + if (packager === "yarn") { + spawnAction = (): SpawnSyncReturns => + spawnYarnWithArg("--optional"); + } else { + spawnAction = (): SpawnSyncReturns => + spawnNPMWithArg("--save-optional"); + } + } + return processPromise(spawnAction()).then( + (): Promise => { + // Recursion doesn't work well with require call being cached + delete require.cache[require.resolve(packageJSONPath)]; + return serve(); + } + ); } - } - if (depTypeAns.confirmDepType === "optionalDependency") { - if (packager === "yarn") { - spawnAction = (_?: void) => spawnYarnWithArg("--optional"); - } else { - spawnAction = (_?: void) => spawnNPMWithArg("--save-optional"); - } - } - return processPromise(spawnAction()) - .then((_: void) => { - // Recursion doesn't work well with require call being cached - delete require.cache[require.resolve(packageJSONPath)]; - return serve(); - }); - }); - } else { - console.error(chalk.bold.red("✖ Serve aborted due cancelling")); + ); + } else { + console.error(chalk.bold.red("✖ Serve aborted due cancelling")); + process.exitCode = 1; + } + } + ) + .catch( + (err: object): void => { + console.error(chalk.red("✖ Serve aborted due to some errors")); + console.error(err); process.exitCode = 1; } - }) - .catch((err: object) => { - console.error(chalk.red("✖ Serve aborted due to some errors")); - console.error(err); - process.exitCode = 1; - }); + ); } } diff --git a/packages/update/.eslintrc b/packages/update/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/update/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/utils/.eslintrc b/packages/utils/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/utils/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/utils/__tests__/.eslintrc b/packages/utils/__tests__/.eslintrc new file mode 100644 index 00000000000..5d4340a351d --- /dev/null +++ b/packages/utils/__tests__/.eslintrc @@ -0,0 +1,7 @@ +{ + "root": true, + "extends": ["../.eslintrc"], + "rules": { + "@typescript-eslint/explicit-function-return-type": ["off"] + } +} diff --git a/packages/utils/__tests__/ast-utils.test.ts b/packages/utils/__tests__/ast-utils.test.ts index b9c8e34576c..6883531049f 100644 --- a/packages/utils/__tests__/ast-utils.test.ts +++ b/packages/utils/__tests__/ast-utils.test.ts @@ -2,7 +2,7 @@ import * as j from "jscodeshift/dist/core"; import * as utils from "../ast-utils"; -import { INode } from "../types/NodePath"; +import { Node } from "../types/NodePath"; describe("utils", () => { describe("createProperty", () => { @@ -106,7 +106,7 @@ const a = { plugs: [] } describe("createOrUpdatePluginByName", () => { it("should create a new plugin without arguments", () => { const ast = j("{ plugins: [] }"); - ast.find(j.ArrayExpression).forEach((node: INode) => { + ast.find(j.ArrayExpression).forEach((node: Node) => { utils.createOrUpdatePluginByName(j, node, "Plugin"); }); expect(ast.toSource()).toMatchSnapshot(); @@ -114,9 +114,9 @@ const a = { plugs: [] } it("should create a new plugin with arguments", () => { const ast = j("{ plugins: [] }"); - ast.find(j.ArrayExpression).forEach((node: INode) => { + ast.find(j.ArrayExpression).forEach((node: Node) => { utils.createOrUpdatePluginByName(j, node, "Plugin", { - foo: "bar", + foo: "bar" }); }); expect(ast.toSource()).toMatchSnapshot(); @@ -124,9 +124,9 @@ const a = { plugs: [] } it("should add an object as an argument", () => { const ast = j("[new Plugin()]"); - ast.find(j.ArrayExpression).forEach((node: INode) => { + ast.find(j.ArrayExpression).forEach((node: Node) => { utils.createOrUpdatePluginByName(j, node, "Plugin", { - foo: true, + foo: true }); }); expect(ast.toSource()).toMatchSnapshot(); @@ -134,13 +134,13 @@ const a = { plugs: [] } it("should merge options objects", () => { const ast = j("[new Plugin({ foo: true })]"); - ast.find(j.ArrayExpression).forEach((node: INode) => { + ast.find(j.ArrayExpression).forEach((node: Node) => { utils.createOrUpdatePluginByName(j, node, "Plugin", { bar: "baz", - foo: false, + foo: false }); utils.createOrUpdatePluginByName(j, node, "Plugin", { - "baz-long": true, + "baz-long": true }); }); expect(ast.toSource()).toMatchSnapshot(); @@ -192,8 +192,8 @@ const a = { plugs: [] } expect( ast .find(j.ObjectExpression) - .filter((p) => utils.findObjWithOneOfKeys(p, ["a"])) - .size(), + .filter(p => utils.findObjWithOneOfKeys(p, ["a"])) + .size() ).toEqual(1); }); }); @@ -208,12 +208,12 @@ const a = { plugs: [] } describe("safeTraverse", () => { it("should safe traverse", () => { const testObject = { - type: "NodeType", + type: "NodeType" }; const p = { foo: { - bar: testObject, - }, + bar: testObject + } }; const require = utils.safeTraverse(p, ["foo", "bar"]); expect(require).toEqual(testObject); @@ -221,14 +221,14 @@ const a = { plugs: [] } it("should safe traverse thrice", () => { const type = { - type: "NodeType", + type: "NodeType" }; const p = { parent: { value: { - value: type, - }, - }, + value: type + } + } }; const traversedValue = utils.safeTraverse(p, ["parent", "value", "value"]); expect(traversedValue).toEqual(type); @@ -241,9 +241,9 @@ const a = { plugs: [] } const p = { value: { value: { - type: NODE_TYPE, - }, - }, + type: NODE_TYPE + } + } }; const typeValue = utils.safeTraverseAndGetType(p); expect(typeValue).toEqual(NODE_TYPE); @@ -254,9 +254,9 @@ const a = { plugs: [] } const p = { foo: { bar: { - type: NODE_TYPE, - }, - }, + type: NODE_TYPE + } + } }; const typeValue = utils.safeTraverseAndGetType(p); expect(typeValue).toEqual(false); @@ -273,14 +273,14 @@ const a = { plugs: [] } super: [ "yeah", { - loader: "'eslint-loader'", - }, - ], + loader: "'eslint-loader'" + } + ] }; const root = ast.find(j.ObjectExpression); - root.forEach((p) => { + root.forEach(p => { utils.addProperty(j, p, "entry", propertyValue); }); @@ -306,14 +306,14 @@ const a = { plugs: [] } super: [ "yeah", { - loader: "'eslint-loader'", - }, - ], + loader: "'eslint-loader'" + } + ] }; const root = ast.find(j.ObjectExpression); - utils.findRootNodesByName(j, root, "entry").forEach((p: INode) => { + utils.findRootNodesByName(j, root, "entry").forEach((p: Node) => { j(p).replaceWith(utils.addProperty(j, p, "entry", propertyValue, "add")); }); diff --git a/packages/utils/__tests__/package-manager.test.ts b/packages/utils/__tests__/package-manager.test.ts index 036f10604bb..baa4204822a 100644 --- a/packages/utils/__tests__/package-manager.test.ts +++ b/packages/utils/__tests__/package-manager.test.ts @@ -7,7 +7,9 @@ jest.mock("cross-spawn"); jest.mock("fs"); describe("package-manager", () => { + // eslint-disable-next-line const spawn = require("cross-spawn"); + // eslint-disable-next-line const fs = require("fs"); const defaultSyncResult = { @@ -50,7 +52,7 @@ describe("package-manager", () => { fs.existsSync.mockReturnValueOnce(true); } - spawn.sync.mockReturnValue(defaultSyncResult); + jest.spyOn(spawn, "sync").mockReturnValue(defaultSyncResult); it("should return 'yarn' from getPackageManager if it's installed", () => { expect(packageManager.getPackageManager()).toEqual("yarn"); diff --git a/packages/utils/__tests__/resolve-packages.test.ts b/packages/utils/__tests__/resolve-packages.test.ts index d571dc01762..765b907f1d2 100644 --- a/packages/utils/__tests__/resolve-packages.test.ts +++ b/packages/utils/__tests__/resolve-packages.test.ts @@ -7,7 +7,7 @@ function mockPromise(value) { const mockedPromise = { then(callback) { return mockPromise(callback(value)); - }, + } }; return isValueAPromise ? value : mockedPromise; @@ -18,14 +18,14 @@ function spawnChild(pkg) { function getLoc(option) { const packageModule = []; - option.filter((pkg) => { - mockPromise(spawnChild(pkg)).then((_) => { + option.filter(pkg => { + mockPromise(spawnChild(pkg)).then(() => { try { const loc = path.join("..", "..", "node_modules", pkg); packageModule.push(loc); } catch (err) { throw new Error( - "Package wasn't validated correctly.." + "Submit an issue for " + pkg + " if this persists", + "Package wasn't validated correctly.." + "Submit an issue for " + pkg + " if this persists" ); } }); @@ -60,7 +60,7 @@ describe("resolve-packages", () => { moduleLoc = getLoc(["webpack-scaffold-ylvis", "webpack-scaffold-noop"]); expect(moduleLoc).toEqual([ path.normalize("../../node_modules/webpack-scaffold-ylvis"), - path.normalize("../../node_modules/webpack-scaffold-noop"), + path.normalize("../../node_modules/webpack-scaffold-noop") ]); }); }); diff --git a/packages/utils/ast-utils.ts b/packages/utils/ast-utils.ts index 53e2e60e685..7a6fed5a657 100644 --- a/packages/utils/ast-utils.ts +++ b/packages/utils/ast-utils.ts @@ -1,4 +1,4 @@ -import { IJSCodeshift, INode, valueType } from "./types/NodePath"; +import { JSCodeshift, Node, valueType } from "./types/NodePath"; import * as validateIdentifier from "./validate-identifier"; /** @@ -6,11 +6,13 @@ import * as validateIdentifier from "./validate-identifier"; * Traverse safely over a path object for array for paths * @param {Object} obj - Object on which we traverse * @param {Array} paths - Array of strings containing the traversal path - * @returns {Any} Value at given traversal path + * @returns {Node} Value at given traversal path */ -function safeTraverse(obj: INode, paths: string[]): any { - let val: INode = obj; +function safeTraverse(obj: Node, paths: string[]): Node | Node[] { + // TODO: to revisit the type of this function, it's not clear what should return. + // Sometimes its return type is used as string + let val: Node = obj; let idx = 0; while (idx < paths.length) { @@ -30,8 +32,8 @@ function safeTraverse(obj: INode, paths: string[]): any { * @returns {String|Boolean} type at given path. */ -function safeTraverseAndGetType(path: INode): string | boolean { - const pathValue: INode = safeTraverse(path, ["value", "value"]); +function safeTraverseAndGetType(path: Node): string | boolean { + const pathValue = safeTraverse(path, ["value", "value"]) as Node; return pathValue ? pathValue.type : false; } @@ -41,17 +43,15 @@ function safeTraverseAndGetType(path: INode): string | boolean { * @returns {String} member expression string. */ -function memberExpressionToPathString(path: INode): string { +function memberExpressionToPathString(path: Node): string { if (path && path.object) { - return [memberExpressionToPathString(path.object), path.property.name].join( - ".", - ); + return [memberExpressionToPathString(path.object), path.property.name].join("."); } return path.name; } // Convert Array like ['webpack', 'optimize', 'DedupePlugin'] to nested MemberExpressions -function pathsToMemberExpression(j: IJSCodeshift, paths: string[]): INode { +function pathsToMemberExpression(j: JSCodeshift, paths: string[]): Node { if (!paths.length) { return null; } else if (paths.length === 1) { @@ -59,10 +59,7 @@ function pathsToMemberExpression(j: IJSCodeshift, paths: string[]): INode { } else { const first: string[] = paths.slice(0, 1); const rest: string[] = paths.slice(1); - return j.memberExpression( - pathsToMemberExpression(j, rest), - pathsToMemberExpression(j, first), - ); + return j.memberExpression(pathsToMemberExpression(j, rest), pathsToMemberExpression(j, first)); } } @@ -77,15 +74,14 @@ function pathsToMemberExpression(j: IJSCodeshift, paths: string[]): INode { * @returns {Node} Node that has the pluginName */ -function findPluginsByName(j: IJSCodeshift, node: INode, pluginNamesArray: string[]): INode { - return node - .find(j.NewExpression) - .filter((path: INode): boolean => { +function findPluginsByName(j: JSCodeshift, node: Node, pluginNamesArray: string[]): Node { + return node.find(j.NewExpression).filter( + (path: Node): boolean => { return pluginNamesArray.some( - (plugin: string) => - memberExpressionToPathString(path.get("callee").value) === plugin, + (plugin: string): boolean => memberExpressionToPathString(path.get("callee").value as Node) === plugin ); - }); + } + ); } /** @@ -95,20 +91,15 @@ function findPluginsByName(j: IJSCodeshift, node: INode, pluginNamesArray: strin * @returns {Node} rootNode modified AST. */ -function findPluginsArrayAndRemoveIfEmpty(j: IJSCodeshift, rootNode: INode): INode { - return rootNode - .find(j.Identifier, { name: "plugins" }) - .forEach((node: INode) => { - const elements: INode[] = safeTraverse(node, [ - "parent", - "value", - "value", - "elements", - ]); +function findPluginsArrayAndRemoveIfEmpty(j: JSCodeshift, rootNode: Node): Node { + return rootNode.find(j.Identifier, { name: "plugins" }).forEach( + (node: Node): void => { + const elements = safeTraverse(node, ["parent", "value", "value", "elements"]) as Node[]; if (!elements.length) { j(node.parent).remove(); } - }); + } + ); } /** @@ -121,51 +112,10 @@ function findPluginsArrayAndRemoveIfEmpty(j: IJSCodeshift, rootNode: INode): INo * @returns {Node} found node and */ -function findRootNodesByName(j: IJSCodeshift, node: INode, propName: string): INode { +function findRootNodesByName(j: JSCodeshift, node: Node, propName: string): Node { return node.find(j.Property, { key: { name: propName } }); } -/** - * - * Creates an Object's property with a given key and value - * - * @param {any} j — jscodeshift API - * @param {String | Number} key - Property key - * @param {String | Number | Boolean} value - Property value - * @returns {Node} - */ - -function createProperty(j: IJSCodeshift, key: string | number, value: valueType): INode { - return j.property( - "init", - createIdentifierOrLiteral(j, key), - createLiteral(j, value), - ); -} - -/** - * - * Creates an appropriate literal property - * - * @param {any} j — jscodeshift API - * @param {String | Boolean | Number} val - * @returns {Node} - */ - -function createLiteral(j: IJSCodeshift, val: valueType): INode { - let literalVal: valueType = val; - // We'll need String to native type conversions - if (typeof val === "string") { - // 'true' => true - if (val === "true") { literalVal = true; } - // 'false' => false - if (val === "false") { literalVal = false; } - // '1' => 1 - if (!isNaN(Number(val))) { literalVal = Number(val); } - } - return j.literal(literalVal); -} - /** * * Creates an appropriate identifier or literal property @@ -175,12 +125,12 @@ function createLiteral(j: IJSCodeshift, val: valueType): INode { * @returns {Node} */ -function createIdentifierOrLiteral(j: IJSCodeshift, val: valueType): INode { +function createIdentifierOrLiteral(j: JSCodeshift, val: valueType): Node { // IPath | IPath doesn't work, find another way let literalVal = val; // We'll need String to native type conversions if (!Array.isArray(val)) { - if (typeof val === "string" || typeof val === "object" && val.__paths) { + if (typeof val === "string" || (typeof val === "object" && val.__paths)) { // 'true' => true if (val === "true") { literalVal = true; @@ -197,7 +147,7 @@ function createIdentifierOrLiteral(j: IJSCodeshift, val: valueType): INode { return j.literal(literalVal); } if (typeof val === "object" && val.__paths) { - const regExpVal = val.__paths[0].value.program.body[0].expression; + const regExpVal = ((val.__paths[0].value as JSCodeshift).program as Node).body[0].expression; return j.literal(regExpVal.value); } else if (typeof literalVal === "string") { // Use identifier instead @@ -214,6 +164,49 @@ function createIdentifierOrLiteral(j: IJSCodeshift, val: valueType): INode { return j.literal(literalVal); } +/** + * + * Creates an appropriate literal property + * + * @param {any} j — jscodeshift API + * @param {String | Boolean | Number} val + * @returns {Node} + */ + +function createLiteral(j: JSCodeshift, val: valueType): Node { + let literalVal: valueType = val; + // We'll need String to native type conversions + if (typeof val === "string") { + // 'true' => true + if (val === "true") { + literalVal = true; + } + // 'false' => false + if (val === "false") { + literalVal = false; + } + // '1' => 1 + if (!isNaN(Number(val))) { + literalVal = Number(val); + } + } + return j.literal(literalVal); +} + +/** + * + * Creates an Object's property with a given key and value + * + * @param {any} j — jscodeshift API + * @param {String | Number} key - Property key + * @param {String | Number | Boolean} value - Property value + * @returns {Node} + */ + +function createProperty(j: JSCodeshift, key: string | number, value: valueType): Node { + return j.property("init", createIdentifierOrLiteral(j, key), createLiteral(j, value)); +} + /** * * Adds or updates the value of a key within a root @@ -228,35 +221,32 @@ function createIdentifierOrLiteral(j: IJSCodeshift, val: valueType): INode { */ function addOrUpdateConfigObject( - j: IJSCodeshift, rootNode: INode, configProperty: string, key: string, value: valueType, + j: JSCodeshift, + rootNode: Node, + configProperty: string, + key: string, + value: valueType ): void { - - const propertyExists = rootNode.properties.filter( - (node: INode): boolean => node.key.name === configProperty, - ).length; + const propertyExists = rootNode.properties.filter((node: Node): boolean => node.key.name === configProperty).length; if (propertyExists) { rootNode.properties - .filter((path: INode): boolean => path.key.name === configProperty) - .forEach((path: INode) => { - const newProperties = path.value.properties.filter( - (p: INode) => p.key.name !== key, - ); - newProperties.push( - j.objectProperty( - j.identifier(key), value, - ), - ); - path.value.properties = newProperties; - }); + .filter((path: Node): boolean => path.key.name === configProperty) + .forEach( + (path: Node): void => { + const newProperties = (path.value as Node).properties.filter( + (p: Node): boolean => p.key.name !== key + ); + newProperties.push(j.objectProperty(j.identifier(key), value)); + (path.value as Node).properties = newProperties; + } + ); } else { rootNode.properties.push( j.objectProperty( j.identifier(configProperty), - j.objectExpression( - [j.objectProperty(j.identifier(key), value)], - ), - ), + j.objectExpression([j.objectProperty(j.identifier(key), value)]) + ) ); } } @@ -272,20 +262,22 @@ function addOrUpdateConfigObject( * @returns {Node | Void} - path to the root webpack configuration object if plugin is found */ -function findAndRemovePluginByName(j: IJSCodeshift, node: INode, pluginName: string): INode { - let rootPath: INode; +function findAndRemovePluginByName(j: JSCodeshift, node: Node, pluginName: string): Node { + let rootPath: Node; findPluginsByName(j, node, [pluginName]) - .filter((path: INode): boolean => safeTraverse(path, ["parent", "value"])) - .forEach((path: INode) => { - rootPath = safeTraverse(path, ["parent", "parent", "parent", "value"]); - const arrayPath: INode = path.parent.value; - if (arrayPath.elements && arrayPath.elements.length === 1) { - j(path.parent.parent).remove(); - } else { - j(path).remove(); + .filter((path: Node): boolean => !!safeTraverse(path, ["parent", "value"])) + .forEach( + (path: Node): void => { + rootPath = safeTraverse(path, ["parent", "parent", "parent", "value"]) as Node; + const arrayPath = path.parent.value as Node; + if (arrayPath.elements && arrayPath.elements.length === 1) { + j(path.parent.parent).remove(); + } else { + j(path).remove(); + } } - }); + ); return rootPath; } @@ -303,62 +295,68 @@ function findAndRemovePluginByName(j: IJSCodeshift, node: INode, pluginName: str * @returns {Void} */ -function createOrUpdatePluginByName(j: IJSCodeshift, rootNodePath: INode, pluginName: string, options?: object): void { - const pluginInstancePath: INode = findPluginsByName(j, j(rootNodePath), [ - pluginName, - ]); - let optionsProps: INode[]; +function createOrUpdatePluginByName(j: JSCodeshift, rootNodePath: Node, pluginName: string, options?: object): void { + const pluginInstancePath: Node = findPluginsByName(j, j(rootNodePath), [pluginName]); + let optionsProps: Node[]; if (options) { - optionsProps = Object.keys(options).map((key: string) => { - return createProperty(j, key, options[key]); - }); + optionsProps = Object.keys(options).map( + (key: string): Node => { + return createProperty(j, key, options[key]); + } + ); } // If plugin declaration already exist if (pluginInstancePath.size()) { - pluginInstancePath.forEach((path: INode) => { - // There are options we want to pass as argument - if (optionsProps) { - const args: INode[] = path.value.arguments; - if (args.length) { - // Plugin is called with object as arguments - // we will merge those objects - const currentProps: INode = j(path) - .find(j.ObjectExpression) - .get("properties"); - - optionsProps.forEach((opt: INode) => { - // Search for same keys in the existing object - const existingProps = j(currentProps) - .find(j.Identifier) - .filter((p: INode): boolean => opt.key.value === p.value.name); - - if (existingProps.size()) { - // Replacing values for the same key - existingProps.forEach((p: INode) => { - j(p.parent).replaceWith(opt); - }); - } else { - // Adding new key:values - currentProps.value.push(opt); - } - }); - } else { - // Plugin is called without arguments - args.push(j.objectExpression(optionsProps)); + pluginInstancePath.forEach( + (path: Node): void => { + // There are options we want to pass as argument + if (optionsProps) { + const args: Node[] = (path.value as Node).arguments; + if (args.length) { + // Plugin is called with object as arguments + // we will merge those objects + const currentProps: Node = j(path) + .find(j.ObjectExpression) + .get("properties"); + + optionsProps.forEach( + (opt: Node): void => { + // Search for same keys in the existing object + const existingProps = j(currentProps) + .find(j.Identifier) + .filter((p: Node): boolean => opt.key.value === (p.value as Node).name); + + if (existingProps.size()) { + // Replacing values for the same key + existingProps.forEach( + (p: Node): void => { + j(p.parent).replaceWith(opt); + } + ); + } else { + // Adding new key:values + (currentProps.value as Node[]).push(opt); + } + } + ); + } else { + // Plugin is called without arguments + args.push(j.objectExpression(optionsProps)); + } } } - }); + ); } else { - let argumentsArray: INode[] = []; + let argumentsArray: Node[] = []; if (optionsProps) { argumentsArray = [j.objectExpression(optionsProps)]; } const loaderPluginInstance = j.newExpression( pathsToMemberExpression(j, pluginName.split(".").reverse()), - argumentsArray, + argumentsArray ); - rootNodePath.value.elements.push(loaderPluginInstance); + (rootNodePath.value as Node).elements.push(loaderPluginInstance); } } @@ -373,12 +371,14 @@ function createOrUpdatePluginByName(j: IJSCodeshift, rootNodePath: INode, plugin * @returns {String} variable name - ex. 'const s = require(s) gives "s"` */ -function findVariableToPlugin(j: IJSCodeshift, rootNode: INode, pluginPackageName: string): string { - const moduleVarNames: INode[] = rootNode +function findVariableToPlugin(j: JSCodeshift, rootNode: Node, pluginPackageName: string): string { + const moduleVarNames: Node[] = rootNode .find(j.VariableDeclarator) .filter(j.filters.VariableDeclarator.requiresModule(pluginPackageName)) .nodes(); - if (moduleVarNames.length === 0) { return null; } + if (moduleVarNames.length === 0) { + return null; + } return moduleVarNames.pop().id.name; } @@ -390,12 +390,12 @@ function findVariableToPlugin(j: IJSCodeshift, rootNode: INode, pluginPackageNam * @returns {Boolean} */ -function isType(path: INode, type: string): boolean { +function isType(path: Node, type: string): boolean { return path.type === type; } -function findObjWithOneOfKeys(p: INode, keyNames: string[]) { - return p.value.properties.reduce((predicate: boolean, prop: INode) => { +function findObjWithOneOfKeys(p: Node, keyNames: string[]): boolean { + return (p.value as Node).properties.reduce((predicate: boolean, prop: Node): boolean => { const name: string = prop.key.name; return keyNames.indexOf(name) > -1 || predicate; }, false); @@ -410,12 +410,12 @@ function findObjWithOneOfKeys(p: INode, keyNames: string[]) { * @returns {Node} - the created ast */ -function getRequire(j: IJSCodeshift, constName: string, packagePath: string): INode { +function getRequire(j: JSCodeshift, constName: string, packagePath: string): Node { return j.variableDeclaration("const", [ j.variableDeclarator( j.identifier(constName), - j.callExpression(j.identifier("require"), [j.literal(packagePath)]), - ), + j.callExpression(j.identifier("require"), [j.literal(packagePath)]) + ) ]); } @@ -430,32 +430,33 @@ function getRequire(j: IJSCodeshift, constName: string, packagePath: string): IN * @returns {Node} - the created ast */ -function addProperty(j: IJSCodeshift, p: INode, key: string, value: valueType, action?: string): INode { +function addProperty(j: JSCodeshift, p: Node, key: string, value: valueType, action?: string): Node { if (!p) { return; } let valForNode: valueType; if (Array.isArray(value)) { - let arrExp: INode = j.arrayExpression([]); + let arrExp: Node = j.arrayExpression([]); if (safeTraverseAndGetType(p) === "ArrayExpression") { - arrExp = p.value.value; + arrExp = (p.value as Node).value as Node; } - value.forEach((val: valueType) => { - addProperty(j, arrExp, null, val); - }); + value.forEach( + (val: valueType): void => { + addProperty(j, arrExp, null, val); + } + ); valForNode = arrExp; - } else if ( - typeof value === "object" && - !(value.__paths || value instanceof RegExp) - ) { - let objectExp: INode = j.objectExpression([]); + } else if (typeof value === "object" && !(value.__paths || value instanceof RegExp)) { + let objectExp: Node = j.objectExpression([]); if (safeTraverseAndGetType(p) === "ObjectExpression") { - objectExp = p.value.value; + objectExp = (p.value as Node).value as Node; } // object -> loop through it - Object.keys(value).forEach((prop: string) => { - addProperty(j, objectExp, prop, value[prop]); - }); + Object.keys(value).forEach( + (prop: string): void => { + addProperty(j, objectExp, prop, value[prop]); + } + ); valForNode = objectExp; } else { valForNode = createIdentifierOrLiteral(j, value); @@ -468,14 +469,16 @@ function addProperty(j: IJSCodeshift, p: INode, key: string, value: valueType, a } // we only return the generated pushVal which will be replace the node path - if (action === "add") { return pushVal; } + if (action === "add") { + return pushVal; + } if (p.properties) { p.properties.push(pushVal); return p; } - if (p.value && p.value.properties) { - p.value.properties.push(pushVal); + if (p.value && (p.value as Node).properties) { + (p.value as Node).properties.push(pushVal); return p; } if (p.elements) { @@ -495,8 +498,7 @@ function addProperty(j: IJSCodeshift, p: INode, key: string, value: valueType, a * @returns {Node} - the created ast */ -function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueType): INode { - +function removeProperty(j: JSCodeshift, ast: Node, key: string, value: valueType): Node { if (typeof value === "object" && !Array.isArray(value)) { // override for module.rules / loaders if (key === "module" && value.rules) { @@ -504,12 +506,14 @@ function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueTy .find(j.Property, { value: { type: "Literal", - value: value.rules[0].loader, - }, + value: value.rules[0].loader + } }) - .forEach((p: INode) => { - j(p.parent).remove(); - }); + .forEach( + (p: Node): void => { + j(p.parent).remove(); + } + ); } } @@ -517,14 +521,16 @@ function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueTy if (Array.isArray(value)) { return ast .find(j.Literal, { - value: value[0], + value: value[0] }) - .forEach((p: INode) => { - const configKey = safeTraverse(p, ["parent", "parent", "node", "key", "name"]); - if (configKey === key) { - j(p).remove(); + .forEach( + (p: Node): void => { + const configKey = safeTraverse(p, ["parent", "parent", "node", "key", "name"]); + if (configKey === key) { + j(p).remove(); + } } - }); + ); } // value => literal string / boolean / nested object @@ -533,19 +539,23 @@ function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueTy objKeyToRemove = key; } else if (typeof value === "object") { for (const innerKey in value) { - if (value[innerKey] === null) { objKeyToRemove = innerKey; } + if (value[innerKey] === null) { + objKeyToRemove = innerKey; + } } } return ast .find(j.Property, { key: { name: objKeyToRemove, - type: "Identifier", - }, + type: "Identifier" + } }) - .forEach((p: INode) => { - j(p).remove(); - }); + .forEach( + (p: Node): void => { + j(p).remove(); + } + ); } /** @@ -560,20 +570,23 @@ function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueTy * @returns ast - jscodeshift API */ -function parseTopScope(j: IJSCodeshift, ast: INode, value: string[], action: string): boolean | INode { - function createTopScopeProperty(p: INode): boolean { - value.forEach((n: string) => { - if ( - !p.value.body[0].declarations || - n.indexOf(p.value.body[0].declarations[0].id.name) <= 0 - ) { - p.value.body.splice(-1, 0, n); + // 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( + (n: string): void => { + if ( + !(p.value as Node).body[0].declarations || + n.indexOf((p.value as Node).body[0].declarations[0].id.name) <= 0 + ) { + (p.value as Node).body.splice(-1, 0, n); + } } - }); + ); return false; // TODO: debug later } if (value) { - return ast.find(j.Program).filter((p: INode): boolean => createTopScopeProperty(p)); + return ast.find(j.Program).filter((p: Node): boolean => createTopScopeProperty(p)); } else { return ast; } @@ -591,36 +604,36 @@ function parseTopScope(j: IJSCodeshift, ast: INode, value: string[], action: str * @returns ast - jscodeshift API */ -function parseMerge(j: IJSCodeshift, ast: INode, value: string, action: string): boolean | INode { - function createMergeProperty(p: INode) { +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function parseMerge(j: JSCodeshift, ast: Node, value: string, action: string): boolean | Node { + function createMergeProperty(p: Node): boolean { // FIXME Use j.callExp() - const exportsDecl: INode[] = p.value.body.map((n: INode) => { - if (n.expression) { - return n.expression.right; + const exportsDecl: Node[] = (p.value as Node).body.map( + (n: Node): Node => { + if (n.expression) { + return n.expression.right; + } } - }); + ); const bodyLength = exportsDecl.length; - const newVal: INode = {}; + const newVal: Node = {}; newVal.type = "ExpressionStatement"; newVal.expression = { left: { computed: false, object: j.identifier("module"), property: j.identifier("exports"), - type: "MemberExpression", + type: "MemberExpression" }, operator: "=", - right: j.callExpression(j.identifier("merge"), [ - j.identifier(value), - exportsDecl.pop(), - ]), - type: "AssignmentExpression", + right: j.callExpression(j.identifier("merge"), [j.identifier(value), exportsDecl.pop()]), + type: "AssignmentExpression" }; - p.value.body[bodyLength - 1] = newVal; + (p.value as Node).body[bodyLength - 1] = newVal; return false; // TODO: debug later } if (value) { - return ast.find(j.Program).filter((p: INode): boolean => createMergeProperty(p)); + return ast.find(j.Program).filter((p: Node): boolean => createMergeProperty(p)); } else { return ast; } @@ -645,5 +658,5 @@ export { addProperty, removeProperty, parseTopScope, - parseMerge, + parseMerge }; diff --git a/packages/utils/copy-utils.ts b/packages/utils/copy-utils.ts index 5f78d92b3d4..4a593e95ae0 100644 --- a/packages/utils/copy-utils.ts +++ b/packages/utils/copy-utils.ts @@ -1,6 +1,6 @@ import * as path from "path"; -interface IGenerator { +interface Generator { fs: { copy(from: string, to: string, options?: object): void; copyTpl(from: string, to: string, context: object, templateOptions?: object, copyOptions?: object): void; @@ -16,10 +16,9 @@ interface IGenerator { * @param {string} templateDir Absolute path to template directory * @returns {Function} A curried function that takes a file path and copies it */ -export const generatorCopy = ( - generator, - templateDir: string, -): (filePath: string) => void => (filePath: string): void => { +export const generatorCopy = (generator, templateDir: string): ((filePath: string) => void) => ( + filePath: string +): void => { const sourceParts = templateDir.split(path.delimiter); sourceParts.push.apply(sourceParts, filePath.split("/")); const targetParts = path.dirname(filePath).split("/"); @@ -27,7 +26,7 @@ export const generatorCopy = ( generator.fs.copy( path.join.apply(null, sourceParts), - generator.destinationPath(path.join.apply(null, targetParts)), + generator.destinationPath(path.join.apply(null, targetParts)) ); }; @@ -45,8 +44,8 @@ export const generatorCopy = ( export const generatorCopyTpl = ( generator, templateDir: string, - templateData: object, -): (filePath: string) => void => (filePath: string): void => { + templateData: object +): ((filePath: string) => void) => (filePath: string): void => { const sourceParts = templateDir.split(path.delimiter); sourceParts.push.apply(sourceParts, filePath.split("/")); const targetParts = path.dirname(filePath).split("/"); @@ -55,6 +54,6 @@ export const generatorCopyTpl = ( generator.fs.copyTpl( path.join.apply(null, sourceParts), generator.destinationPath(path.join.apply(null, targetParts)), - templateData, + templateData ); }; diff --git a/packages/utils/defineTest.ts b/packages/utils/defineTest.ts index a5ee041d26f..350e03a05ba 100644 --- a/packages/utils/defineTest.ts +++ b/packages/utils/defineTest.ts @@ -1,27 +1,28 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ import * as fs from "fs"; import * as path from "path"; -import { IJSCodeshift, INode } from "./types/NodePath"; +import { JSCodeshift, Node } from "./types/NodePath"; -interface IModule { - ( - jscodeshift: IJSCodeshift, - ast: INode, - initOptions: string | boolean | object, - action: string, - transformName?: string, - ): INode; - default: transformType; - parser: string; +interface Module { + ( + jscodeshift: JSCodeshift, + ast: Node, + initOptions: string | boolean | object, + action: string, + transformName?: string + ): Node; + default: transformType; + parser: string; } type transformType = ( - jscodeshift: IJSCodeshift, - ast: INode, - initOptions: string | boolean | object, - action: object | string, - transformName?: string, -) => INode; + jscodeshift: JSCodeshift, + ast: Node, + initOptions: string | boolean | object, + action: object | string, + transformName?: string +) => Node; /** * Utility function to run a jscodeshift script within a unit test. @@ -48,54 +49,45 @@ type transformType = ( * @return {Function} Function that fires of the transforms */ function runSingleTransform( - dirName: string, - transformName: string, - testFilePrefix: string, - initOptions: object | boolean | string, - action: object | string, + dirName: string, + transformName: string, + testFilePrefix: string, + initOptions: object | boolean | string, + action: object | string ): string { - if (!testFilePrefix) { - testFilePrefix = transformName; - } - const fixtureDir = path.join( - dirName, - "__tests__", - "__testfixtures__", - ); - const inputPath = path.join(fixtureDir, `${testFilePrefix}.input.js`); - const source = fs.readFileSync(inputPath, "utf8"); + if (!testFilePrefix) { + testFilePrefix = transformName; + } + const fixtureDir = path.join(dirName, "__tests__", "__testfixtures__"); + const inputPath = path.join(fixtureDir, `${testFilePrefix}.input.js`); + const source = fs.readFileSync(inputPath, "utf8"); - let module: IModule; - // Assumes transform and test are on the same level - if (action) { - module = require(path.join(dirName, "recursive-parser.ts")); - } else { - module = require(path.join(dirName, `${transformName}.ts`)); - } - // Handle ES6 modules using default export for the transform - const transform = module.default ? module.default : module; + let module: Module; + // Assumes transform and test are on the same level + if (action) { + module = require(path.join(dirName, "recursive-parser.ts")); + } else { + module = require(path.join(dirName, `${transformName}.ts`)); + } + // Handle ES6 modules using default export for the transform + const transform = module.default ? module.default : module; - // Jest resets the module registry after each test, so we need to always get - // a fresh copy of jscodeshift on every test run. - let jscodeshift: IJSCodeshift = require("jscodeshift/dist/core"); - if (module.parser) { - jscodeshift = jscodeshift.withParser(module.parser); - } - const ast: INode = jscodeshift(source); - if (initOptions || typeof initOptions === "boolean") { - return transform( - jscodeshift, - ast, - initOptions, - action, - transformName, - ).toSource({ - quote: "single", - }); - } - return transform(jscodeshift, ast, source, action).toSource({ - quote: "single", - }); + // Jest resets the module registry after each test, so we need to always get + // a fresh copy of jscodeshift on every test run. + // eslint-disable-next-line + let jscodeshift: JSCodeshift = require("jscodeshift/dist/core"); + if (module.parser) { + jscodeshift = jscodeshift.withParser(module.parser); + } + const ast: Node = jscodeshift(source); + if (initOptions || typeof initOptions === "boolean") { + return transform(jscodeshift, ast, initOptions, action, transformName).toSource({ + quote: "single" + }); + } + return transform(jscodeshift, ast, source, action).toSource({ + quote: "single" + }); } /** @@ -116,19 +108,19 @@ function runSingleTransform( * @return {Void} Jest makes sure to execute the globally defined functions */ export default function defineTest( - dirName: string, - transformName: string, - testFilePrefix?: string, - transformObject?: object | string, - action?: object | string, + dirName: string, + transformName: string, + testFilePrefix?: string, + transformObject?: object | string, + action?: object | string ): void { - const testName: string = testFilePrefix - ? `transforms correctly using "${testFilePrefix}" data` - : "transforms correctly"; - describe(transformName, () => { - it(testName, () => { - const output = runSingleTransform(dirName, transformName, testFilePrefix, transformObject, action); - expect(output).toMatchSnapshot(); - }); - }); + const testName: string = testFilePrefix + ? `transforms correctly using "${testFilePrefix}" data` + : "transforms correctly"; + describe(transformName, () => { + it(testName, () => { + const output = runSingleTransform(dirName, transformName, testFilePrefix, transformObject, action); + expect(output).toMatchSnapshot(); + }); + }); } diff --git a/packages/utils/modify-config-helper.ts b/packages/utils/modify-config-helper.ts index 219a45ae5fe..c457a115e26 100644 --- a/packages/utils/modify-config-helper.ts +++ b/packages/utils/modify-config-helper.ts @@ -6,9 +6,9 @@ import * as yeoman from "yeoman-environment"; import Generator = require("yeoman-generator"); import runTransform from "./scaffold"; -import { IGenerator, IYeoman } from "./types/Yeoman"; +import { YeoGenerator } from "./types/Yeoman"; -export interface IConfig extends Object { +export interface Config extends Object { item?: { name: string; }; @@ -18,10 +18,10 @@ export interface IConfig extends Object { webpackOptions: object; } -export interface ITransformConfig extends Object { +export interface TransformConfig extends Object { configPath?: string; configFile?: string; - config?: IConfig; + config?: Config; } const DEFAULT_WEBPACK_CONFIG_FILENAME = "webpack.config.js"; @@ -40,11 +40,10 @@ const DEFAULT_WEBPACK_CONFIG_FILENAME = "webpack.config.js"; export default function modifyHelperUtil( action: string, - generator: IGenerator, + generator: YeoGenerator, configFile: string = DEFAULT_WEBPACK_CONFIG_FILENAME, - packages?: string[]) - : Function { - + packages?: string[] +): Function { let configPath: string | null = null; if (action !== "init") { @@ -57,7 +56,7 @@ export default function modifyHelperUtil( chalk.green(" SUCCESS ") + "Found config " + chalk.cyan(configFile + "\n") + - "\n", + "\n" ); } else { process.stdout.write( @@ -68,7 +67,7 @@ export default function modifyHelperUtil( " not found. Please specify a valid path to your webpack config like " + chalk.white("$ ") + chalk.cyan(`webpack-cli ${action} webpack.dev.js`) + - "\n", + "\n" ); return; } @@ -79,58 +78,68 @@ export default function modifyHelperUtil( if (!generator) { generator = class extends Generator { - public initializing() { - packages.forEach((pkgPath: string) => { - return (this as IGenerator).composeWith(require.resolve(pkgPath)); - }); + public initializing(): void { + packages.forEach( + (pkgPath: string): void => { + return (this as YeoGenerator).composeWith(require.resolve(pkgPath)); + } + ); } }; } env.registerStub(generator, generatorName); - env.run(generatorName).then((_: void) => { - let configModule: object; - try { - const confPath = path.resolve(process.cwd(), ".yo-rc.json"); - configModule = require(confPath); - // Change structure of the config to be transformed - const tmpConfig: object = {}; - Object.keys(configModule).forEach((prop: string): void => { - const configs = Object.keys(configModule[prop].configuration); - configs.forEach((conf: string): void => { - tmpConfig[conf] = configModule[prop].configuration[conf]; - }); - }); - configModule = tmpConfig; - } catch (err) { - console.error( - chalk.red("\nCould not find a yeoman configuration file.\n"), - ); - console.error( - chalk.red( - "\nPlease make sure to use 'this.config.set('configuration', this.configuration);' at the end of the generator.\n", - ), - ); - Error.stackTraceLimit = 0; - process.exitCode = -1; - } - const transformConfig: ITransformConfig = Object.assign( - { - configFile: !configPath ? null : fs.readFileSync(configPath, "utf8"), - configPath, - }, - configModule, - ); - return runTransform(transformConfig, action); - }).catch((err) => { - console.error( - chalk.red( - ` + env.run(generatorName) + .then( + (): void => { + let configModule: object; + try { + const confPath = path.resolve(process.cwd(), ".yo-rc.json"); + configModule = require(confPath); + // Change structure of the config to be transformed + const tmpConfig: object = {}; + Object.keys(configModule).forEach( + (prop: string): void => { + const configs = Object.keys(configModule[prop].configuration); + configs.forEach( + (conf: string): void => { + tmpConfig[conf] = configModule[prop].configuration[conf]; + } + ); + } + ); + configModule = tmpConfig; + } catch (err) { + console.error(chalk.red("\nCould not find a yeoman configuration file.\n")); + console.error( + chalk.red( + "\nPlease make sure to use 'this.config.set('configuration', this.configuration);' at the end of the generator.\n" + ) + ); + Error.stackTraceLimit = 0; + process.exitCode = -1; + } + const transformConfig: TransformConfig = Object.assign( + { + configFile: !configPath ? null : fs.readFileSync(configPath, "utf8"), + configPath + }, + configModule + ); + return runTransform(transformConfig, action); + } + ) + .catch( + (err): void => { + console.error( + chalk.red( + ` Unexpected Error please file an issue here https://github.com/webpack/webpack-cli/issues/new?template=Bug_report.md - `, - ), + ` + ) + ); + console.error(err); + } ); - console.error(err); - }); } diff --git a/packages/utils/npm-exists.ts b/packages/utils/npm-exists.ts index 2abc29b40c3..0db70f11883 100644 --- a/packages/utils/npm-exists.ts +++ b/packages/utils/npm-exists.ts @@ -1,5 +1,7 @@ import * as got from "got"; +// TODO: to understand the type +// eslint-disable-next-line const constant = (value: boolean) => (res: got.Response): boolean | PromiseLike => value; /** @@ -11,11 +13,13 @@ const constant = (value: boolean) => (res: got.Response): boolean | Prom * based on if it exists or not */ +// TODO: figure out the correct type here +// eslint-disable-next-line export default function npmExists(moduleName: string): Promise { const hostname = "https://www.npmjs.org"; const pkgUrl = `${hostname}/package/${moduleName}`; return got(pkgUrl, { - method: "HEAD", + method: "HEAD" }) .then(constant(true)) .catch(constant(false)); diff --git a/packages/utils/npm-packages-exists.ts b/packages/utils/npm-packages-exists.ts index a1987c3332d..529da51ad2f 100644 --- a/packages/utils/npm-packages-exists.ts +++ b/packages/utils/npm-packages-exists.ts @@ -18,46 +18,52 @@ const WEBPACK_SCAFFOLD_PREFIX = "webpack-scaffold"; export default function npmPackagesExists(pkg: string[]): void { const acceptedPackages: string[] = []; - function resolvePackagesIfReady() { + function resolvePackagesIfReady(): void | Function { if (acceptedPackages.length === pkg.length) { return resolvePackages(acceptedPackages); } } - pkg.forEach((scaffold: string): void => { - if (isLocalPath(scaffold)) { - // If the scaffold is a path to a local folder, no name validation is necessary. - acceptedPackages.push(scaffold); - resolvePackagesIfReady(); - return; - } + pkg.forEach( + (scaffold: string): void => { + if (isLocalPath(scaffold)) { + // If the scaffold is a path to a local folder, no name validation is necessary. + acceptedPackages.push(scaffold); + resolvePackagesIfReady(); + return; + } - // The scaffold is on npm; validate name and existence - if ( - scaffold.length <= WEBPACK_SCAFFOLD_PREFIX.length || - scaffold.slice(0, WEBPACK_SCAFFOLD_PREFIX.length) !== WEBPACK_SCAFFOLD_PREFIX - ) { - throw new TypeError( - chalk.bold(`${scaffold} isn't a valid name.\n`) + - chalk.red( - `\nIt should be prefixed with '${WEBPACK_SCAFFOLD_PREFIX}', but have different suffix.\n`, - ), - ); - } + // The scaffold is on npm; validate name and existence + if ( + scaffold.length <= WEBPACK_SCAFFOLD_PREFIX.length || + scaffold.slice(0, WEBPACK_SCAFFOLD_PREFIX.length) !== WEBPACK_SCAFFOLD_PREFIX + ) { + throw new TypeError( + chalk.bold(`${scaffold} isn't a valid name.\n`) + + chalk.red( + `\nIt should be prefixed with '${WEBPACK_SCAFFOLD_PREFIX}', but have different suffix.\n` + ) + ); + } - npmExists(scaffold) - .then((moduleExists: boolean) => { - if (moduleExists) { - acceptedPackages.push(scaffold); - } else { - Error.stackTraceLimit = 0; - throw new TypeError(`Cannot resolve location of package ${scaffold}.`); - } - }) - .catch((err: IError) => { - console.error(err.stack || err); - process.exit(0); - }) - .then(resolvePackagesIfReady); - }); + npmExists(scaffold) + .then( + (moduleExists: boolean): void => { + if (moduleExists) { + acceptedPackages.push(scaffold); + } else { + Error.stackTraceLimit = 0; + throw new TypeError(`Cannot resolve location of package ${scaffold}.`); + } + } + ) + .catch( + (err: Error): void => { + console.error(err.stack || err); + process.exit(0); + } + ) + .then(resolvePackagesIfReady); + } + ); } diff --git a/packages/utils/package-lock.json b/packages/utils/package-lock.json index 5c04b28b295..be49655ae02 100644 --- a/packages/utils/package-lock.json +++ b/packages/utils/package-lock.json @@ -149,7 +149,7 @@ }, "ansi-escapes": { "version": "3.1.0", - "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" }, "ansi-regex": { @@ -465,7 +465,7 @@ }, "array-equal": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" }, "array-union": { @@ -1619,7 +1619,7 @@ "dependencies": { "colors": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" } } @@ -2942,7 +2942,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -2960,11 +2961,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2977,15 +2980,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3088,7 +3094,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3098,6 +3105,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3110,17 +3118,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -3137,6 +3148,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3209,7 +3221,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3219,6 +3232,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3294,7 +3308,8 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3324,6 +3339,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3341,6 +3357,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3379,11 +3396,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.2", - "bundled": true + "bundled": true, + "optional": true } } }, @@ -3545,7 +3564,7 @@ }, "globby": { "version": "8.0.1", - "resolved": "http://registry.npmjs.org/globby/-/globby-8.0.1.tgz", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz", "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==", "requires": { "array-union": "^1.0.1", @@ -4728,7 +4747,7 @@ }, "jsesc": { "version": "1.3.0", - "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" }, "json-buffer": { @@ -5395,7 +5414,7 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { @@ -5410,7 +5429,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "p-cancelable": { @@ -5516,7 +5535,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { @@ -6049,7 +6068,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "requires": { "ret": "~0.1.10" @@ -6711,7 +6730,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "supports-color": { @@ -6729,7 +6748,7 @@ }, "temp": { "version": "0.8.3", - "resolved": "http://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", "requires": { "os-tmpdir": "^1.0.0", diff --git a/packages/utils/package-manager.ts b/packages/utils/package-manager.ts index 0a48e062607..888b974ef18 100644 --- a/packages/utils/package-manager.ts +++ b/packages/utils/package-manager.ts @@ -4,16 +4,11 @@ import * as spawn from "cross-spawn"; import * as fs from "fs"; import * as path from "path"; -interface ISpawnFunctions { +interface SpawnFunctions { npm: (pkg: string, isNew: boolean) => SpawnSyncReturns; yarn: (pkg: string, isNew: boolean) => SpawnSyncReturns; } -const SPAWN_FUNCTIONS: ISpawnFunctions = { - npm: spawnNPM, - yarn: spawnYarn, -}; - /** * * Spawns a new process using npm @@ -25,7 +20,7 @@ const SPAWN_FUNCTIONS: ISpawnFunctions = { function spawnNPM(pkg: string, isNew: boolean): SpawnSyncReturns { return spawn.sync("npm", [isNew ? "install" : "update", "-g", pkg], { - stdio: "inherit", + stdio: "inherit" }); } @@ -40,25 +35,14 @@ function spawnNPM(pkg: string, isNew: boolean): SpawnSyncReturns { function spawnYarn(pkg: string, isNew: boolean): SpawnSyncReturns { return spawn.sync("yarn", ["global", isNew ? "add" : "upgrade", pkg], { - stdio: "inherit", + stdio: "inherit" }); } -/** - * - * Spawns a new process that installs the scaffold/dependency - * - * @param {String} pkg - The dependency to be installed - * @returns {Function} spawn - Installs the package - */ - -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); - return SPAWN_FUNCTIONS[packageManager](pkg, isNew); -} +const SPAWN_FUNCTIONS: SpawnFunctions = { + npm: spawnNPM, + yarn: spawnYarn +}; /** * @@ -69,9 +53,7 @@ export function spawnChild(pkg: string): SpawnSyncReturns { */ export function getPackageManager(): string { - const hasLocalNPM = fs.existsSync( - path.resolve(process.cwd(), "package-lock.json"), - ); + const hasLocalNPM = fs.existsSync(path.resolve(process.cwd(), "package-lock.json")); const hasLocalYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock")); if (hasLocalNPM) { return "npm"; @@ -109,3 +91,18 @@ export function getPathToGlobalPackages(): string { return require("global-modules"); } +/** + * + * Spawns a new process that installs the scaffold/dependency + * + * @param {String} pkg - The dependency to be installed + * @returns {SpawnSyncReturns} spawn - Installs the package + */ +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); + + return SPAWN_FUNCTIONS[packageManager](pkg, isNew); +} diff --git a/packages/utils/recursive-parser.ts b/packages/utils/recursive-parser.ts index f6c9f03b7eb..a6312798f5b 100644 --- a/packages/utils/recursive-parser.ts +++ b/packages/utils/recursive-parser.ts @@ -1,9 +1,13 @@ import * as utils from "./ast-utils"; -import { IJSCodeshift, INode, valueType } from "./types/NodePath"; +import { JSCodeshift, Node, valueType } from "./types/NodePath"; export default function recursiveTransform( - j: IJSCodeshift, ast: INode, key: string, value: valueType, action: string, -): boolean | INode { + j: JSCodeshift, + ast: Node, + key: string, + value: valueType, + action: string +): boolean | Node { if (key === "topScope") { if (Array.isArray(value)) { return utils.parseTopScope(j, ast, value, action); @@ -15,46 +19,39 @@ export default function recursiveTransform( return utils.parseMerge(j, ast, value, action); } } - const node: INode = utils.findRootNodesByName(j, ast, key); + const node: Node = utils.findRootNodesByName(j, ast, key); // get module.exports prop const root = ast .find(j.ObjectExpression) - .filter((p: INode): boolean => { - return ( - utils.safeTraverse(p, [ - "parentPath", - "value", - "left", - "object", - "name", - ]) === "module" && - utils.safeTraverse(p, [ - "parentPath", - "value", - "left", - "property", - "name", - ]) === "exports" - ); - }) - .filter((p: INode): boolean => p.value.properties); + .filter( + (p: Node): boolean => { + return ( + utils.safeTraverse(p, ["parentPath", "value", "left", "object", "name"]) === "module" && + utils.safeTraverse(p, ["parentPath", "value", "left", "property", "name"]) === "exports" + ); + } + ) + .filter((p: Node): boolean => !!(p.value as Node).properties); if (node.size() !== 0) { if (action === "add") { - return utils.findRootNodesByName(j, root, key) - .forEach((p: INode) => { + return utils.findRootNodesByName(j, root, key).forEach( + (p: Node): void => { j(p).replaceWith(utils.addProperty(j, p, key, value, action)); - }); + } + ); } else if (action === "remove") { return utils.removeProperty(j, root, key, value); } } else { - return root.forEach((p: INode) => { - if (value) { - // init, add new property - utils.addProperty(j, p, key, value, null); + return root.forEach( + (p: Node): void => { + if (value) { + // init, add new property + utils.addProperty(j, p, key, value, null); + } } - }); + ); } } diff --git a/packages/utils/resolve-packages.ts b/packages/utils/resolve-packages.ts index b16823509a9..c5dabe60474 100644 --- a/packages/utils/resolve-packages.ts +++ b/packages/utils/resolve-packages.ts @@ -6,7 +6,7 @@ import modifyConfigHelper from "./modify-config-helper"; import { getPathToGlobalPackages } from "./package-manager"; import { spawnChild } from "./package-manager"; -interface IChildProcess { +interface ChildProcess { status: number; } @@ -18,14 +18,16 @@ interface IChildProcess { * @returns {Promise} promise - Returns a promise to the installation */ -export function processPromise(child: IChildProcess): Promise { - return new Promise((resolve: (_?: void) => void, reject: (_?: void) => void) => { - if (child.status !== 0) { - reject(); - } else { - resolve(); +export function processPromise(child: ChildProcess): Promise { + return new Promise( + (resolve: () => void, reject: () => void): void => { + if (child.status !== 0) { + reject(); + } else { + resolve(); + } } - }); + ); } /** @@ -48,46 +50,52 @@ export function resolvePackages(pkg: string[]): Function | void { } } - pkg.forEach((scaffold: string) => { - // Resolve paths to modules on local filesystem - if (isLocalPath(scaffold)) { - let absolutePath: string = scaffold; - - try { - absolutePath = path.resolve(process.cwd(), scaffold); - require.resolve(absolutePath); - packageLocations.push(absolutePath); - } catch (err) { - console.error(`Cannot find a generator at ${absolutePath}.`); - console.error("\nReason:\n"); - console.error(chalk.bold.red(err)); - process.exitCode = 1; - } - - invokeGeneratorIfReady(); - return; - } + pkg.forEach( + (scaffold: string): void => { + // Resolve paths to modules on local filesystem + if (isLocalPath(scaffold)) { + let absolutePath: string = scaffold; - // Resolve modules on npm registry - processPromise(spawnChild(scaffold)) - .then((_: void) => { try { - const globalPath: string = getPathToGlobalPackages(); - packageLocations.push(path.resolve(globalPath, scaffold)); + absolutePath = path.resolve(process.cwd(), scaffold); + require.resolve(absolutePath); + packageLocations.push(absolutePath); } catch (err) { - console.error("Package wasn't validated correctly.."); - console.error("Submit an issue for", pkg, "if this persists"); - console.error("\nReason: \n"); + console.error(`Cannot find a generator at ${absolutePath}.`); + console.error("\nReason:\n"); console.error(chalk.bold.red(err)); process.exitCode = 1; } - }) - .catch((err: string) => { - console.error("Package couldn't be installed, aborting.."); - console.error("\nReason: \n"); - console.error(chalk.bold.red(err)); - process.exitCode = 1; - }) - .then(invokeGeneratorIfReady); - }); + + invokeGeneratorIfReady(); + return; + } + + // Resolve modules on npm registry + processPromise(spawnChild(scaffold)) + .then( + (): void => { + try { + const globalPath: string = getPathToGlobalPackages(); + packageLocations.push(path.resolve(globalPath, scaffold)); + } catch (err) { + console.error("Package wasn't validated correctly.."); + console.error("Submit an issue for", pkg, "if this persists"); + console.error("\nReason: \n"); + console.error(chalk.bold.red(err)); + process.exitCode = 1; + } + } + ) + .catch( + (err: string): void => { + console.error("Package couldn't be installed, aborting.."); + console.error("\nReason: \n"); + console.error(chalk.bold.red(err)); + process.exitCode = 1; + } + ) + .then(invokeGeneratorIfReady); + } + ); } diff --git a/packages/utils/scaffold.ts b/packages/utils/scaffold.ts index a3add9ee769..2d2ece8a390 100644 --- a/packages/utils/scaffold.ts +++ b/packages/utils/scaffold.ts @@ -4,12 +4,12 @@ import pEachSeries = require("p-each-series"); import * as path from "path"; import { findProjectRoot } from "./find-root"; -import { IError } from "../init/types"; -import { IConfig, ITransformConfig } from "./modify-config-helper"; +import { Error } from "../init/types"; +import { Config, TransformConfig } from "./modify-config-helper"; import propTypes from "./prop-types"; import astTransform from "./recursive-parser"; import runPrettier from "./run-prettier"; -import { INode } from "./types/NodePath"; +import { Node } from "./types/NodePath"; /** * @@ -20,7 +20,7 @@ import { INode } from "./types/NodePath"; * @returns {Array} - An array with keys on which transformations need to be run */ -function mapOptionsToTransform(config: IConfig): string[] { +function mapOptionsToTransform(config: Config): string[] { return Object.keys(config.webpackOptions).filter((k: string): boolean => propTypes.has(k)); } @@ -34,72 +34,73 @@ function mapOptionsToTransform(config: IConfig): string[] { * and writes the file */ -export default function runTransform(transformConfig: ITransformConfig, action: string): void { +export default function runTransform(transformConfig: TransformConfig, action: string): void { // webpackOptions.name sent to nameTransform if match - const webpackConfig = Object.keys(transformConfig).filter((p: string): boolean => { - return p !== "configFile" && p !== "configPath"; - }); + const webpackConfig = Object.keys(transformConfig).filter( + (p: string): boolean => { + return p !== "configFile" && p !== "configPath"; + } + ); const initActionNotDefined = action && action !== "init" ? true : false; - webpackConfig.forEach((scaffoldPiece: string) => { - const config: IConfig = transformConfig[scaffoldPiece]; + webpackConfig.forEach( + (scaffoldPiece: string): Promise => { + const config: Config = transformConfig[scaffoldPiece]; - const transformations = mapOptionsToTransform(config); + const transformations = mapOptionsToTransform(config); - if (config.topScope && transformations.indexOf("topScope") === -1) { - transformations.push("topScope"); - } + if (config.topScope && transformations.indexOf("topScope") === -1) { + transformations.push("topScope"); + } - if (config.merge) { - transformations.push("merge"); - } + if (config.merge) { + transformations.push("merge"); + } - const ast: INode = j( - initActionNotDefined - ? transformConfig.configFile - : "module.exports = {}", - ); + const ast: Node = j(initActionNotDefined ? transformConfig.configFile : "module.exports = {}"); - const transformAction: string = action || null; + const transformAction: string = action || null; - return pEachSeries(transformations, (f: string): boolean | INode => { - if (f === "merge" || f === "topScope") { - return astTransform(j, ast, f, config[f], transformAction); - } - return astTransform(j, ast, f, config.webpackOptions[f], transformAction); - }) - .then((value: string[]): void | PromiseLike => { - let configurationName: string; - if (!config.configName) { - configurationName = "webpack.config.js"; - } else { - configurationName = "webpack." + config.configName + ".js"; + return pEachSeries( + transformations, + (f: string): boolean | Node => { + if (f === "merge" || f === "topScope") { + // TODO: typing here is difficult to understand + // eslint-disable-next-line @typescript-eslint/no-explicit-any + 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", - }); - runPrettier(outputPath, source); - - }) - .catch((err: IError) => { - console.error(err.message ? err.message : err); - }); - }); + 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`; if (initActionNotDefined && transformConfig.config.item) { - successMessage = `Congratulations! ${ - transformConfig.config.item - } has been ${action}ed!\n`; + successMessage = `Congratulations! ${transformConfig.config.item} has been ${action}ed!\n`; } - process.stdout.write( - "\n" + - chalk.green( - successMessage, - ), - ); + process.stdout.write("\n" + chalk.green(successMessage)); } diff --git a/packages/utils/types/NodePath.ts b/packages/utils/types/NodePath.ts index d082ddc6587..1b828378ddb 100644 --- a/packages/utils/types/NodePath.ts +++ b/packages/utils/types/NodePath.ts @@ -1,93 +1,99 @@ -export interface INode extends Object { +export interface Node extends Object { id?: { name: string; }; - arguments?: INode[]; - body?: INode[]; - elements?: INode[]; + arguments?: Node[]; + body?: Node[]; + elements?: Node[]; expression?: { left: { - computed: boolean, - object: INode, - property: INode, - type: string, - }, - operator: string, - right: INode, - type: string, + computed: boolean; + object: Node; + property: Node; + type: string; + }; + operator: string; + right: Node; + type: string; + value?: string; }; - filter?: (p: (p: INode) => boolean) => INode; - find?: (objectExpression: object, filterExpression?: object) => INode; - forEach?: (p: (p: INode) => void) => INode; - get?: (property: string) => INode; - remove?: (_?: void) => void; - nodes?: (_?: void) => INode[]; - pop?: (_?: void) => INode; + filter?: (p: (p: Node) => boolean) => Node; + find?: (objectExpression: object, filterExpression?: object) => Node; + forEach?: (p: (p: Node) => void) => Node; + get?: (property: string) => Node; + remove?: () => void; + nodes?: () => Node[]; + pop?: () => Node; key?: { name: string; - value: INode | string; + value: Node | string; }; - node?: INode; + node?: Node; name?: string; object?: object; - parent?: INode; - properties?: INode[]; - property?: INode; + parent?: Node; + properties?: Node[]; + property?: Node; prune?: Function; - replaceWith?: (objectExpression: object) => INode; - size?: (_?: void) => number; + replaceWith?: (objectExpression: object) => Node; + size?: () => number; type?: string; - value?: INode | string | any; - toSource?: (object: { - quote?: string, - }) => string; + value?: Node | string | Node[]; + toSource?: ( + object: { + quote?: string; + } + ) => string; source?: string; - ast?: INode; - rules?: IModuleRule[]; - __paths?: INode[]; + ast?: Node; + rules?: ModuleRule[]; + + declarations?: Node[]; + + __paths?: Node[]; } -interface IModuleRule { +interface ModuleRule { loader?: string; } -interface IExpressionObject { +interface ExpressionObject { name?: string; } -export interface IJSCodeshift extends Object { - (source?: INode | string): INode; - withParser?: (parser: string) => IJSCodeshift; - identifier?: (key: string) => INode; - literal?: (key: valueType) => INode; - memberExpression?: (node1: INode, node2: INode, bool?: boolean) => INode; - objectProperty?: (key: INode, property: valueType) => INode; - objectExpression?: (properties: INode[]) => INode; - newExpression?: (expression: INode, args: INode[]) => INode; - callExpression?: (expression: INode, args: INode[]) => INode; - variableDeclarator?: (key: INode, args: INode) => INode; - variableDeclaration?: (key: string, args: INode[]) => INode; - arrayExpression?: (args?: INode[]) => INode; - property?: (type: string, key: INode, value: INode) => INode; - program?: (nodes: INode[]) => INode; - booleanLiteral?: (bool: boolean) => INode; - Property?: IExpressionObject; - NewExpression?: IExpressionObject; - CallExpression?: IExpressionObject; - VariableDeclarator?: IExpressionObject; - Identifier?: IExpressionObject; - Literal?: IExpressionObject; - ArrayExpression?: IExpressionObject; - MemberExpression?: IExpressionObject; - FunctionExpression?: IExpressionObject; - ObjectExpression?: IExpressionObject; - BlockStatement?: IExpressionObject; - Program?: IExpressionObject; +export interface JSCodeshift extends Object { + (source?: Node | string): Node; + withParser?: (parser: string) => JSCodeshift; + identifier?: (key: string) => Node; + literal?: (key: valueType) => Node; + memberExpression?: (node1: Node, node2: Node, bool?: boolean) => Node; + objectProperty?: (key: Node, property: valueType) => Node; + objectExpression?: (properties: Node[]) => Node; + newExpression?: (expression: Node, args: Node[]) => Node; + callExpression?: (expression: Node, args: Node[]) => Node; + variableDeclarator?: (key: Node, args: Node) => Node; + variableDeclaration?: (key: string, args: Node[]) => Node; + arrayExpression?: (args?: Node[]) => Node; + property?: (type: string, key: Node, value: Node) => Node; + program?: (nodes: Node[]) => Node; + booleanLiteral?: (bool: boolean) => Node; + Property?: ExpressionObject; + NewExpression?: ExpressionObject; + CallExpression?: ExpressionObject; + VariableDeclarator?: ExpressionObject; + Identifier?: ExpressionObject; + Literal?: ExpressionObject; + ArrayExpression?: ExpressionObject; + MemberExpression?: ExpressionObject; + FunctionExpression?: ExpressionObject; + ObjectExpression?: ExpressionObject; + BlockStatement?: ExpressionObject; + Program?: ExpressionObject; filters?: { VariableDeclarator: { - requiresModule: Function, - }, + requiresModule: Function; + }; }; } -export type valueType = string | number | boolean | any[] | INode | null; +export type valueType = string | number | boolean | Node | null; diff --git a/packages/utils/types/Yeoman.ts b/packages/utils/types/Yeoman.ts index 4c56a771c00..16615324c03 100644 --- a/packages/utils/types/Yeoman.ts +++ b/packages/utils/types/Yeoman.ts @@ -1,12 +1,12 @@ -interface IRunEnv extends Object { +interface RunEnv extends Object { on?: (event: string, callbackFn: Function) => void; } -export interface IYeoman extends Object { - registerStub?(generator: IGenerator, namespace: string): void; - run?(target: string, options?: object, done?: Function): IRunEnv; +export interface Yeoman extends Object { + registerStub?(generator: YeoGenerator, namespace: string): void; + run?(target: string, options?: object, done?: Function): RunEnv; } -export interface IGenerator extends Object { +export interface YeoGenerator extends Object { composeWith?: (path: string) => void; } diff --git a/packages/utils/types/index.ts b/packages/utils/types/index.ts index fd94138d988..dba558d3ccf 100644 --- a/packages/utils/types/index.ts +++ b/packages/utils/types/index.ts @@ -1,4 +1,4 @@ -interface IError { - stack?: object; - message?: string; +interface Error { + stack?: string; + message: string; } diff --git a/packages/utils/validate-identifier.ts b/packages/utils/validate-identifier.ts index b3d0b155acf..272b01f364a 100644 --- a/packages/utils/validate-identifier.ts +++ b/packages/utils/validate-identifier.ts @@ -8,13 +8,7 @@ function isKeyword(code: string): boolean { case 2: return code === "if" || code === "in" || code === "do"; case 3: - return ( - code === "var" || - code === "for" || - code === "new" || - code === "try" || - code === "let" - ); + return code === "var" || code === "for" || code === "new" || code === "try" || code === "let"; case 4: return ( code === "this" || @@ -61,9 +55,7 @@ function isKeyword(code: string): boolean { case 8: return code === "function" || code === "continue" || code === "debugger"; case 9: - return ( - code === "protected" || code === "interface" || code === "arguments" - ); + return code === "protected" || code === "interface" || code === "arguments"; case 10: return code === "instanceof" || code === "implements"; default: @@ -77,19 +69,13 @@ function isKeyword(code: string): boolean { // are only applied when a character is found to actually have a // code point above 128. -/* tslint:disable: max-line-length */ let nonASCIIidentifierStartChars = -"\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b2\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua7ad\ua7b0\ua7b1\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab5f\uab64\uab65\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b2\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua7ad\ua7b0\ua7b1\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab5f\uab64\uab65\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; let nonASCIIidentifierChars = -"\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfc-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2d\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; -/* tslint:enable: max-line-length */ + "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfc-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2d\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; -const nonASCIIidentifierStart: RegExp = new RegExp( - "[" + nonASCIIidentifierStartChars + "]", -); -const nonASCIIidentifier: RegExp = new RegExp( - "[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]", -); +const nonASCIIidentifierStart: RegExp = new RegExp("[" + nonASCIIidentifierStartChars + "]"); +const nonASCIIidentifier: RegExp = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; @@ -425,7 +411,7 @@ const astralIdentifierStartCodes = [ 12, 221, 16355, - 541, + 541 ]; const astralIdentifierCodes = [ @@ -548,7 +534,7 @@ const astralIdentifierCodes = [ 4305, 6, 792618, - 239, + 239 ]; // This has a complexity linear to the value of the code. The @@ -558,10 +544,14 @@ function isInAstralSet(code: number, set: number[]): boolean { let pos = 0x10000; for (let i = 0; i < set.length; i += 2) { pos += set[i]; - if (pos > code) { return false; } + if (pos > code) { + return false; + } pos += set[i + 1]; - if (pos >= code) { return true; } + if (pos >= code) { + return true; + } } } @@ -569,16 +559,49 @@ function isInAstralSet(code: number, set: number[]): boolean { function isIdentifierStart(code: string): boolean { const c: number = code.charCodeAt(0); - if (c < 65) { return c === 36; } - if (c < 91) { return true; } - if (c < 97) { return c === 95; } - if (c < 123) { return true; } + if (c < 65) { + return c === 36; + } + if (c < 91) { + return true; + } + if (c < 97) { + return c === 95; + } + if (c < 123) { + return true; + } if (c <= 0xffff) { return c >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(c)); } return isInAstralSet(c, astralIdentifierStartCodes); } +function validationChar(charCode: number): boolean { + if (charCode < 48) { + return charCode === 36; + } + if (charCode < 58) { + return true; + } + if (charCode < 65) { + return false; + } + if (charCode < 91) { + return true; + } + if (charCode < 97) { + return charCode === 95; + } + if (charCode < 123) { + return true; + } + if (charCode <= 0xffff) { + return charCode >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(charCode)); + } + return isInAstralSet(charCode, astralIdentifierStartCodes) || isInAstralSet(charCode, astralIdentifierCodes); +} + // Test whether a given character is part of an identifier. function isIdentifierChar(code: string): boolean { @@ -595,24 +618,4 @@ function isIdentifierChar(code: string): boolean { } } -function validationChar(charCode: number): boolean { - if (charCode < 48) { return charCode === 36; } - if (charCode < 58) { return true; } - if (charCode < 65) { return false; } - if (charCode < 91) { return true; } - if (charCode < 97) { return charCode === 95; } - if (charCode < 123) { return true; } - if (charCode <= 0xffff) { - return charCode >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(charCode)); - } - return ( - isInAstralSet(charCode, astralIdentifierStartCodes) || - isInAstralSet(charCode, astralIdentifierCodes) - ); -} - -export { - isIdentifierChar, - isIdentifierStart, - isKeyword, -}; +export { isIdentifierChar, isIdentifierStart, isKeyword }; diff --git a/packages/webpack-scaffold/.eslintrc b/packages/webpack-scaffold/.eslintrc new file mode 100644 index 00000000000..365d9f85d71 --- /dev/null +++ b/packages/webpack-scaffold/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": [ + "../../.eslintrc.js", + "plugin:@typescript-eslint/recommended", + "prettier", + "prettier/@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"] +} diff --git a/packages/webpack-scaffold/__tests__/.eslintrc b/packages/webpack-scaffold/__tests__/.eslintrc new file mode 100644 index 00000000000..5d4340a351d --- /dev/null +++ b/packages/webpack-scaffold/__tests__/.eslintrc @@ -0,0 +1,7 @@ +{ + "root": true, + "extends": ["../.eslintrc"], + "rules": { + "@typescript-eslint/explicit-function-return-type": ["off"] + } +} diff --git a/packages/webpack-scaffold/index.ts b/packages/webpack-scaffold/index.ts index e666071046d..66303f5d989 100755 --- a/packages/webpack-scaffold/index.ts +++ b/packages/webpack-scaffold/index.ts @@ -1,23 +1,28 @@ import * as jscodeshift from "jscodeshift"; -export interface IInquirerScaffoldObject { +export interface InquirerScaffoldObject { type?: string; name: string; message: string; - choices?: ((answers: Object) => string) | string[]; - default?: string | number | boolean | string[] | number[] - | ((answers: Object) => (string | number | boolean | string[] | number[])); - validate?: ((input: string) => boolean | string); - when?: ((answers: Object) => boolean) | boolean; + choices?: ((answers: Record) => string) | string[]; + default?: + | string + | number + | boolean + | string[] + | number[] + | ((answers: Record) => string | number | boolean | string[] | number[]); + validate?: (input: string) => boolean | string; + when?: ((answers: Record) => boolean) | boolean; store?: boolean; filter?: (name: string) => string; } -export interface IInquirerList extends IInquirerScaffoldObject { +export interface InquirerList extends InquirerScaffoldObject { choices?: string[]; } -export interface IInquirerInput extends IInquirerScaffoldObject { +export interface InquirerInput extends InquirerScaffoldObject { validate?: (input: string) => string | boolean; } @@ -33,9 +38,11 @@ export function createDynamicPromise(arrOrString: string[] | string): string { if (Array.isArray(arrOrString)) { return ( "() => new Promise((resolve) => resolve([" + - arrOrString.map((func: string): string => { - return "'" + func + "'"; - }) + + arrOrString.map( + (func: string): string => { + return "'" + func + "'"; + } + ) + "]))" ); } else { @@ -67,63 +74,68 @@ export function createRequire(val: string): string { return `const ${val} = require('${val}');`; } -export function List(name: string, message: string, choices: string[]): IInquirerList { +export function List(name: string, message: string, choices: string[]): InquirerList { return { choices, message, name, - type: "list", + type: "list" }; } -export function RawList(name: string, message: string, choices: string[]): IInquirerList { +export function RawList(name: string, message: string, choices: string[]): InquirerList { return { choices, message, name, - type: "rawlist", + type: "rawlist" }; } -export function CheckList(name: string, message: string, choices: string[]): IInquirerList { +export function CheckList(name: string, message: string, choices: string[]): InquirerList { return { choices, message, name, - type: "checkbox", + type: "checkbox" }; } -export function Input(name: string, message: string): IInquirerInput { +export function Input(name: string, message: string): InquirerInput { return { message, name, - type: "input", + type: "input" }; } -export function InputValidate(name: string, message: string, cb?: (input: string) => string | boolean): IInquirerInput { +export function InputValidate(name: string, message: string, cb?: (input: string) => string | boolean): InquirerInput { return { message, name, type: "input", - validate: cb, + validate: cb }; } -export function Confirm(name: string, message: string, defaultChoice: boolean = true): IInquirerScaffoldObject { +export function Confirm(name: string, message: string, defaultChoice: boolean = true): InquirerScaffoldObject { return { default: defaultChoice, message, name, - type: "confirm", + type: "confirm" }; } -export function AutoComplete(name: string, message: string, options: object = {}) { - return Object.assign({ - message, - name, - type: "autocomplete", - }, options); +// TODO: to understand this type +// eslint-disable-next-line +export function AutoComplete(name: string, message: string, options: object = {}): any { + return Object.assign( + { + message, + name, + type: "autocomplete" + }, + options + ); } diff --git a/packages/webpack-scaffold/package-lock.json b/packages/webpack-scaffold/package-lock.json index 9ef7540efc7..c7674e406ae 100644 --- a/packages/webpack-scaffold/package-lock.json +++ b/packages/webpack-scaffold/package-lock.json @@ -1,6 +1,6 @@ { "name": "@webpack-cli/webpack-scaffold", - "version": "0.1.3", + "version": "0.1.5", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1248,7 +1248,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "parse-glob": { @@ -1439,7 +1439,7 @@ }, "temp": { "version": "0.8.3", - "resolved": "http://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", "requires": { "os-tmpdir": "^1.0.0", diff --git a/tsconfig.packages.json b/tsconfig.packages.json index 87eae9c0e2a..3f4af061bd6 100644 --- a/tsconfig.packages.json +++ b/tsconfig.packages.json @@ -1,5 +1,5 @@ { - "extends": "tsconfig.base.json", + "extends": "./tsconfig.base.json", "compilerOptions": { "declaration": true } diff --git a/tslint.json b/tslint.json deleted file mode 100644 index ee672ce2d93..00000000000 --- a/tslint.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": { - "indent": [ - true, - "tabs", - 4 - ], - "ban-types": [ - false - ], - "no-console": [true, "log"] - }, - "rulesDirectory": [], - "linterOptions": { - "exclude": [ - "node_modules/**", - "packages/*/node_modules/**" - ] - } -} From f7451d427df679755587006b62550b2f202de817 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Sun, 21 Apr 2019 17:11:58 +0530 Subject: [PATCH 18/39] docs(serve): update docs to use webpack-dev-server update docs to use webpack-dev-server ISSUES CLOSED: #846 --- bin/config/optionsSchema.json | 2 +- packages/serve/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/config/optionsSchema.json b/bin/config/optionsSchema.json index aa272397d03..8e95e1b7926 100644 --- a/bin/config/optionsSchema.json +++ b/bin/config/optionsSchema.json @@ -1680,7 +1680,7 @@ ] }, "serve": { - "description": "Options for webpack-serve", + "description": "Options for webpack-dev-server", "type": "object" }, "stats": { diff --git a/packages/serve/README.md b/packages/serve/README.md index aab9613599c..a4f3c9a51f9 100644 --- a/packages/serve/README.md +++ b/packages/serve/README.md @@ -4,7 +4,7 @@ ## Description -This package contains the logic to run webpack-serve without using webpack-serve directly. +This package contains the logic to run webpack-dev-server to serve your webpack app and provide live reloading. ## Installation From cb68b1bfb899068006b2f7ad3b8ee0b409ea2763 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Sun, 21 Apr 2019 21:51:37 +0530 Subject: [PATCH 19/39] docs(serve): link to webpack-dev-server link to webpack-dev-server --- packages/serve/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/serve/README.md b/packages/serve/README.md index a4f3c9a51f9..39269aef404 100644 --- a/packages/serve/README.md +++ b/packages/serve/README.md @@ -4,7 +4,7 @@ ## Description -This package contains the logic to run webpack-dev-server to serve your webpack app and provide live reloading. +This package contains the logic to run [webpack-dev-server](https://github.com/webpack/webpack-dev-server) to serve your webpack app and provide live reloading. ## Installation From d3f8e2098130493299206acdd5d8887419d66bcc Mon Sep 17 00:00:00 2001 From: ev1stensberg Date: Sun, 21 Apr 2019 20:54:48 +0200 Subject: [PATCH 20/39] chore: v.3.1.1 --- CHANGELOG.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eda649a0f3..37c2792d7ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,91 @@ + +# 3.3.1 (2019-04-21) +[Full Changelog](https://github.com/webpack/webpack-cli/compare/v0.1.5...v3.3.1) + +## New Features + +* terser: clean old files ([89e6b74](https://github.com/webpack/webpack-cli/commit/89e6b74)) +* terser: remove leftover files ([27d5b4d](https://github.com/webpack/webpack-cli/commit/27d5b4d)) +* terser: replace after merging master ([c404655](https://github.com/webpack/webpack-cli/commit/c404655)) +* replace Uglify with Terser in generators ([2b8651b](https://github.com/webpack/webpack-cli/commit/2b8651b)) +* use terserPlugin in loaderOptionsPlugin ([14f5337](https://github.com/webpack/webpack-cli/commit/14f5337)) +* use terserJsPlugin for transformations during migrate ([33c6185](https://github.com/webpack/webpack-cli/commit/33c6185)) +* replace uglifyJsPlugin with terserPlugin in migrate ([d467f3b](https://github.com/webpack/webpack-cli/commit/d467f3b)) +* opencollective prompt: work on windows setting atime by code ([3af73a8](https://github.com/webpack/webpack-cli/commit/3af73a8)) +* opencollective prompt: fix typo ([c2351b1](https://github.com/webpack/webpack-cli/commit/c2351b1)) +* opencollective prompt: remove .lastocprint file from fs ([b96ad56](https://github.com/webpack/webpack-cli/commit/b96ad56)) +* opencollective prompt: extract weekday to variable ([790d27a](https://github.com/webpack/webpack-cli/commit/790d27a)) +* opencollective prompt: set terminal cols to 80 ([badc32d](https://github.com/webpack/webpack-cli/commit/badc32d)) +* opencollective prompt: fix azure ci ([ea0039a](https://github.com/webpack/webpack-cli/commit/ea0039a)) +* opencollective prompt: lint ([ea906d8](https://github.com/webpack/webpack-cli/commit/ea906d8)) +* opencollective prompt: clear package.json modifications ([f080733](https://github.com/webpack/webpack-cli/commit/f080733)) +* opencollective prompt: add prompt in postinstall script ([dd9d528](https://github.com/webpack/webpack-cli/commit/dd9d528)) + +## Ast + +* change tooltip property from uglify to terser ([ea9e4b8](https://github.com/webpack/webpack-cli/commit/ea9e4b8)) +* replace requires and inits for uglify with terser ([3011a6c](https://github.com/webpack/webpack-cli/commit/3011a6c)) +* replace UglifyJsPlugin with TerserPlugin ([21da35f](https://github.com/webpack/webpack-cli/commit/21da35f)) + +## Chore + +* cli: move constants to a separate file ([#798](https://github.com/webpack/webpack-cli/pull/798)) +* deps: upgrade lerna to fix vulnerabilities & update webpack-dev-server ([#823](https://github.com/webpack/webpack-cli/pull/823)) +* docs: removes scaffolding docs from the root ([8c1db03](https://github.com/webpack/webpack-cli/commit/8c1db03)) +* junit: reverting the junit.xml ([80fd4fa](https://github.com/webpack/webpack-cli/commit/80fd4fa)) +* tests: updated test regex, some helper scripts ([#809](https://github.com/webpack/webpack-cli/pull/809)) +* types: add type information ([#791](https://github.com/webpack/webpack-cli/pull/791)) +* replace instances of uglify with terser ([f9cb8ce](https://github.com/webpack/webpack-cli/commit/f9cb8ce)) +* use actual package name in comment about removing uglify ([b1cf4cc](https://github.com/webpack/webpack-cli/commit/b1cf4cc)) +* align file in the same way as other terserPlugin test fixtures ([b6c6484](https://github.com/webpack/webpack-cli/commit/b6c6484)) +* remove gitHash from package.json ([2af08be](https://github.com/webpack/webpack-cli/commit/2af08be)) + +## Docs + +* contributing: fixes dead link ([#835](https://github.com/webpack/webpack-cli/pull/835)) +* opencollective prompt: improve code clarity ([55992a4](https://github.com/webpack/webpack-cli/commit/55992a4)) +* packages: adds downloads/month shield ([6a0375a](https://github.com/webpack/webpack-cli/commit/6a0375a)) +* readme: adds contributors shield ([958d064](https://github.com/webpack/webpack-cli/commit/958d064)) +* README: phrase change ([3a11a16](https://github.com/webpack/webpack-cli/commit/3a11a16)) +* README: add link to webpack-scaffold-starter ([e35a194](https://github.com/webpack/webpack-cli/commit/e35a194)) +* README: update scaffolding links ([74179b5](https://github.com/webpack/webpack-cli/commit/74179b5)) +* serve: link to webpack-dev-server ([cb68b1b](https://github.com/webpack/webpack-cli/commit/cb68b1b)) +* serve: update docs to use webpack-dev-server ([f7451d4](https://github.com/webpack/webpack-cli/commit/f7451d4)) +* replace tooltip link to terser plugin ([4254730](https://github.com/webpack/webpack-cli/commit/4254730)) +* replace Uglify with Terser in comments ([799577d](https://github.com/webpack/webpack-cli/commit/799577d)) +* replace UglifyJsPlugin with TerserPlugin in migrate docs ([326f783](https://github.com/webpack/webpack-cli/commit/326f783)) + +## Enh + +* webpack-scaffold: improve prompt and doc ([#794](https://github.com/webpack/webpack-cli/pull/794)) + +## Fix + +* add: add types ([d4ce6f2](https://github.com/webpack/webpack-cli/commit/d4ce6f2)) +* add: fix runTransform ([dbc3e9e](https://github.com/webpack/webpack-cli/commit/dbc3e9e)) +* add: lint code ([163b309](https://github.com/webpack/webpack-cli/commit/163b309)) +* add: add handling for topScope ([1162cf5](https://github.com/webpack/webpack-cli/commit/1162cf5)) +* bin, serve: force default package export, add serve default ([#815](https://github.com/webpack/webpack-cli/pull/815)) +* init: refactored the init.ts success message ([#810](https://github.com/webpack/webpack-cli/pull/810)) +* scaffold: config file is always generated at the project root ([#801](https://github.com/webpack/webpack-cli/pull/801)) +* utils: refactors utils ([7fe3543](https://github.com/webpack/webpack-cli/commit/7fe3543)) +* clear up comment about default function purpose ([e48507d](https://github.com/webpack/webpack-cli/commit/e48507d)) +* remove unused files ([ec242ab](https://github.com/webpack/webpack-cli/commit/ec242ab)) +* reset files ([9863445](https://github.com/webpack/webpack-cli/commit/9863445)) +* replace lookups for TerserPlugin in webpack.optimise ([ef23fec](https://github.com/webpack/webpack-cli/commit/ef23fec)) + +## Tests + +* update snapshots ([ce9fbc8](https://github.com/webpack/webpack-cli/commit/ce9fbc8)) +* replace uglify with terser in ast-utils tests ([73f493f](https://github.com/webpack/webpack-cli/commit/73f493f)) +* migration: typescript ([#613](https://github.com/webpack/webpack-cli/pull/613)) + +## Misc + +* Remove tslint in favour of eslint ([#834](https://github.com/webpack/webpack-cli/pull/834)) +* cli: refactor functions into utils and config dirs, merge yargs options ([#781](https://github.com/webpack/webpack-cli/pull/781)) +* utils: refactors scaffold ([0b28fb3](https://github.com/webpack/webpack-cli/commit/0b28fb3)) + # 3.3.0 (2019-03-15) [Full Changelog](https://github.com/webpack/webpack-cli/compare/v0.1.3...v3.3.0) diff --git a/package-lock.json b/package-lock.json index f72cab5b2a6..5af3e7a31cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "webpack-cli", - "version": "3.3.0", + "version": "3.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 7d4b80cf5ea..f3a9eac7bc3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "webpack-cli", - "version": "3.3.0", + "version": "3.3.1", "description": "CLI for webpack & friends", "license": "MIT", "repository": { From 46049e6d8fbf328dae9fd4624baa6422d9627519 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Mon, 22 Apr 2019 10:16:22 +0530 Subject: [PATCH 21/39] docs(readme): fix typos, add summary of all commands (#845) * docs(readme): fix typos, add summary of all commands fix typos, add summary of all commands in commands section * docs(readme): remove commands list in the beginning remove commands list from the beginning * docs(docs): include util packages include util packages --- README.md | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 8e5a30b157b..381f5610cd1 100644 --- a/README.md +++ b/README.md @@ -27,16 +27,7 @@ - [How to install](#how-to-install) * [Getting Started](#getting-started) * [webpack CLI Scaffolds](#webpack-cli-scaffolds) -* Commands - - [`webpack-cli init`](./packages/init/README.md#webpack-cli-init) - - [`webpack-cli add`](./packages/add/README.md#webpack-cli-add) - - [`webpack-cli info`](./packages/info/README.md#webpack-cli-info) - - [`webpack-cli migrate`](./packages/migrate/README.md#webpack-cli-migrate) - - [`webpack-cli remove`](./packages/remove/README.md#webpack-cli-remove) - - [`webpack-cli generate-plugin`](./packages/generate-plugin/README.md#webpack-cli-generate-plugin) - - [`webpack-cli generate-loader`](./packages/generate-loader/README.md#webpack-cli-generate-loader) - - [`webpack-cli serve`](./packages/serve/README.md#webpack-cli-serve) - - [`webpack-cli update`](./packages/update/README.md#webpack-cli-update) +* [Commands](#commands) * [webpack.config.js](https://webpack.js.org/concepts/configuration/) * [Contributing and Internal Documentation](#contributing-and-internal-documentation) @@ -50,24 +41,47 @@ When you have followed the [Getting Started](https://webpack.js.org/guides/getti Otherwise `npm install --save-dev webpack-cli` or `yarn add webpack-cli --dev` will install it. +## Packages + +We organize webpack CLI as a multi-package repository using [lerna](https://github.com/lerna/lerna). Every command has a dedicated subfolder in the `packages` Folder. Here's a summary of commands provided by the CLI. + ### Commands -Supporting developers is an important task for webpack CLI. Thus, webpack CLI provides different commands for many common tasks. We organize webpack CLI as a [multi-package repository](https://github.com/lerna/lerna). Every command has a dedicated subfolder in the `packages` Folder. +Supporting developers is an important task for webpack CLI. Thus, webpack CLI provides different commands for many common tasks. + +- [`webpack-cli init`](./packages/init/README.md#webpack-cli-init) - Create a new webpack configuration. +- [`webpack-cli add`](./packages/add/README.md#webpack-cli-add) - Add new properties to a webpack configuration file. +- [`webpack-cli info`](./packages/info/README.md#webpack-cli-info) - Returns information related to the local environment. +- [`webpack-cli migrate`](./packages/migrate/README.md#webpack-cli-migrate) - Migrate project from one version to another. +- [`webpack-cli remove`](./packages/remove/README.md#webpack-cli-remove) - Remove properties from a webpack configuration file. +- [`webpack-cli generate-plugin`](./packages/generate-plugin/README.md#webpack-cli-generate-plugin) - Initiate new plugin project. +- [`webpack-cli generate-loader`](./packages/generate-loader/README.md#webpack-cli-generate-loader) - Initiate new loader project. +- [`webpack-cli serve`](./packages/serve/README.md#webpack-cli-serve) - Use webpack with a development server that provides live reloading. +- [`webpack-cli update`](./packages/update/README.md#webpack-cli-update) - Update properties in a webpack configuration file. + +### Utilities + +The project also has several utility packages which are used by other commands + +- [`utils`](./packages/utils/README.md) - Several utilities used across webpack-cli. +- [`generators`](./packages/generators/README.md) - Contains all webpack-cli related yeoman generators. +- [`webpack-scaffold`](./packages/info/README.md#webpack-cli-info) - Utilities to create a webpack scaffold. + ## Getting started -When you have followed the [Getting Started](https://webpack.js.org/guides/getting-started/) guide of webpack then webpack CLI is already installed! Otherwise, you would need to install webpack CLI and the packages you want to use. If we want to use the `init` functionality to create a new `webpack.config.js` configuration file: +When you have followed the [Getting Started](https://webpack.js.org/guides/getting-started/) guide of webpack then webpack CLI is already installed! Otherwise, you would need to install webpack CLI and the packages you want to use. If we want to use the `init` command to create a new `webpack.config.js` configuration file: ```sh npm i webpack-cli @webpack-cli/init npx webpack-cli init ``` -You will answer many questions when running the `init` so webpack CLI can provide the best fitting configuration. +You will be prompted for some questions about what how you want to generate your config file when running the `init` command so webpack CLI can provide the best fitting configuration. ## webpack CLI Scaffolds -With v3 of webpack CLI, we introduced scaffolding as an integral part of the CLI. Our goal is to simplify the creation of webpack configurations for different purposes. Additionally, sharing such solutions with the community is beneficial and with webpack webpack's we want to allow this. We provide `webpack-scaffold` as a utility suite for creating these scaffolds. It contains functions that could be of use for creating an scaffold yourself. +With v3 of webpack CLI, we introduced scaffolding as an integral part of the CLI. Our goal is to simplify the creation of webpack configurations for different purposes. Additionally, sharing such solutions with the community is beneficial and with webpack we want to allow this. We provide `webpack-scaffold` as a utility suite for creating these scaffolds. It contains functions that could be of use for creating a scaffold yourself. You can read more about [Scaffolding](https://webpack.js.org/guides/scaffolding), learn [How to compose a webpack-scaffold?](https://webpack.js.org/contribute/writing-a-scaffold) or generate one with [webpack-scaffold-starter](https://github.com/rishabh3112/webpack-scaffold-starter). From c1c33aed7f2df128156601a65968052180c438f6 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Tue, 23 Apr 2019 12:26:42 +0530 Subject: [PATCH 22/39] chore: addon generator to async/await (#849) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **What kind of change does this PR introduce?** refactor **Did you add tests for your changes?** yes **If relevant, did you update the documentation?** NA **Summary** * Move async gen to async await. **Does this PR introduce a breaking change?** No **Other information** Not yet --- package-lock.json | 41 +++++++------------------- packages/generators/addon-generator.ts | 9 ++---- 2 files changed, 14 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5af3e7a31cd..f2764863823 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7543,8 +7543,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -7565,14 +7564,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7587,20 +7584,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -7717,8 +7711,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -7730,7 +7723,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7745,7 +7737,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7753,14 +7744,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7779,7 +7768,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -7860,8 +7848,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -7873,7 +7860,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -7959,8 +7945,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -7996,7 +7981,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -8016,7 +8000,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -8060,14 +8043,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/packages/generators/addon-generator.ts b/packages/generators/addon-generator.ts index d81c2d0b378..8099016d584 100644 --- a/packages/generators/addon-generator.ts +++ b/packages/generators/addon-generator.ts @@ -39,12 +39,9 @@ export default function addonGenerator( public copy: (value: string, index: number, array: string[]) => void; public copyTpl: (value: string, index: number, array: string[]) => void; - public prompting(): Promise<{}> { - return this.prompt(prompts).then( - (props: InquirerScaffoldObject): void => { - this.props = props; - } - ); + public async prompting(): Promise { + const scaffoldObject: InquirerScaffoldObject = await this.prompt(prompts); + this.props = scaffoldObject; } public default(): void { From 309cc1c53fce3fa2cead8955f90182a1d99b5841 Mon Sep 17 00:00:00 2001 From: Pranshu Chittora Date: Tue, 23 Apr 2019 13:33:44 +0530 Subject: [PATCH 23/39] docs(contribute): adds table of contents and info about dependencies. (#842) - [x] Adds Table of Contents. - [x] Adds a section about dependencies. **What kind of change does this PR introduce?** Docs **Motivation** - It was getting harder to reach the desired section in the doc. - CI failing while modifying dependency (not committing the `package-lock.json`) Hence everything sorted :tada: --- .github/CONTRIBUTING.md | 290 ++++++++++++++++++++++------------------ 1 file changed, 163 insertions(+), 127 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index cb1991ee88d..c3194a9eadc 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -5,6 +5,34 @@ appreciated and welcomed. If you're planning a new feature or changing the API, please create an issue first. This way we can ensure that your precious work is not in vain. +Table of Contents + +- [Issues](#issues) +- [Your first Contribution](#your-first-contribution) +- [Setup](#setup) + - [Using npm](#using-npm) + - [Using yarn](#using-yarn) +- [Running Tests](#running-tests) + - [Using npm](#using-npm-1) + - [Using yarn](#using-yarn-1) +- [Editor Config](#editor-config) +- [Dependencies](#dependencies) +- [Branching Model](#branching-model) +- [Naming a branch](#naming-a-branch) + - [Features](#features) + - [Fixes](#fixes) +- [Testing](#testing) +- [Pull Requests](#pull-requests) +- [Submitting a good Pull Request](#submitting-a-good-pull-request) +- [Commit message](#commit-message) + - [Commit Message Format](#commit-message-format) +- [Migrate with the CLI](#migrate-with-the-cli) + - [How it's being done](#how-its-being-done) + - [Structure of a transform](#structure-of-a-transform) + - [Further Work](#further-work) +- [Contributor License Agreement](#contributor-license-agreement) +- [Documentation](#documentation) + ## Issues Most of the time, when webpack does not work correctly, it might be a configuration issue. @@ -19,7 +47,7 @@ that include your `webpack.config.js` and relevant files. This way you help othe First of all, you will need to create an issue in Github for the feature or bugfix that you want to work on. When you open a new issue, there will be a template that will be automatically added to the text of the issue, which you would need to fill in. Doing this will help us to understand better what the ticket is about. -After you've created the issue, we will have a look, and provide feedback to your ticket. +After you've created the issue, we will have a look, and provide feedback to your ticket. In case it is a bug that you want to fix, we might help you with background information about the issue, so you can make an informed fix. @@ -27,136 +55,142 @@ In case you are suggesting a new feature, we will match your idea with our curre ## Setup -* Install [Node.js](https://nodejs.org/) if you don't have it already. - *Note: Node 6 or greater would be better for "best results".* -* Fork the **webpack-cli** repo at [https://github.com/webpack/webpack-cli](https://github.com/webpack/webpack-cli). -* `git clone && cd webpack-cli` +- Install [Node.js](https://nodejs.org/) if you don't have it already. + _Note: Node 6 or greater would be better for "best results"._ +- Fork the **webpack-cli** repo at [https://github.com/webpack/webpack-cli](https://github.com/webpack/webpack-cli). +- `git clone && cd webpack-cli` ### Using npm -* Install the dependencies and link them: +- Install the dependencies and link them: - ```bash - npm install - npm link - npm link webpack-cli - ``` + ```bash + npm install + npm link + npm link webpack-cli + ``` -* Bootstrap all the submodules before building for the first time +- Bootstrap all the submodules before building for the first time - ```bash - npm run bootstrap - npm run build - ``` + ```bash + npm run bootstrap + npm run build + ``` ### Using yarn -* If you don't have yarn yet: - - ```bash - npm install -g yarn - ``` - -* Install the dependencies and link them +- If you don't have yarn yet: - ```bash - yarn - yarn link - yarn link webpack-cli - ``` + ```bash + npm install -g yarn + ``` -* Bootstrap all the submodules before building for the first time +- Install the dependencies and link them - ```bash - yarn bootstrap - yarn build - ``` + ```bash + yarn + yarn link + yarn link webpack-cli + ``` +- Bootstrap all the submodules before building for the first time -## Testing + ```bash + yarn bootstrap + yarn build + ``` + +## Running Tests ### Using npm -* Run all the tests with: - - ```bash - npm run test - ``` +- Run all the tests with: + + ```bash + npm run test + ``` -* Run CLI tests with: - - ```bash - npm run test:cli - ``` +- Run CLI tests with: -* Run tests of all packages: - - ```bash - npm run test:packages - ``` + ```bash + npm run test:cli + ``` -* Test a single CLI test case: - - ```bash - npx jest path/to/my-test.js - ``` +- Run tests of all packages: -* You can also install jest globally and run tests without npx: + ```bash + npm run test:packages + ``` - ```bash - npm i -g jest - jest path/to/my-test.js - ``` +- Test a single CLI test case: -* You can run the linters: + ```bash + npx jest path/to/my-test.js + ``` - ```bash - npm run lint - ``` +- You can also install jest globally and run tests without npx: + + ```bash + npm i -g jest + jest path/to/my-test.js + ``` + +- You can run the linters: + + ```bash + npm run lint + ``` ### Using yarn -* Run all the tests with: - - ```bash - yarn test - ``` - -* Run CLI tests with: - - ```bash - yarn test:cli` - ``` - -* Run tests of all packages: - - ```bash - yarn test:packages - ``` - -* Test a single CLI test case: - - ```bash - yarn jest path/to/my-test.js - ``` - -* You can also install jest globally and run tests: - - ```bash - yarn global add jest - jest path/to/my-test.js - ``` - -* You can run the linters: - - ```bash - yarn lint - ``` +- Run all the tests with: + + ```bash + yarn test + ``` + +- Run CLI tests with: + + ```bash + yarn test:cli` + ``` + +- Run tests of all packages: + + ```bash + yarn test:packages + ``` + +- Test a single CLI test case: + + ```bash + yarn jest path/to/my-test.js + ``` + +- You can also install jest globally and run tests: + + ```bash + yarn global add jest + jest path/to/my-test.js + ``` + +- You can run the linters: + + ```bash + yarn lint + ``` + ## Editor Config The [.editorconfig](https://github.com/webpack/webpack-cli/blob/master/.editorconfig) in the root should ensure consistent formatting. Please make sure you've [installed the plugin](http://editorconfig.org/#download) if your text editor needs one. +## Dependencies + +This is a multi-package repository and dependencies are managed using [lerna](https://lerna.js.org/) + +> If you are adding or updating any dependency, please commit the updated `package-lock.json` file. + ## Branching Model We base our branching model on [git flow](http://nvie.com/posts/a-successful-git-branching-model/). Instead of working with a `develop` base branch, we use the `master` branch. We do it to ease the workflow a bit. However, we find that adding prefixes to the branches is useful. @@ -165,15 +199,15 @@ We base our branching model on [git flow](http://nvie.com/posts/a-successful-git Making a branch in your fork for your contribution is helpful in the following ways: -* It allows you to submit more than one contribution in a single PR. -* It allows us to identify what your contribution is about from the branch name. +- It allows you to submit more than one contribution in a single PR. +- It allows us to identify what your contribution is about from the branch name. You will want to checkout the `master` branch locally before creating your new branch. There are two types of branches: -* Feature -* Bugfix +- Feature +- Bugfix ### Features @@ -189,7 +223,7 @@ If you are fixing an existing bug, you can create a branch with the following pr ## Testing -Every bugfix or feature that you submit, needs to be tested. Writing tests for code is very important to prevent future bugs, and help to discover possible new bugs promptly. +Every bugfix or feature that you submit, needs to be tested. Writing tests for the code is very important to prevent future bugs, and help to discover possible new bugs promptly. It is important that you test the logic of the code you're writing, and that your tests really go through all your lines, branches and statements. This is the only way to ensure that the code coverage is high enough to ensure the users of the cli, that they are using a solid tool. @@ -204,11 +238,11 @@ In case you've got a small change in most of the cases, your pull request would ## Submitting a good Pull Request -* Write tests -* Follow the existing coding style -* Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) +- Write tests +- Follow the existing coding style +- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) -## Commit message format +## Commit message Our commit messages format follows the [angular.js commits format](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format). @@ -217,10 +251,11 @@ You can use `npm run commit` script to have an interactive way of making commits We don't use the scope. The template of a commit would look like this: ### Commit Message Format -Each commit message consists of a **header**, a **body** and a **footer**. The header has a special + +Each commit message consists of a **header**, a **body** and a **footer**. The header has a special format that includes a **type** and a **subject**: -``` +```md : @@ -228,16 +263,17 @@ format that includes a **type** and a **subject**: