diff --git a/bin/cli.js b/bin/cli.js index a61730e6c7e..b5d8f9ecccd 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -16,16 +16,6 @@ require("v8-compile-cache"); - // try local module, fallback to global - try { - require.resolve("webpack"); - process.webpackModule = require("webpack"); - } catch (err) { - const globalPathToWebpack = require("global-modules-path").getPath( - "webpack" - ); - process.webpackModule = require(globalPathToWebpack); - } const ErrorHelpers = require("./errorHelpers"); const NON_COMPILATION_ARGS = [ @@ -298,7 +288,7 @@ For more information, see https://webpack.js.org/api/cli/.`); } const firstOptions = [].concat(options)[0]; - const statsPresetToOptions = process.webpackModule.Stats.presetToOptions; + const statsPresetToOptions = require("webpack").Stats.presetToOptions; let outputOptions = options.stats; if ( @@ -443,7 +433,7 @@ For more information, see https://webpack.js.org/api/cli/.`); outputOptions.buildDelimiter = value; }); - const webpack = process.webpackModule; + const webpack = require("webpack"); let lastHash = null; let compiler; @@ -464,7 +454,7 @@ For more information, see https://webpack.js.org/api/cli/.`); } if (argv.progress) { - const ProgressPlugin = process.webpackModule.ProgressPlugin; + const ProgressPlugin = require("webpack").ProgressPlugin; new ProgressPlugin({ profile: argv.profile }).apply(compiler); diff --git a/bin/convert-argv.js b/bin/convert-argv.js index 7059f9442f5..82fe87a410e 100644 --- a/bin/convert-argv.js +++ b/bin/convert-argv.js @@ -4,9 +4,9 @@ fs.existsSync = fs.existsSync || path.existsSync; const interpret = require("interpret"); const prepareOptions = require("./prepareOptions"); const webpackConfigurationSchema = require("./webpackConfigurationSchema.json"); -const validateSchema = process.webpackModule.validateSchema; -const WebpackOptionsValidationError = - process.webpackModule.WebpackOptionsValidationError; +const validateSchema = require("webpack").validateSchema; +const WebpackOptionsValidationError = require("webpack") + .WebpackOptionsValidationError; module.exports = function(...args) { const argv = args[1] || args[0]; @@ -398,7 +398,7 @@ module.exports = function(...args) { defineObject = {}; }, function() { - const DefinePlugin = process.webpackModule.DefinePlugin; + const DefinePlugin = require("webpack").DefinePlugin; addPlugin(options, new DefinePlugin(defineObject)); } ); @@ -468,13 +468,13 @@ module.exports = function(...args) { mapArgToBoolean("cache"); ifBooleanArg("hot", function() { - const HotModuleReplacementPlugin = - process.webpackModule.HotModuleReplacementPlugin; + const HotModuleReplacementPlugin = require("webpack") + .HotModuleReplacementPlugin; addPlugin(options, new HotModuleReplacementPlugin()); }); ifBooleanArg("debug", function() { - const LoaderOptionsPlugin = process.webpackModule.LoaderOptionsPlugin; + const LoaderOptionsPlugin = require("webpack").LoaderOptionsPlugin; addPlugin( options, new LoaderOptionsPlugin({ @@ -510,8 +510,8 @@ module.exports = function(...args) { }); ifArg("optimize-max-chunks", function(value) { - const LimitChunkCountPlugin = - process.webpackModule.optimize.LimitChunkCountPlugin; + const LimitChunkCountPlugin = require("webpack").optimize + .LimitChunkCountPlugin; addPlugin( options, new LimitChunkCountPlugin({ @@ -521,8 +521,7 @@ module.exports = function(...args) { }); ifArg("optimize-min-chunk-size", function(value) { - const MinChunkSizePlugin = - process.webpackModule.optimize.MinChunkSizePlugin; + const MinChunkSizePlugin = require("webpack").optimize.MinChunkSizePlugin; addPlugin( options, new MinChunkSizePlugin({ @@ -532,7 +531,7 @@ module.exports = function(...args) { }); ifBooleanArg("optimize-minimize", function() { - const LoaderOptionsPlugin = process.webpackModule.LoaderOptionsPlugin; + const LoaderOptionsPlugin = require("webpack").LoaderOptionsPlugin; addPlugin( options, new LoaderOptionsPlugin({ @@ -542,7 +541,7 @@ module.exports = function(...args) { }); ifArg("prefetch", function(request) { - const PrefetchPlugin = process.webpackModule.PrefetchPlugin; + const PrefetchPlugin = require("webpack").PrefetchPlugin; addPlugin(options, new PrefetchPlugin(request)); }); @@ -555,7 +554,7 @@ module.exports = function(...args) { } else { name = value; } - const ProvidePlugin = process.webpackModule.ProvidePlugin; + const ProvidePlugin = require("webpack").ProvidePlugin; addPlugin(options, new ProvidePlugin(name, value)); }); diff --git a/docs/AddGenerator.html b/docs/AddGenerator.html new file mode 100644 index 00000000000..e9eaa995c79 --- /dev/null +++ b/docs/AddGenerator.html @@ -0,0 +1,201 @@ + + + + + JSDoc: Class: AddGenerator + + + + + + + + + + +
+ +

Class: AddGenerator

+ + + + + + +
+ +
+ +

AddGenerator() → {Void}

+ + +
+ +
+
+ + + + + + +

new AddGenerator() → {Void}

+ + + + + + +
+ Generator for adding properties +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ After execution, transforms are triggered +
+ + + +
+
+ Type +
+
+ +Void + + +
+
+ + + + + + + + +
+ + +

Extends

+ + + + +
    +
  • Generator
  • +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/InitGenerator.html b/docs/InitGenerator.html new file mode 100644 index 00000000000..62b1c584cfd --- /dev/null +++ b/docs/InitGenerator.html @@ -0,0 +1,201 @@ + + + + + JSDoc: Class: InitGenerator + + + + + + + + + + +
+ +

Class: InitGenerator

+ + + + + + +
+ +
+ +

InitGenerator() → {Void}

+ + +
+ +
+
+ + + + + + +

new InitGenerator() → {Void}

+ + + + + + +
+ Generator for initializing a webpack config +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ After execution, transforms are triggered +
+ + + +
+
+ Type +
+
+ +Void + + +
+
+ + + + + + + + +
+ + +

Extends

+ + + + +
    +
  • Generator
  • +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/LoaderGenerator.html b/docs/LoaderGenerator.html new file mode 100644 index 00000000000..0733f3e11d6 --- /dev/null +++ b/docs/LoaderGenerator.html @@ -0,0 +1,181 @@ + + + + + JSDoc: Class: LoaderGenerator + + + + + + + + + + +
+ +

Class: LoaderGenerator

+ + + + + + +
+ +
+ +

LoaderGenerator()

+ + +
+ +
+
+ + + + + + +

new LoaderGenerator()

+ + + + + + +
+ A yeoman generator class for creating a webpack +loader project. It adds some starter loader code +and runs `webpack-defaults`. +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + +

Extends

+ + + + +
    +
  • Generator
  • +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/PluginGenerator.html b/docs/PluginGenerator.html new file mode 100644 index 00000000000..7f6ac28a5f1 --- /dev/null +++ b/docs/PluginGenerator.html @@ -0,0 +1,181 @@ + + + + + JSDoc: Class: PluginGenerator + + + + + + + + + + +
+ +

Class: PluginGenerator

+ + + + + + +
+ +
+ +

PluginGenerator()

+ + +
+ +
+
+ + + + + + +

new PluginGenerator()

+ + + + + + +
+ A yeoman generator class for creating a webpack +plugin project. It adds some starter plugin code +and runs `webpack-defaults`. +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + +

Extends

+ + + + +
    +
  • Generator
  • +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/add_index.js.html b/docs/add_index.js.html new file mode 100644 index 00000000000..34586de947e --- /dev/null +++ b/docs/add_index.js.html @@ -0,0 +1,67 @@ + + + + + JSDoc: Source: add/index.js + + + + + + + + + + +
+ +

Source: add/index.js

+ + + + + + +
+
+
"use strict";
+
+const defaultGenerator = require("@webpack-cli/generators/add-generator");
+const modifyHelper = require("@webpack-cli/utils/modify-config-helper");
+
+/**
+ * Is called and returns a scaffolding instance, adding properties
+ *
+ * @returns {Function} modifyHelper - A helper function that uses the action
+ * 	we're given on a generator
+ *
+ */
+
+module.exports = function add() {
+	return modifyHelper("add", defaultGenerator);
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/fonts/OpenSans-Bold-webfont.eot b/docs/fonts/OpenSans-Bold-webfont.eot new file mode 100644 index 00000000000..5d20d916338 Binary files /dev/null and b/docs/fonts/OpenSans-Bold-webfont.eot differ diff --git a/docs/fonts/OpenSans-Bold-webfont.svg b/docs/fonts/OpenSans-Bold-webfont.svg new file mode 100644 index 00000000000..3ed7be4bc5b --- /dev/null +++ b/docs/fonts/OpenSans-Bold-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Bold-webfont.woff b/docs/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 00000000000..1205787b0ed Binary files /dev/null and b/docs/fonts/OpenSans-Bold-webfont.woff differ diff --git a/docs/fonts/OpenSans-BoldItalic-webfont.eot b/docs/fonts/OpenSans-BoldItalic-webfont.eot new file mode 100644 index 00000000000..1f639a15ff3 Binary files /dev/null and b/docs/fonts/OpenSans-BoldItalic-webfont.eot differ diff --git a/docs/fonts/OpenSans-BoldItalic-webfont.svg b/docs/fonts/OpenSans-BoldItalic-webfont.svg new file mode 100644 index 00000000000..6a2607b9daf --- /dev/null +++ b/docs/fonts/OpenSans-BoldItalic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-BoldItalic-webfont.woff b/docs/fonts/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 00000000000..ed760c0628b Binary files /dev/null and b/docs/fonts/OpenSans-BoldItalic-webfont.woff differ diff --git a/docs/fonts/OpenSans-Italic-webfont.eot b/docs/fonts/OpenSans-Italic-webfont.eot new file mode 100644 index 00000000000..0c8a0ae06ed Binary files /dev/null and b/docs/fonts/OpenSans-Italic-webfont.eot differ diff --git a/docs/fonts/OpenSans-Italic-webfont.svg b/docs/fonts/OpenSans-Italic-webfont.svg new file mode 100644 index 00000000000..e1075dcc246 --- /dev/null +++ b/docs/fonts/OpenSans-Italic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Italic-webfont.woff b/docs/fonts/OpenSans-Italic-webfont.woff new file mode 100644 index 00000000000..ff652e64356 Binary files /dev/null and b/docs/fonts/OpenSans-Italic-webfont.woff differ diff --git a/docs/fonts/OpenSans-Light-webfont.eot b/docs/fonts/OpenSans-Light-webfont.eot new file mode 100644 index 00000000000..14868406aa7 Binary files /dev/null and b/docs/fonts/OpenSans-Light-webfont.eot differ diff --git a/docs/fonts/OpenSans-Light-webfont.svg b/docs/fonts/OpenSans-Light-webfont.svg new file mode 100644 index 00000000000..11a472ca8a5 --- /dev/null +++ b/docs/fonts/OpenSans-Light-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Light-webfont.woff b/docs/fonts/OpenSans-Light-webfont.woff new file mode 100644 index 00000000000..e786074813a Binary files /dev/null and b/docs/fonts/OpenSans-Light-webfont.woff differ diff --git a/docs/fonts/OpenSans-LightItalic-webfont.eot b/docs/fonts/OpenSans-LightItalic-webfont.eot new file mode 100644 index 00000000000..8f445929ffb Binary files /dev/null and b/docs/fonts/OpenSans-LightItalic-webfont.eot differ diff --git a/docs/fonts/OpenSans-LightItalic-webfont.svg b/docs/fonts/OpenSans-LightItalic-webfont.svg new file mode 100644 index 00000000000..431d7e35463 --- /dev/null +++ b/docs/fonts/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,1835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-LightItalic-webfont.woff b/docs/fonts/OpenSans-LightItalic-webfont.woff new file mode 100644 index 00000000000..43e8b9e6cc0 Binary files /dev/null and b/docs/fonts/OpenSans-LightItalic-webfont.woff differ diff --git a/docs/fonts/OpenSans-Regular-webfont.eot b/docs/fonts/OpenSans-Regular-webfont.eot new file mode 100644 index 00000000000..6bbc3cf58cb Binary files /dev/null and b/docs/fonts/OpenSans-Regular-webfont.eot differ diff --git a/docs/fonts/OpenSans-Regular-webfont.svg b/docs/fonts/OpenSans-Regular-webfont.svg new file mode 100644 index 00000000000..25a3952340f --- /dev/null +++ b/docs/fonts/OpenSans-Regular-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/fonts/OpenSans-Regular-webfont.woff b/docs/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 00000000000..e231183dce4 Binary files /dev/null and b/docs/fonts/OpenSans-Regular-webfont.woff differ diff --git a/docs/generate-loader_index.js.html b/docs/generate-loader_index.js.html new file mode 100644 index 00000000000..c276e178f75 --- /dev/null +++ b/docs/generate-loader_index.js.html @@ -0,0 +1,69 @@ + + + + + JSDoc: Source: generate-loader/index.js + + + + + + + + + + +
+ +

Source: generate-loader/index.js

+ + + + + + +
+
+
const yeoman = require("yeoman-environment");
+const { LoaderGenerator } = require("@webpack-cli/generators/loader-generator");
+
+/**
+ * Runs a yeoman generator to create a new webpack loader project
+ * @returns {void}
+ */
+
+function loaderCreator() {
+	const env = yeoman.createEnv();
+	const generatorName = "webpack-loader-generator";
+
+	env.registerStub(LoaderGenerator, generatorName);
+
+	env.run(generatorName);
+}
+
+module.exports = loaderCreator;
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generate-plugin_index.js.html b/docs/generate-plugin_index.js.html new file mode 100644 index 00000000000..a3f6161c41f --- /dev/null +++ b/docs/generate-plugin_index.js.html @@ -0,0 +1,69 @@ + + + + + JSDoc: Source: generate-plugin/index.js + + + + + + + + + + +
+ +

Source: generate-plugin/index.js

+ + + + + + +
+
+
const yeoman = require("yeoman-environment");
+const { PluginGenerator } = require("@webpack-cli/generators/plugin-generator");
+
+/**
+ * Runs a yeoman generator to create a new webpack plugin project
+ * @returns {void}
+ */
+
+function pluginCreator() {
+	const env = yeoman.createEnv();
+	const generatorName = "webpack-plugin-generator";
+
+	env.registerStub(PluginGenerator, generatorName);
+
+	env.run(generatorName);
+}
+
+module.exports = pluginCreator;
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_add-generator.js.html b/docs/generators_add-generator.js.html new file mode 100644 index 00000000000..13651d0bb88 --- /dev/null +++ b/docs/generators_add-generator.js.html @@ -0,0 +1,507 @@ + + + + + JSDoc: Source: generators/add-generator.js + + + + + + + + + + +
+ +

Source: generators/add-generator.js

+ + + + + + +
+
+
const Generator = require("yeoman-generator");
+const glob = require("glob-all");
+const path = require("path");
+const Confirm = require("@webpack-cli/webpack-scaffold").Confirm;
+const List = require("@webpack-cli/webpack-scaffold").List;
+const Input = require("@webpack-cli/webpack-scaffold").Input;
+
+const webpackSchema = require("./utils/optionsSchema.json");
+const webpackDevServerSchema = require("webpack-dev-server/lib/optionsSchema.json");
+const PROP_TYPES = require("@webpack-cli/utils/prop-types");
+
+const getPackageManager = require("@webpack-cli/utils/package-manager")
+	.getPackageManager;
+const npmExists = require("@webpack-cli/utils/npm-exists");
+const entryQuestions = require("./utils/entry");
+
+/**
+ *
+ * Replaces the string with a substring at the given index
+ * https://gist.github.com/efenacigiray/9367920
+ *
+ * @param	{String} string - string to be modified
+ * @param	{Number} index - index to replace from
+ * @param	{String} replace - string to replace starting from index
+ *
+ * @returns	{String} string - The newly mutated string
+ *
+ */
+function replaceAt(string, index, replace) {
+	return string.substring(0, index) + replace + string.substring(index + 1);
+}
+
+/**
+ *
+ * Checks if the given array has a given property
+ *
+ * @param	{Array} arr - array to check
+ * @param	{String} prop - property to check existence of
+ *
+ * @returns	{Boolean} hasProp - Boolean indicating if the property
+ * is present
+ */
+const traverseAndGetProperties = (arr, prop) => {
+	let hasProp = false;
+	arr.forEach(p => {
+		if (p[prop]) {
+			hasProp = true;
+		}
+	});
+	return hasProp;
+};
+
+/**
+ *
+ * Generator for adding properties
+ * @class	AddGenerator
+ * @extends	Generator
+ * @returns	{Void} After execution, transforms are triggered
+ *
+ */
+
+module.exports = class AddGenerator extends Generator {
+	constructor(args, opts) {
+		super(args, opts);
+		this.dependencies = [];
+		this.configuration = {
+			config: {
+				webpackOptions: {},
+				topScope: ["const webpack = require('webpack')"]
+			}
+		};
+	}
+
+	prompting() {
+		let done = this.async();
+		let action;
+		let self = this;
+		let manualOrListInput = action =>
+			Input("actionAnswer", `What do you want to add to ${action}?`);
+
+		// first index indicates if it has a deep prop, 2nd indicates what kind of
+		let isDeepProp = [false, false];
+
+		return this.prompt([
+			List(
+				"actionType",
+				"What property do you want to add to?",
+				Array.from(PROP_TYPES.keys())
+			)
+		])
+			.then(actionTypeAnswer => {
+				// 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(() => {
+				if (action === "entry") {
+					return this.prompt([
+						Confirm("entryType", "Will your application have multiple bundles?")
+					])
+						.then(entryTypeAnswer => {
+							// Ask different questions for entry points
+							return entryQuestions(self, entryTypeAnswer);
+						})
+						.then(entryOptions => {
+							this.configuration.config.webpackOptions.entry = entryOptions;
+							this.configuration.config.item = action;
+						});
+				}
+				let temp = action;
+				if (action === "resolveLoader") {
+					action = "resolve";
+				}
+				const webpackSchemaProp = 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 = webpackSchemaProp
+					? webpackSchemaProp.properties
+					: webpackSchema.properties[action].properties
+						? webpackSchema.properties[action].properties
+						: webpackSchema.properties[action].anyOf
+							? webpackSchema.properties[action].anyOf.filter(
+								p => p.properties || p.enum
+							  ) // eslint-disable-line
+							: null;
+				if (Array.isArray(defOrPropDescription)) {
+					// Todo: Generalize these to go through the array, then merge enum with props if needed
+					const hasPropertiesProp = traverseAndGetProperties(
+						defOrPropDescription,
+						"properties"
+					);
+					const hasEnumProp = 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 = defOrPropDescription[0].enum;
+						// Array -> Object -> Merge objects into one for compat in manualOrListInput
+						defOrPropDescription = Object.keys(defOrPropDescription[0].enum)
+							.map(p => {
+								return Object.assign(
+									{},
+									{
+										[originalPropDesc[p]]: "noop"
+									}
+								);
+							})
+							.reduce((result, currentObject) => {
+								for (let 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 =
+					action === "devServer" ? webpackDevServerSchema : null;
+				// Watch has a boolean arg, but we need to append to it manually
+				if (action === "watch") {
+					defOrPropDescription = {
+						true: {},
+						false: {}
+					};
+				}
+				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, {
+								eval: {},
+								"cheap-eval-source-map": {},
+								"cheap-module-eval-source-map": {},
+								"eval-source-map": {},
+								"cheap-source-map": {},
+								"cheap-module-source-map": {},
+								"inline-cheap-source-map": {},
+								"inline-cheap-module-source-map": {},
+								"source-map": {},
+								"inline-source-map": {},
+								"hidden-source-map": {},
+								"nosources-source-map": {}
+							});
+						}
+						manualOrListInput = 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: {}
+							}
+						);
+						manualOrListInput = 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
+						manualOrListInput = manualOrListInput(action);
+					}
+				} else {
+					manualOrListInput = manualOrListInput(action);
+				}
+				return this.prompt([manualOrListInput]);
+			})
+			.then(answerToAction => {
+				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 = glob
+						.sync([
+							"node_modules/webpack/lib/*Plugin.js",
+							"node_modules/webpack/lib/**/*Plugin.js"
+						])
+						.map(p =>
+							p
+								.split("/")
+								.pop()
+								.replace(".js", "")
+						)
+						.find(
+							p => p.toLowerCase().indexOf(answerToAction.actionAnswer) >= 0
+						);
+					if (pluginExist) {
+						this.configuration.config.item = pluginExist;
+						const pluginsSchemaPath = glob
+							.sync([
+								"node_modules/webpack/schemas/plugins/*Plugin.json",
+								"node_modules/webpack/schemas/plugins/**/*Plugin.json"
+							])
+							.find(
+								p =>
+									p
+										.split("/")
+										.pop()
+										.replace(".json", "")
+										.toLowerCase()
+										.indexOf(answerToAction.actionAnswer) >= 0
+							);
+						if (pluginsSchemaPath) {
+							const constructorPrefix =
+								pluginsSchemaPath.indexOf("optimize") >= 0
+									? "webpack.optimize"
+									: "webpack";
+							const resolvePluginsPath = path.resolve(pluginsSchemaPath);
+							const pluginSchema = resolvePluginsPath
+								? require(resolvePluginsPath)
+								: null;
+							let pluginsSchemaProps = ["other"];
+							if (pluginSchema) {
+								Object.keys(pluginSchema)
+									.filter(p => Array.isArray(pluginSchema[p]))
+									.forEach(p => {
+										Object.keys(pluginSchema[p]).forEach(n => {
+											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 => {
+								return this.prompt([
+									Input(
+										"pluginsPropTypeVal",
+										`What value should ${pluginExist}.${
+											pluginsPropAnswer.pluginsPropType
+										} have?`
+									)
+								]).then(valForProp => {
+									this.configuration.config.webpackOptions[action] = {
+										[`${constructorPrefix}.${pluginExist}`]: {
+											[pluginsPropAnswer.pluginsPropType]:
+												valForProp.pluginsPropTypeVal
+										}
+									};
+									done();
+								});
+							});
+						} else {
+							this.configuration.config.webpackOptions[
+								action
+							] = `new webpack.${pluginExist}`;
+							done();
+						}
+					} else {
+						// If its not in webpack, check npm
+						npmExists(answerToAction.actionAnswer).then(p => {
+							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.runInstall(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 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 => {
+								// The other option needs to be validated of either being empty or not
+								if (isDeepProp[1] === "other") {
+									let othersDeepPropKey = 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("deepProp", othersDeepPropKey)]).then(
+										deepPropAns => {
+											// 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] =
+													deepPropAns.deepProp;
+											} 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]]: deepPropAns.deepProp
+												};
+											}
+											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();
+					}
+				}
+			});
+	}
+
+	writing() {
+		this.config.set("configuration", this.configuration);
+	}
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_addon-generator.js.html b/docs/generators_addon-generator.js.html new file mode 100644 index 00000000000..31acff7232c --- /dev/null +++ b/docs/generators_addon-generator.js.html @@ -0,0 +1,128 @@ + + + + + JSDoc: Source: generators/addon-generator.js + + + + + + + + + + +
+ +

Source: generators/addon-generator.js

+ + + + + + +
+
+
const path = require("path");
+const mkdirp = require("mkdirp");
+const Generator = require("yeoman-generator");
+const copyUtils = require("@webpack-cli/utils/copy-utils");
+
+/**
+ * Creates a Yeoman Generator that generates a project conforming
+ * to webpack-defaults.
+ *
+ * @param {any[]} prompts An array of Yeoman prompt objects
+ *
+ * @param {string} templateDir Absolute path to template directory
+ *
+ * @param {string[]} copyFiles An array of file paths (relative to `./templates`)
+ * of files to be copied to the generated project. File paths should be of the
+ * form `path/to/file.js.tpl`.
+ *
+ * @param {string[]} copyTemplateFiles An array of file paths (relative to
+ * `./templates`) of files to be copied to the generated project. Template
+ * file paths should be of the form `path/to/_file.js.tpl`.
+ *
+ * @param {Function} templateFn A function that is passed a generator instance and
+ * returns an object containing data to be supplied to the template files.
+ *
+ * @returns {Generator} A class extending Generator
+ */
+function addonGenerator(
+	prompts,
+	templateDir,
+	copyFiles,
+	copyTemplateFiles,
+	templateFn
+) {
+	//eslint-disable-next-line
+	return class extends Generator {
+		prompting() {
+			return this.prompt(prompts).then(props => {
+				this.props = props;
+			});
+		}
+
+		default() {
+			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);
+				const pathToProjectDir = this.destinationPath(this.props.name);
+				this.destinationRoot(pathToProjectDir);
+			}
+		}
+
+		writing() {
+			this.copy = copyUtils.generatorCopy(this, templateDir);
+			this.copyTpl = copyUtils.generatorCopyTpl(
+				this,
+				templateDir,
+				templateFn(this)
+			);
+
+			copyFiles.forEach(this.copy);
+			copyTemplateFiles.forEach(this.copyTpl);
+		}
+
+		install() {
+			this.npmInstall(["webpack-defaults", "bluebird"], {
+				"save-dev": true
+			}).then(() => {
+				this.spawnCommand("npm", ["run", "defaults"]);
+			});
+		}
+	};
+}
+
+module.exports = addonGenerator;
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_init-generator.js.html b/docs/generators_init-generator.js.html new file mode 100644 index 00000000000..3776e41be0e --- /dev/null +++ b/docs/generators_init-generator.js.html @@ -0,0 +1,471 @@ + + + + + JSDoc: Source: generators/init-generator.js + + + + + + + + + + +
+ +

Source: generators/init-generator.js

+ + + + + + +
+
+
"use strict";
+
+const Generator = require("yeoman-generator");
+const chalk = require("chalk");
+const logSymbols = require("log-symbols");
+
+const Input = require("@webpack-cli/webpack-scaffold").Input;
+const Confirm = require("@webpack-cli/webpack-scaffold").Confirm;
+const List = require("@webpack-cli/webpack-scaffold").List;
+
+const getPackageManager = require("@webpack-cli/utils/package-manager")
+	.getPackageManager;
+
+const entryQuestions = require("./utils/entry");
+const getBabelPlugin = require("./utils/module");
+const getDefaultPlugins = require("./utils/plugins");
+const tooltip = require("./utils/tooltip");
+
+/**
+ *
+ * Generator for initializing a webpack config
+ *
+ * @class 	InitGenerator
+ * @extends Generator
+ * @returns {Void} After execution, transforms are triggered
+ *
+ */
+module.exports = class InitGenerator extends Generator {
+	constructor(args, opts) {
+		super(args, opts);
+		this.isProd = false;
+		(this.usingDefaults = false),
+		(this.dependencies = [
+			"webpack",
+			"webpack-cli",
+			"uglifyjs-webpack-plugin",
+			"babel-plugin-syntax-dynamic-import"
+		]);
+		this.configuration = {
+			config: {
+				webpackOptions: {},
+				topScope: []
+			}
+		};
+	}
+
+	prompting() {
+		const done = this.async();
+		const self = this;
+		let regExpForStyles;
+		let ExtractUseProps;
+		let outputPath = "dist";
+		process.stdout.write(
+			"\n" +
+				logSymbols.info +
+				chalk.blue(" INFO ") +
+				"For more information and a detailed description of each question, have a look at " +
+				chalk.bold.green(
+					"https://github.com/webpack/webpack-cli/blob/master/INIT.md"
+				) +
+				"\n"
+		);
+		process.stdout.write(
+			logSymbols.info +
+				chalk.blue(" INFO ") +
+				"Alternatively, run `webpack(-cli) --help` for usage info." +
+				"\n\n"
+		);
+		this.configuration.config.webpackOptions.module = {
+			rules: []
+		};
+		this.configuration.config.webpackOptions.plugins = getDefaultPlugins();
+		this.configuration.config.topScope.push(
+			"const webpack = require('webpack')",
+			"const path = require('path')",
+			"\n"
+		);
+
+		this.prompt([
+			Confirm("entryType", "Will your application have multiple bundles?")
+		])
+			.then(entryTypeAnswer => {
+				// Ask different questions for entry points
+				return entryQuestions(self, entryTypeAnswer);
+			})
+			.then(entryOptions => {
+				if (entryOptions !== "\"\"") {
+					this.configuration.config.webpackOptions.entry = entryOptions;
+				}
+				return this.prompt([
+					Input(
+						"outputType",
+						"Which folder will your generated bundles be in? [default: dist]:"
+					)
+				]);
+			})
+			.then(outputTypeAnswer => {
+				// 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 = {
+						filename: "'[name].[chunkhash].js'",
+						chunkFilename: "'[name].[chunkhash].js'"
+					};
+				} else if (!this.usingDefaults) {
+					this.configuration.config.webpackOptions.output = {
+						filename: "'[name].[chunkhash].js'"
+					};
+				}
+				if (outputTypeAnswer["outputType"].length) {
+					outputPath = outputTypeAnswer["outputType"];
+				}
+				if (!this.usingDefaults) {
+					this.configuration.config.webpackOptions.output.path = `path.resolve(__dirname, '${outputPath}')`;
+				}
+			})
+			.then(() => {
+				console.log(this.usingDefaults);
+				this.isProd = this.usingDefaults ? true : false;
+				this.configuration.config.configName = this.isProd ? "prod" : "dev";
+				this.configuration.config.webpackOptions.mode = this.isProd
+					? "'production'"
+					: "'development'";
+				return this.prompt([
+					Confirm("babelConfirm", "Will you be using ES2015?")
+				]);
+			})
+			.then(babelConfirmAnswer => {
+				if (babelConfirmAnswer["babelConfirm"] === true) {
+					this.configuration.config.webpackOptions.module.rules.push(
+						getBabelPlugin()
+					);
+					this.dependencies.push(
+						"babel-core",
+						"babel-loader",
+						"babel-preset-env"
+					);
+				}
+			})
+			.then(() => {
+				return this.prompt([
+					List("stylingType", "Will you use one of the below CSS solutions?", [
+						"SASS",
+						"LESS",
+						"CSS",
+						"PostCSS",
+						"No"
+					])
+				]);
+			})
+			.then(stylingTypeAnswer => {
+				ExtractUseProps = [];
+				switch (stylingTypeAnswer["stylingType"]) {
+					case "SASS":
+						this.dependencies.push(
+							"sass-loader",
+							"node-sass",
+							"style-loader",
+							"css-loader"
+						);
+						regExpForStyles = `${new RegExp(/\.(scss|css)$/)}`;
+						if (this.isProd) {
+							ExtractUseProps.push(
+								{
+									loader: "'css-loader'",
+									options: {
+										sourceMap: true
+									}
+								},
+								{
+									loader: "'sass-loader'",
+									options: {
+										sourceMap: true
+									}
+								}
+							);
+						} else {
+							ExtractUseProps.push(
+								{
+									loader: "'style-loader'"
+								},
+								{
+									loader: "'css-loader'"
+								},
+								{
+									loader: "'sass-loader'"
+								}
+							);
+						}
+						break;
+					case "LESS":
+						regExpForStyles = `${new RegExp(/\.(less|css)$/)}`;
+						this.dependencies.push(
+							"less-loader",
+							"less",
+							"style-loader",
+							"css-loader"
+						);
+						if (this.isProd) {
+							ExtractUseProps.push(
+								{
+									loader: "'css-loader'",
+									options: {
+										sourceMap: true
+									}
+								},
+								{
+									loader: "'less-loader'",
+									options: {
+										sourceMap: true
+									}
+								}
+							);
+						} else {
+							ExtractUseProps.push(
+								{
+									loader: "'css-loader'",
+									options: {
+										sourceMap: true
+									}
+								},
+								{
+									loader: "'less-loader'",
+									options: {
+										sourceMap: true
+									}
+								}
+							);
+						}
+						break;
+					case "PostCSS":
+						this.configuration.config.topScope.push(
+							tooltip.postcss(),
+							"const autoprefixer = require('autoprefixer');",
+							"const precss = require('precss');",
+							"\n"
+						);
+						this.dependencies.push(
+							"style-loader",
+							"css-loader",
+							"postcss-loader",
+							"precss",
+							"autoprefixer"
+						);
+						regExpForStyles = `${new RegExp(/\.css$/)}`;
+						if (this.isProd) {
+							ExtractUseProps.push(
+								{
+									loader: "'css-loader'",
+									options: {
+										sourceMap: true,
+										importLoaders: 1
+									}
+								},
+								{
+									loader: "'postcss-loader'",
+									options: {
+										plugins: `function () {
+											return [
+												precss,
+												autoprefixer
+											];
+										}`
+									}
+								}
+							);
+						} else {
+							ExtractUseProps.push(
+								{
+									loader: "'style-loader'"
+								},
+								{
+									loader: "'css-loader'",
+									options: {
+										sourceMap: true,
+										importLoaders: 1
+									}
+								},
+								{
+									loader: "'postcss-loader'",
+									options: {
+										plugins: `function () {
+											return [
+												precss,
+												autoprefixer
+											];
+										}`
+									}
+								}
+							);
+						}
+						break;
+					case "CSS":
+						this.dependencies.push("style-loader", "css-loader");
+						regExpForStyles = `${new RegExp(/\.css$/)}`;
+						if (this.isProd) {
+							ExtractUseProps.push({
+								loader: "'css-loader'",
+								options: {
+									sourceMap: true
+								}
+							});
+						} else {
+							ExtractUseProps.push(
+								{
+									loader: "'style-loader'",
+									options: {
+										sourceMap: true
+									}
+								},
+								{
+									loader: "'css-loader'"
+								}
+							);
+						}
+						break;
+					default:
+						regExpForStyles = null;
+				}
+			})
+			.then(() => {
+				if (this.isProd) {
+					// Ask if the user wants to use extractPlugin
+					return this.prompt([
+						Input(
+							"extractPlugin",
+							"If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)"
+						)
+					]);
+				}
+			})
+			.then(extractPluginAnswer => {
+				if (regExpForStyles) {
+					if (this.isProd) {
+						const cssBundleName = 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' })"
+							);
+						}
+
+						ExtractUseProps.unshift({
+							loader: "MiniCssExtractPlugin.loader"
+						});
+
+						const moduleRulesObj = {
+							test: regExpForStyles,
+							use: ExtractUseProps
+						};
+
+						this.configuration.config.webpackOptions.module.rules.push(
+							moduleRulesObj
+						);
+						this.configuration.config.topScope.push(
+							"const MiniCssExtractPlugin = require('mini-css-extract-plugin');",
+							"\n"
+						);
+					} else {
+						const moduleRulesObj = {
+							test: regExpForStyles,
+							use: ExtractUseProps
+						};
+
+						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: {
+						chunks: "'async'",
+						minSize: 30000,
+						minChunks: 1,
+						// for production name is recommended to be off
+						name: !this.isProd,
+						cacheGroups: {
+							vendors: {
+								test: "/[\\\\/]node_modules[\\\\/]/",
+								priority: -10
+							}
+						}
+					}
+				};
+				done();
+			});
+	}
+	installPlugins() {
+		if (this.isProd) {
+			this.dependencies = this.dependencies.filter(
+				p => p !== "uglifyjs-webpack-plugin"
+			);
+		} else {
+			this.configuration.config.topScope.push(
+				tooltip.uglify(),
+				"const UglifyJSPlugin = require('uglifyjs-webpack-plugin');",
+				"\n"
+			);
+		}
+		const packager = getPackageManager();
+		const opts = packager === "yarn" ? { dev: true } : { "save-dev": true };
+		this.runInstall(packager, this.dependencies, opts);
+	}
+	writing() {
+		this.config.set("configuration", this.configuration);
+	}
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_loader-generator.js.html b/docs/generators_loader-generator.js.html new file mode 100644 index 00000000000..c0a49d9c569 --- /dev/null +++ b/docs/generators_loader-generator.js.html @@ -0,0 +1,110 @@ + + + + + JSDoc: Source: generators/loader-generator.js + + + + + + + + + + +
+ +

Source: generators/loader-generator.js

+ + + + + + +
+
+
const path = require("path");
+const _ = require("lodash");
+const addonGenerator = require("./addon-generator");
+
+/**
+ * Formats a string into webpack loader format
+ * (eg: 'style-loader', 'raw-loader')
+ *
+ * @param {string} name A loader name to be formatted
+ * @returns {string} The formatted string
+ */
+function makeLoaderName(name) {
+	name = _.kebabCase(name);
+	if (!/loader$/.test(name)) {
+		name += "-loader";
+	}
+	return name;
+}
+
+/**
+ * A yeoman generator class for creating a webpack
+ * loader project. It adds some starter loader code
+ * and runs `webpack-defaults`.
+ *
+ * @class LoaderGenerator
+ * @extends {Generator}
+ */
+
+const LoaderGenerator = addonGenerator(
+	[
+		{
+			type: "input",
+			name: "name",
+			message: "Loader name",
+			default: "my-loader",
+			filter: makeLoaderName,
+			validate: str => str.length > 0
+		}
+	],
+	path.resolve(__dirname, "..", "generate-loader"),
+	[
+		"src/cjs.js.tpl",
+		"test/test-utils.js.tpl",
+		"test/unit.test.js.tpl",
+		"test/functional.test.js.tpl",
+		"test/fixtures/simple-file.js.tpl",
+		"examples/simple/webpack.config.js.tpl",
+		"examples/simple/src/index.js.tpl",
+		"examples/simple/src/lazy-module.js.tpl",
+		"examples/simple/src/static-esm-module.js.tpl"
+	],
+	["src/_index.js.tpl"],
+	gen => ({ name: gen.props.name })
+);
+
+module.exports = {
+	makeLoaderName,
+	LoaderGenerator
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_plugin-generator.js.html b/docs/generators_plugin-generator.js.html new file mode 100644 index 00000000000..f0c70dfa6a2 --- /dev/null +++ b/docs/generators_plugin-generator.js.html @@ -0,0 +1,90 @@ + + + + + JSDoc: Source: generators/plugin-generator.js + + + + + + + + + + +
+ +

Source: generators/plugin-generator.js

+ + + + + + +
+
+
const path = require("path");
+const _ = require("lodash");
+const addonGenerator = require("./addon-generator");
+
+/**
+ * A yeoman generator class for creating a webpack
+ * plugin project. It adds some starter plugin code
+ * and runs `webpack-defaults`.
+ *
+ * @class PluginGenerator
+ * @extends {Generator}
+ */
+const PluginGenerator = addonGenerator(
+	[
+		{
+			type: "input",
+			name: "name",
+			message: "Plugin name",
+			default: "my-webpack-plugin",
+			filter: _.kebabCase,
+			validate: str => str.length > 0
+		}
+	],
+	path.resolve(__dirname, "..", "generate-plugin"),
+	[
+		"src/cjs.js.tpl",
+		"test/test-utils.js.tpl",
+		"test/functional.test.js.tpl",
+		"examples/simple/src/index.js.tpl",
+		"examples/simple/src/lazy-module.js.tpl",
+		"examples/simple/src/static-esm-module.js.tpl"
+	],
+	["src/_index.js.tpl", "examples/simple/_webpack.config.js.tpl"],
+	gen => ({ name: _.upperFirst(_.camelCase(gen.props.name)) })
+);
+
+module.exports = {
+	PluginGenerator
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_utils_entry.js.html b/docs/generators_utils_entry.js.html new file mode 100644 index 00000000000..08ca6e5713f --- /dev/null +++ b/docs/generators_utils_entry.js.html @@ -0,0 +1,151 @@ + + + + + JSDoc: Source: generators/utils/entry.js + + + + + + + + + + +
+ +

Source: generators/utils/entry.js

+ + + + + + +
+
+
"use strict";
+
+const InputValidate = require("@webpack-cli/webpack-scaffold").InputValidate;
+const validate = require("./validate");
+
+/**
+ *
+ * Prompts for entry points, either if it has multiple or one entry
+ *
+ * @param	{Object} self 	- A variable holding the instance of the prompting
+ * @param	{Object} answer - Previous answer from asking if the user wants single or multiple entries
+ * @returns	{Object} An Object that holds the answers given by the user, later used to scaffold
+ */
+
+module.exports = (self, answer) => {
+	let entryIdentifiers;
+	let result;
+	if (answer["entryType"] === true) {
+		result = self
+			.prompt([
+				InputValidate(
+					"multipleEntries",
+					"Type the names you want for your modules (entry files), separated by comma [example: app,vendor]",
+					validate
+				)
+			])
+			.then(multipleEntriesAnswer => {
+				let webpackEntryPoint = {};
+				entryIdentifiers = multipleEntriesAnswer["multipleEntries"].split(",");
+				function forEachPromise(obj, fn) {
+					return obj.reduce((promise, prop) => {
+						const trimmedProp = prop.trim();
+						return promise.then(n => {
+							if (n) {
+								Object.keys(n).forEach(val => {
+									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 =>
+					self.prompt([
+						InputValidate(
+							`${entryProp}`,
+							`What is the location of "${entryProp}"? [example: ./src/${entryProp}]`,
+							validate
+						)
+					])
+				).then(entryPropAnswer => {
+					Object.keys(entryPropAnswer).forEach(val => {
+						if (
+							entryPropAnswer[val].charAt(0) !== "(" &&
+							entryPropAnswer[val].charAt(0) !== "[" &&
+							!entryPropAnswer[val].includes("function") &&
+							!entryPropAnswer[val].includes("path") &&
+							!entryPropAnswer[val].includes("process")
+						) {
+							entryPropAnswer[val] = `\'${entryPropAnswer[val]
+								.replace(/"|'/g, "")
+								.concat(".js")}\'`;
+						}
+						webpackEntryPoint[val] = entryPropAnswer[val];
+					});
+					return webpackEntryPoint;
+				});
+			});
+	} else {
+		result = self
+			.prompt([
+				InputValidate(
+					"singularEntry",
+					"Which module will be the first to enter the application? [default: ./src/index]"
+				)
+			])
+			.then(singularEntryAnswer => {
+				let { singularEntry } = singularEntryAnswer;
+				if (singularEntry.indexOf("\"") >= 0) {
+					singularEntry = singularEntry.replace(/"/g, "'");
+				}
+				if (singularEntry.length <= 0) {
+					self.usingDefaults = true;
+				}
+				return singularEntry;
+			});
+	}
+	return result;
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_utils_module.js.html b/docs/generators_utils_module.js.html new file mode 100644 index 00000000000..446d85cbee2 --- /dev/null +++ b/docs/generators_utils_module.js.html @@ -0,0 +1,73 @@ + + + + + JSDoc: Source: generators/utils/module.js + + + + + + + + + + +
+ +

Source: generators/utils/module.js

+ + + + + + +
+
+
"use strict";
+
+/**
+ *
+ * Returns an module.rule object that has the babel loader if invoked
+ *
+ * @param {Void} _ - void value
+ * @returns {Function} A callable function that adds the babel-loader with env preset
+ */
+module.exports = _ => {
+	return {
+		test: `${new RegExp(/\.js$/)}`,
+		include: ["path.resolve(__dirname, 'src')"],
+		loader: "'babel-loader'",
+		options: {
+			presets: ["'env'", {
+				modules: false
+			}],
+			plugins: ["'syntax-dynamic-import'"]
+		}
+	};
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_utils_plugins.js.html b/docs/generators_utils_plugins.js.html new file mode 100644 index 00000000000..74f60b78a56 --- /dev/null +++ b/docs/generators_utils_plugins.js.html @@ -0,0 +1,65 @@ + + + + + JSDoc: Source: generators/utils/plugins.js + + + + + + + + + + +
+ +

Source: generators/utils/plugins.js

+ + + + + + +
+
+
"use strict";
+
+/**
+ *
+ * Callable function with the initial plugins
+ *
+ * @param {Void} _ - void value
+ * @returns {Function} An function that returns an array
+ * that consists of the uglify plugin
+ */
+
+module.exports = _ => {
+	return ["new UglifyJSPlugin()"];
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_utils_tooltip.js.html b/docs/generators_utils_tooltip.js.html new file mode 100644 index 00000000000..167ef35b8f1 --- /dev/null +++ b/docs/generators_utils_tooltip.js.html @@ -0,0 +1,111 @@ + + + + + JSDoc: Source: generators/utils/tooltip.js + + + + + + + + + + +
+ +

Source: generators/utils/tooltip.js

+ + + + + + +
+
+
"use strict";
+/**
+ *
+ * Tooltip object that consists of tooltips for various of
+ * features
+ *
+ * @returns {Object} An Object that consists of tooltip methods to be invoked
+ */
+
+module.exports = {
+	uglify: _ => {
+		return `/*
+ * We've enabled UglifyJSPlugin for you! This minifies your app
+ * in order to load faster and run less javascript.
+ *
+ * https://github.com/webpack-contrib/uglifyjs-webpack-plugin
+ *
+ */`;
+	},
+	splitChunks: _ => {
+		return `/*
+ * SplitChunksPlugin is enabled by default and replaced
+ * deprecated CommonsChunkPlugin. It automatically identifies modules which
+ * should be splitted of chunk by heuristics using module duplication count and
+ * module category (i. e. node_modules). And splits the chunks…
+ *
+ * It is safe to remove "splitChunks" from the generated configuration
+ * and was added as an educational example.
+ *
+ * https://webpack.js.org/plugins/split-chunks-plugin/
+ *
+ */`;
+	},
+	cssPlugin: _ => {
+		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
+ * one of your module entries!
+ *
+ * https://github.com/webpack-contrib/mini-css-extract-plugin
+ *
+ */`;
+	},
+	postcss: _ => {
+		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,
+ * inline images, and more!
+ *
+ * To enable SASS or LESS, add the respective loaders to module.rules
+ *
+ * https://github.com/postcss/postcss
+ *
+ * https://github.com/postcss/autoprefixer
+ *
+ * https://github.com/jonathantneal/precss
+ *
+ */`;
+	}
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/generators_utils_validate.js.html b/docs/generators_utils_validate.js.html new file mode 100644 index 00000000000..17697e0e485 --- /dev/null +++ b/docs/generators_utils_validate.js.html @@ -0,0 +1,68 @@ + + + + + JSDoc: Source: generators/utils/validate.js + + + + + + + + + + +
+ +

Source: generators/utils/validate.js

+ + + + + + +
+
+
"use strict";
+
+/**
+ *
+ * Validates an input to check if an input is provided
+ *
+ * @param {String} value - The input string to validate
+ * @returns {String | Boolean } Returns truthy if its long enough
+ * Or a string if the user hasn't written anything
+ */
+module.exports = value => {
+	const pass = value.length;
+	if (pass) {
+		return true;
+	}
+	return "Please specify an answer!";
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/global.html b/docs/global.html new file mode 100644 index 00000000000..6b0ccebdd9a --- /dev/null +++ b/docs/global.html @@ -0,0 +1,8211 @@ + + + + + JSDoc: Global + + + + + + + + + + +
+ +

Global

+ + + + + + +
+ +
+ +

+ + +
+ +
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

addonGenerator(prompts, templateDir, copyFiles, copyTemplateFiles, templateFn) → {Generator}

+ + + + + + +
+ Creates a Yeoman Generator that generates a project conforming +to webpack-defaults. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
prompts + + +Array.<any> + + + + An array of Yeoman prompt objects
templateDir + + +string + + + + Absolute path to template directory
copyFiles + + +Array.<string> + + + + An array of file paths (relative to `./templates`) +of files to be copied to the generated project. File paths should be of the +form `path/to/file.js.tpl`.
copyTemplateFiles + + +Array.<string> + + + + An array of file paths (relative to +`./templates`) of files to be copied to the generated project. Template +file paths should be of the form `path/to/_file.js.tpl`.
templateFn + + +function + + + + A function that is passed a generator instance and +returns an object containing data to be supplied to the template files.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ A class extending Generator +
+ + + +
+
+ Type +
+
+ +Generator + + +
+
+ + + + + + + + + + + + + +

addOrUpdateConfigObject(j, rootNode, configProperty, key, value) → {Void}

+ + + + + + +
+ Adds or updates the value of a key within a root +webpack configuration property that's of type Object. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
rootNode + + +Node + + + + node of root webpack configuration
configProperty + + +String + + + + key of an Object webpack configuration property
key + + +String + + + + key within the configuration object to update
value + + +Object + + + + the value to set for the key
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Void + + +
+
+ + + + + + + + + + + + + +

addProperty(j, p, key, value, action) → {Node}

+ + + + + + +
+ Recursively adds an object/property to a node +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
p + + +Node + + + + AST node
key + + +String + + + + key of a key/val object
value + + +Any + + + + Any type of object
action + + +String + + + + Action to be done on the given ast
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ - the created ast +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

createIdentifierOrLiteral(j, val) → {Node}

+ + + + + + +
+ Creates an appropriate identifier or literal property +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
val + + +String +| + +Boolean +| + +Number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

createLiteral(j, val) → {Node}

+ + + + + + +
+ Creates an appropriate literal property +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
val + + +String +| + +Boolean +| + +Number + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

createOrUpdatePluginByName(j, rootNodePath, pluginName, options) → {Void}

+ + + + + + +
+ Finds or creates a node for a given plugin name string with options object +If plugin declaration already exist, options are merged. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
rootNodePath + + +Node + + + + `plugins: []` NodePath where plugin should be added. See https://github.com/facebook/jscodeshift/wiki/jscodeshift-Documentation#nodepaths
pluginName + + +String + + + + ex. `webpack.LoaderOptionsPlugin`
options + + +Object + + + + plugin options
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Void + + +
+
+ + + + + + + + + + + + + +

createProperty(j, key, value) → {Node}

+ + + + + + +
+ Creates an Object's property with a given key and value +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
key + + +String +| + +Number + + + + Property key
value + + +String +| + +Number +| + +Boolean + + + + Property value
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

defineTest(dirName, transformName, testFilePrefixopt, transformObject, action) → {Void}

+ + + + + + +
+ Handles some boilerplate around defining a simple jest/Jasmine test for a +jscodeshift transform. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
dirName + + +String + + + + + + + + + + contains the name of the directory the test is located in. This + should normally be passed via __dirname.
transformName + + +String + + + + + + + + + + contains the filename of the transform being tested, + excluding the .js extension.
testFilePrefix + + +String + + + + + + <optional>
+ + + + + +
Optionally contains the name of the file with the test + data. If not specified, it defaults to the same value as `transformName`. + This will be suffixed with ".input.js" for the input file and ".output.js" + for the expected output. For example, if set to "foo", we will read the + "foo.input.js" file, pass this to the transform, and expect its output to + be equal to the contents of "foo.output.js".
transformObject + + +any + + + + + + + + + + Object to be transformed with the transformations
action + + +String + + + + + + + + + + init, update or remove, decides how to format the AST
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ Jest makes sure to execute the globally defined functions +
+ + + +
+
+ Type +
+
+ +Void + + +
+
+ + + + + + + + + + + + + +

findAndRemovePluginByName(j, node, pluginName) → {Node|Void}

+ + + + + + +
+ Finds and removes a node for a given plugin name. If the plugin +is the last in the plugins array, the array is also removed. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
node + + +Node + + + + node to start search from
pluginName + + +String + + + + name of the plugin to remove
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ - path to the root webpack configuration object if plugin is found +
+ + + +
+
+ Type +
+
+ +Node +| + +Void + + +
+
+ + + + + + + + + + + + + +

findInvocation(j, node, pluginName) → {Boolean}

+ + + + + + +
+ Check whether `node` is the invocation of the plugin denoted by `pluginName` +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +Object + + + + jscodeshift top-level import
node + + +Node + + + + ast node to check
pluginName + + +String + + + + name of the plugin
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ isPluginInvocation - whether `node` is the invocation of the plugin denoted by `pluginName` +
+ + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + + + + + + + + + + +

findPluginsArrayAndRemoveIfEmpty(j, rootNode) → {Node}

+ + + + + + +
+ It lookouts for the plugins property and, if the array is empty, it removes it from the AST +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + jscodeshift API
rootNode + + +Node + + + + node to start search from
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ rootNode modified AST. +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

findPluginsByName(j, node, pluginNamesArray) → {Node}

+ + + + + + +
+ Find paths that match `new name.space.PluginName()` for a +given array of plugin names +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
node + + +Node + + + + Node to start search from
pluginNamesArray + + +Array.<String> + + + + Array of plugin names like `webpack.LoaderOptionsPlugin`
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ Node that has the pluginName +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

findRootNodesByName(j, node, propName) → {Node}

+ + + + + + +
+ Finds the path to the `name: []` node +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
node + + +Node + + + + Node to start search from
propName + + +String + + + + property to search for
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ found node and +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

findVariableToPlugin(j, rootNode, pluginPackageName) → {String}

+ + + + + + +
+ Finds the variable to which a third party plugin is assigned to +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
rootNode + + +Node + + + + `plugins: []` Root Node. See https://github.com/facebook/jscodeshift/wiki/jscodeshift-Documentation#nodepaths
pluginPackageName + + +String + + + + ex. `extract-text-plugin`
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ variable name - ex. 'const s = require(s) gives "s"` +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +

generatorCopy(generator, templateDir) → {function}

+ + + + + + +
+ Takes in a file path in the `./templates` directory. Copies that +file to the destination, with the `.tpl` extension stripped. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
generator + + +Generator + + + + A Yeoman Generator instance
templateDir + + +string + + + + Absolute path to template directory
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ A curried function that takes a file path and copies it +
+ + + +
+
+ Type +
+
+ +function + + +
+
+ + + + + + + + + + + + + +

generatorCopyTpl(generator, templateDir, templateData) → {function}

+ + + + + + +
+ Takes in a file path in the `./templates` directory. Copies that +file to the destination, with the `.tpl` extension and `_` prefix +stripped. Passes `this.props` to the template. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
generator + + +Generator + + + + A Yeoman Generator instance
templateDir + + +string + + + + Absolute path to template directory
templateData + + +any + + + + An object containing the data passed to +the template files.
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ A curried function that takes a file path and copies it +
+ + + +
+
+ Type +
+
+ +function + + +
+
+ + + + + + + + + + + + + +

getPackageManager() → {String}

+ + + + + + +
+ Returns the name of package manager to use, +preferring yarn over npm if available +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ - The package manager name +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +

getPathToGlobalPackages() → {String}

+ + + + + + +
+ Returns the path to globally installed +npm packages, depending on the available +package manager determined by `getPackageManager` +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ path - Path to global node_modules folder +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +

getRequire(j, constName, packagePath) → {Node}

+ + + + + + +
+ Returns constructed require symbol +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + +any + + + + — jscodeshift API
constName + + +String + + + + Name of require
packagePath + + +String + + + + path of required package
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ - the created ast +
+ + + +
+
+ Type +
+
+ +Node + + +
+
+ + + + + + + + + + + + + +

getRootPathModule(dep) → {String}

+ + + + + + +
+ Find the path of a given module +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
dep + + +Object + + + + dependency to find
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ string with given path +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +

isType(path, type) → {Boolean}

+ + + + + + +
+ Returns true if type is given type +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
path + + +Node + + + + AST node
type + + +String + + + + node type
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + + + + + + + + + + +

loaderCreator() → {void}

+ + + + + + +
+ Runs a yeoman generator to create a new webpack loader project +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + + + + + + +

makeLoaderName(name) → {string}

+ + + + + + +
+ Formats a string into webpack loader format +(eg: 'style-loader', 'raw-loader') +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
name + + +string + + + + A loader name to be formatted
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ The formatted string +
+ + + +
+
+ Type +
+
+ +string + + +
+
+ + + + + + + + + + + + + +

mapOptionsToTransform(transformObject, config) → {Object}

+ + + + + + +
+ Maps back transforms that needs to be run using the configuration +provided. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
transformObject + + +Object + + + + An Object with all transformations
config + + +Object + + + + Configuration to transform
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ - An Object with the transformations to be run +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

mapOptionsToTransform(transformObject, config) → {Object}

+ + + + + + +
+ Maps back transforms that needs to be run using the configuration +provided. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
transformObject + + +Object + + + + An Object with all transformations
config + + +Object + + + + Configuration to transform
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ - An Object with the transformations to be run +
+ + + +
+
+ Type +
+
+ +Object + + +
+
+ + + + + + + + + + + + + +

parseMerge(j, ast, value, action)

+ + + + + + +
+ Transform for merge. Finds the merge property from yeoman and creates a way +for users to allow webpack-merge in their scaffold +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + — jscodeshift API
ast + + jscodeshift API
value + + +any + + + + transformation object to scaffold
action + + +String + + + + action that indicates what to be done to the AST
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ ast - jscodeshift API +
+ + + + + + + + + + + + + + + +

parseTopScope(j, ast, value, action)

+ + + + + + +
+ Get an property named topScope from yeoman and inject it to the top scope of +the config, outside module.exports +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
j + + — jscodeshift API
ast + + jscodeshift API
value + + +any + + + + transformation object to scaffold
action + + +String + + + + action that indicates what to be done to the AST
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ ast - jscodeshift API +
+ + + + + + + + + + + + + + + +

pluginCreator() → {void}

+ + + + + + +
+ Runs a yeoman generator to create a new webpack plugin project +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +void + + +
+
+ + + + + + + + + + + + + +

processPromise(child) → {Promise}

+ + + + + + +
+ Attaches a promise to the installation of the package +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
child + + +function + + + + The function to attach a promise to
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ promise - Returns a promise to the installation +
+ + + +
+
+ Type +
+
+ +Promise + + +
+
+ + + + + + + + + + + + + +

replaceAt(string, index, replace) → {String}

+ + + + + + +
+ Replaces the string with a substring at the given index +https://gist.github.com/efenacigiray/9367920 +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
string + + +String + + + + string to be modified
index + + +Number + + + + index to replace from
replace + + +String + + + + string to replace starting from index
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ string - The newly mutated string +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +

resolvePackages(pkg) → {function|Error}

+ + + + + + +
+ Resolves and installs the packages, later sending them to @creator +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
pkg + + +Array.<String> + + + + The dependencies to be installed
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ creator - Builds +a webpack configuration through yeoman or throws an error +
+ + + +
+
+ Type +
+
+ +function +| + +Error + + +
+
+ + + + + + + + + + + + + +

runMigration(currentConfigPath, outputConfigPath) → {Promise}

+ + + + + + +
+ Runs migration on a given configuration using AST's and promises +to sequentially transform a configuration file. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
currentConfigPath + + +String + + + + input path for config
outputConfigPath + + +String + + + + output path for config
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ Runs the migration using a promise that +will throw any errors during each transform or output if the +user decides to abort the migration +
+ + + +
+
+ Type +
+
+ +Promise + + +
+
+ + + + + + + + + + + + + +

runSingleTransform(dirName, transformName, testFilePrefixopt, initOptions, action) → {function}

+ + + + + + +
+ Utility function to run a jscodeshift script within a unit test. +This makes several assumptions about the environment. + +Notes: +- The test should be located in a subdirectory next to the transform itself. + Commonly tests are located in a directory called __tests__. + +- Test data should be located in a directory called __testfixtures__ + alongside the transform and __tests__ directory. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
dirName + + +String + + + + + + + + + + contains the name of the directory the test is located in. This + should normally be passed via __dirname.
transformName + + +String + + + + + + + + + + contains the filename of the transform being tested, + excluding the .js extension.
testFilePrefix + + +String + + + + + + <optional>
+ + + + + +
Optionally contains the name of the file with the test + data. If not specified, it defaults to the same value as `transformName`. + This will be suffixed with ".input.js" for the input file and ".output.js" + for the expected output. For example, if set to "foo", we will read the + "foo.input.js" file, pass this to the transform, and expect its output to + be equal to the contents of "foo.output.js".
initOptions + + +Object +| + +Boolean +| + +String + + + + + + + + + + TBD
action + + +String + + + + + + + + + + init, update or remove, decides how to format the AST
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ Function that fires of the transforms +
+ + + +
+
+ Type +
+
+ +function + + +
+
+ + + + + + + + + + + + + +

safeTraverse(obj, paths) → {Any}

+ + + + + + +
+ Traverse safely over a path object for array for paths +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
obj + + +Object + + + + Object on which we traverse
paths + + +Array + + + + Array of strings containing the traversal path
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ Value at given traversal path +
+ + + +
+
+ Type +
+
+ +Any + + +
+
+ + + + + + + + + + + + + +

safeTraverseAndGetType(path) → {String|Boolean}

+ + + + + + +
+ Traverse safely and return `type` for path object with value.value property +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
path + + +Node + + + + AST node
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ type at given path. +
+ + + +
+
+ Type +
+
+ +String +| + +Boolean + + +
+
+ + + + + + + + + + + + + +

serve(args) → {function}

+ + + + + + +
+ Prompts for installing the devServer and running it +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
args + + +Object + + + + args processed from the CLI
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ invokes the devServer API +
+ + + +
+
+ Type +
+
+ +function + + +
+
+ + + + + + + + + + + + + +

spawnChild(pkg) → {function}

+ + + + + + +
+ Spawns a new process that installs the addon/dependency +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
pkg + + +String + + + + The dependency to be installed
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ spawn - Installs the package +
+ + + +
+
+ Type +
+
+ +function + + +
+
+ + + + + + + + + + + + + +

spawnNPM(pkg, isNew) → {function}

+ + + + + + +
+ Spawns a new process using npm +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
pkg + + +String + + + + The dependency to be installed
isNew + + +Boolean + + + + indicates if it needs to be updated or installed
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ spawn - Installs the package +
+ + + +
+
+ Type +
+
+ +function + + +
+
+ + + + + + + + + + + + + +

spawnNPMWithArg(cmd) → {Void}

+ + + + + + +
+ Installs WDS using NPM with --save --dev etc +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
cmd + + +Object + + + + arg to spawn with
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Void + + +
+
+ + + + + + + + + + + + + +

spawnYarn(pkg, isNew) → {function}

+ + + + + + +
+ Spawns a new process using yarn +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
pkg + + +String + + + + The dependency to be installed
isNew + + +Boolean + + + + indicates if it needs to be updated or installed
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ spawn - Installs the package +
+ + + +
+
+ Type +
+
+ +function + + +
+
+ + + + + + + + + + + + + +

spawnYarnWithArg(cmd) → {Void}

+ + + + + + +
+ Installs WDS using Yarn with add etc +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
cmd + + +Object + + + + arg to spawn with
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + + + +
+
+ Type +
+
+ +Void + + +
+
+ + + + + + + + + + + + + +

transform(source, transformsopt, optionsopt) → {String}

+ + + + + + +
+ Transforms a given piece of source code by applying selected transformations to the AST. +By default, transforms a webpack version 1 configuration file into a webpack version 2 +configuration file. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeAttributesDescription
source + + +String + + + + + + + + + + source file contents
transforms + + +Array.<function()> + + + + + + <optional>
+ + + + + +
List of transformation functions, defined in the +order to apply them in. By default, all defined transformations.
options + + +Object + + + + + + <optional>
+ + + + + +
recast formatting options
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ source — transformed source code +
+ + + +
+
+ Type +
+
+ +String + + +
+
+ + + + + + + + + + + + + +

traverseAndGetProperties(arr, prop) → {Boolean}

+ + + + + + +
+ Checks if the given array has a given property +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
arr + + +Array + + + + array to check
prop + + +String + + + + property to check existence of
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + +
Returns:
+ + +
+ hasProp - Boolean indicating if the property +is present +
+ + + +
+
+ Type +
+
+ +Boolean + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000000..2be970804a7 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,65 @@ + + + + + JSDoc: Home + + + + + + + + + + +
+ +

Home

+ + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/info_index.js.html b/docs/info_index.js.html new file mode 100644 index 00000000000..cc7937aa8cf --- /dev/null +++ b/docs/info_index.js.html @@ -0,0 +1,70 @@ + + + + + JSDoc: Source: info/index.js + + + + + + + + + + +
+ +

Source: info/index.js

+ + + + + + +
+
+
"use strict";
+
+const envinfo = require("envinfo");
+
+/**
+ * Prints debugging information for webpack issue reporting
+ */
+
+module.exports = function info() {
+	console.log(
+		envinfo.run({
+			System: ["OS", "CPU"],
+			Binaries: ["Node", "Yarn", "npm"],
+			Browsers: ["Chrome", "Firefox", "Safari"],
+			npmPackages: "*webpack*",
+			npmGlobalPackages: ["webpack", "webpack-cli"]
+		})
+	);
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/init_index.js.html b/docs/init_index.js.html new file mode 100644 index 00000000000..27a6ab76063 --- /dev/null +++ b/docs/init_index.js.html @@ -0,0 +1,76 @@ + + + + + JSDoc: Source: init/index.js + + + + + + + + + + +
+ +

Source: init/index.js

+ + + + + + +
+
+
"use strict";
+
+const npmPackagesExists = require("@webpack-cli/utils/npm-packages-exists");
+const defaultGenerator = require("@webpack-cli/generators/init-generator");
+const modifyHelper = require("@webpack-cli/utils/modify-config-helper");
+
+/**
+ *
+ * First function to be called after running the init flag. This is a check,
+ * if we are running the init command with no arguments or if we got dependencies
+ *
+ * @param	{Array}		args - array of arguments such as
+ * packages included when running the init command
+ * @returns	{Function}	creator/npmPackagesExists - returns an installation of the package,
+ * followed up with a yeoman instance of that if there's packages. If not, it creates a defaultGenerator
+ */
+
+module.exports = function initializeInquirer(...args) {
+	const packages = args.slice(3);
+
+	if (packages.length === 0) {
+		return modifyHelper("init", defaultGenerator);
+	}
+	return npmPackagesExists(packages);
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/init_init.js.html b/docs/init_init.js.html new file mode 100644 index 00000000000..ee693609ccb --- /dev/null +++ b/docs/init_init.js.html @@ -0,0 +1,145 @@ + + + + + JSDoc: Source: init/init.js + + + + + + + + + + +
+ +

Source: init/init.js

+ + + + + + +
+
+
"use strict";
+
+const path = require("path");
+const j = require("jscodeshift");
+const chalk = require("chalk");
+const pEachSeries = require("p-each-series");
+
+const runPrettier = require("@webpack-cli/utils/run-prettier");
+const astTransform = require("@webpack-cli/utils/recursive-parser");
+const propTypes = require("@webpack-cli/utils/prop-types");
+
+/**
+ *
+ * Maps back transforms that needs to be run using the configuration
+ * provided.
+ *
+ * @param	{Object} transformObject 	- An Object with all transformations
+ * @param	{Object} config 			- Configuration to transform
+ * @returns {Object} - An Object with the transformations to be run
+ */
+
+function mapOptionsToTransform(config) {
+	return Object.keys(config.webpackOptions).filter(k => propTypes.has(k));
+}
+
+/**
+ *
+ * Runs the transformations from an object we get from yeoman
+ *
+ * @param	{Object} webpackProperties 	- Configuration to transform
+ * @param	{String} action 			- Action to be done on the given ast
+ * @returns {Promise} - A promise that writes each transform, runs prettier
+ * and writes the file
+ */
+
+module.exports = function runTransform(webpackProperties, action) {
+	// webpackOptions.name sent to nameTransform if match
+	const webpackConfig = Object.keys(webpackProperties).filter(p => {
+		return p !== "configFile" && p !== "configPath";
+	});
+	const initActionNotDefined = action && action !== "init" ? true : false;
+
+	webpackConfig.forEach(scaffoldPiece => {
+		const config = webpackProperties[scaffoldPiece];
+		const transformations = mapOptionsToTransform(config);
+		const ast = j(
+			initActionNotDefined
+				? webpackProperties.configFile
+				: "module.exports = {}"
+		);
+		const transformAction = action || null;
+
+		return pEachSeries(transformations, f => {
+			return astTransform(j, ast, config.webpackOptions[f], transformAction, f);
+		})
+			.then(_ => {
+				let configurationName;
+				if (!config.configName) {
+					configurationName = "webpack.config.js";
+				} else {
+					configurationName = "webpack." + config.configName + ".js";
+				}
+
+				const outputPath = initActionNotDefined
+					? webpackProperties.configPath
+					: path.join(process.cwd(), configurationName);
+				const source = ast.toSource({
+					quote: "single"
+				});
+
+				runPrettier(outputPath, source);
+			})
+			.catch(err => {
+				console.error(err.message ? err.message : err);
+			});
+	});
+	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"
+				)
+		);
+	}
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/make_index.js.html b/docs/make_index.js.html new file mode 100644 index 00000000000..eabb34f0444 --- /dev/null +++ b/docs/make_index.js.html @@ -0,0 +1,63 @@ + + + + + JSDoc: Source: make/index.js + + + + + + + + + + +
+ +

Source: make/index.js

+ + + + + + +
+
+
"use strict";
+
+/**
+ * Is called and returns a scaffolding instance, adding properties
+ *
+ * @returns {Function} TBD
+ *
+ */
+
+module.exports = function make() {
+	return console.log("make me");
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_bannerPlugin_bannerPlugin.js.html b/docs/migrate_bannerPlugin_bannerPlugin.js.html new file mode 100644 index 00000000000..ca8ed1a974f --- /dev/null +++ b/docs/migrate_bannerPlugin_bannerPlugin.js.html @@ -0,0 +1,84 @@ + + + + + JSDoc: Source: migrate/bannerPlugin/bannerPlugin.js + + + + + + + + + + +
+ +

Source: migrate/bannerPlugin/bannerPlugin.js

+ + + + + + +
+
+
const utils = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Transform for BannerPlugin arguments. Consolidates first and second argument (if
+ * both are present) into single options object.
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+
+module.exports = function(j, ast) {
+	return utils
+		.findPluginsByName(j, ast, ["webpack.BannerPlugin"])
+		.forEach(path => {
+			const args = path.value.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
+					}
+				);
+			}
+		});
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_extractTextPlugin_extractTextPlugin.js.html b/docs/migrate_extractTextPlugin_extractTextPlugin.js.html new file mode 100644 index 00000000000..6cb8c076275 --- /dev/null +++ b/docs/migrate_extractTextPlugin_extractTextPlugin.js.html @@ -0,0 +1,109 @@ + + + + + JSDoc: Source: migrate/extractTextPlugin/extractTextPlugin.js + + + + + + + + + + +
+ +

Source: migrate/extractTextPlugin/extractTextPlugin.js

+ + + + + + +
+
+
const utils = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Check whether `node` is the invocation of the plugin denoted by `pluginName`
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} node - ast node to check
+ * @param {String} pluginName - name of the plugin
+ * @returns {Boolean} isPluginInvocation - whether `node` is the invocation of the plugin denoted by `pluginName`
+ */
+
+function findInvocation(j, node, pluginName) {
+	let found = false;
+	found =
+		j(node)
+			.find(j.MemberExpression)
+			.filter(p => p.get("object").value.name === pluginName)
+			.size() > 0;
+	return found;
+}
+
+/**
+ *
+ * Transform for ExtractTextPlugin arguments. Consolidates arguments into single options object.
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+
+module.exports = function(j, ast) {
+	const changeArguments = function(p) {
+		const args = p.value.arguments;
+
+		const literalArgs = args.filter(p => utils.isType(p, "Literal"));
+		if (literalArgs && literalArgs.length > 1) {
+			const newArgs = j.objectExpression(
+				literalArgs.map((p, index) =>
+					utils.createProperty(j, index === 0 ? "fallback" : "use", p.value)
+				)
+			);
+			p.value.arguments = [newArgs];
+		}
+		return p;
+	};
+	const name = utils.findVariableToPlugin(
+		j,
+		ast,
+		"extract-text-webpack-plugin"
+	);
+	if (!name) return ast;
+
+	return ast
+		.find(j.CallExpression)
+		.filter(p => findInvocation(j, p, name))
+		.forEach(changeArguments);
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_index.js.html b/docs/migrate_index.js.html new file mode 100644 index 00000000000..bde3b566827 --- /dev/null +++ b/docs/migrate_index.js.html @@ -0,0 +1,255 @@ + + + + + JSDoc: Source: migrate/index.js + + + + + + + + + + +
+ +

Source: migrate/index.js

+ + + + + + +
+
+
"use strict";
+
+const fs = require("fs");
+const path = require("path");
+const chalk = require("chalk");
+const diff = require("diff");
+const inquirer = require("inquirer");
+const PLazy = require("p-lazy");
+const Listr = require("listr");
+
+const { validate } = process.webpackModule;
+const { WebpackOptionsValidationError } = process.webpackModule;
+
+const runPrettier = require("@webpack-cli/utils/run-prettier");
+
+/**
+ *
+ * Runs migration on a given configuration using AST's and promises
+ * to sequentially transform a configuration file.
+ *
+ * @param {Array} args - Migrate arguments such as input and
+ * output path
+ * @returns {Function} Runs the migration using the 'runMigrate'
+ * function.
+ */
+
+module.exports = function migrate(...args) {
+	const filePaths = args.slice(3);
+	if (!filePaths.length) {
+		const errMsg = "\n ✖ Please specify a path to your webpack config \n ";
+		console.error(chalk.red(errMsg));
+		return;
+	}
+	const currentConfigPath = path.resolve(process.cwd(), filePaths[0]);
+	let outputConfigPath;
+	if (!filePaths[1]) {
+		return inquirer
+			.prompt([
+				{
+					type: "confirm",
+					name: "confirmPath",
+					message:
+						"Migration output path not specified. " +
+						"Do you want to use your existing webpack " +
+						"configuration?",
+					default: "Y"
+				}
+			])
+			.then(ans => {
+				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);
+			})
+			.catch(err => {
+				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, outputConfigPath) {
+	const recastOptions = {
+		quote: "single"
+	};
+	const tasks = new Listr([
+		{
+			title: "Reading webpack config",
+			task: ctx =>
+				new PLazy((resolve, reject) => {
+					fs.readFile(currentConfigPath, "utf8", (err, content) => {
+						if (err) {
+							reject(err);
+						}
+						try {
+							const jscodeshift = require("jscodeshift");
+							ctx.source = content;
+							ctx.ast = jscodeshift(content);
+							resolve();
+						} catch (err) {
+							reject("Error generating AST", err);
+						}
+					});
+				})
+		},
+		{
+			title: "Migrating config to newest version",
+			task: ctx => {
+				const transformations = require("./migrate").transformations;
+				return new Listr(
+					Object.keys(transformations).map(key => {
+						const transform = transformations[key];
+						return {
+							title: key,
+							task: _ => transform(ctx.ast, ctx.source)
+						};
+					})
+				);
+			}
+		}
+	]);
+
+	tasks
+		.run()
+		.then(ctx => {
+			const result = ctx.ast.toSource(recastOptions);
+			const diffOutput = diff.diffLines(ctx.source, result);
+			diffOutput.forEach(diffLine => {
+				if (diffLine.added) {
+					process.stdout.write(chalk.green(`+ ${diffLine.value}`));
+				} else if (diffLine.removed) {
+					process.stdout.write(chalk.red(`- ${diffLine.value}`));
+				}
+			});
+			return inquirer
+				.prompt([
+					{
+						type: "confirm",
+						name: "confirmMigration",
+						message: "Are you sure these changes are fine?",
+						default: "Y"
+					}
+				])
+				.then(answers => {
+					if (answers["confirmMigration"]) {
+						return inquirer.prompt([
+							{
+								type: "confirm",
+								name: "confirmValidation",
+								message:
+									"Do you want to validate your configuration? " +
+									"(If you're using webpack merge, validation isn't useful)",
+								default: "Y"
+							}
+						]);
+					} else {
+						console.log(chalk.red("✖ Migration aborted"));
+					}
+				})
+				.then(answer => {
+					if (!answer) return;
+
+					runPrettier(outputConfigPath, result, err => {
+						if (err) {
+							throw err;
+						}
+					});
+
+					if (answer["confirmValidation"]) {
+						const webpackOptionsValidationErrors = validate(
+							require(outputConfigPath)
+						);
+						if (webpackOptionsValidationErrors.length) {
+							console.log(
+								chalk.red(
+									"\n✖ Your configuration validation wasn't successful \n"
+								)
+							);
+							console.error(
+								new WebpackOptionsValidationError(
+									webpackOptionsValidationErrors
+								).message
+							);
+						}
+					}
+					console.log(
+						chalk.green(
+							`\n✔︎ New webpack config file is at ${outputConfigPath}.`
+						)
+					);
+					console.log(
+						chalk.green(
+							"✔︎ Heads up! Updating to the latest version could contain breaking changes."
+						)
+					);
+					console.log(
+						chalk.green(
+							"✔︎ Plugin and loader dependencies may need to be updated."
+						)
+					);
+				});
+		})
+		.catch(err => {
+			const errMsg = "\n ✖ ︎Migration aborted due to some errors: \n";
+			console.error(chalk.red(errMsg));
+			console.error(err);
+			process.exitCode = 1;
+		});
+}
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_loaderOptionsPlugin_loaderOptionsPlugin.js.html b/docs/migrate_loaderOptionsPlugin_loaderOptionsPlugin.js.html new file mode 100644 index 00000000000..453c02d9cb7 --- /dev/null +++ b/docs/migrate_loaderOptionsPlugin_loaderOptionsPlugin.js.html @@ -0,0 +1,100 @@ + + + + + JSDoc: Source: migrate/loaderOptionsPlugin/loaderOptionsPlugin.js + + + + + + + + + + +
+ +

Source: migrate/loaderOptionsPlugin/loaderOptionsPlugin.js

+ + + + + + +
+
+
const isEmpty = require("lodash/isEmpty");
+const findPluginsByName = require("@webpack-cli/utils/ast-utils")
+	.findPluginsByName;
+const createOrUpdatePluginByName = require("@webpack-cli/utils/ast-utils")
+	.createOrUpdatePluginByName;
+const safeTraverse = require("@webpack-cli/utils/ast-utils").safeTraverse;
+
+/**
+ *
+ * Transform which adds context information for old loaders by injecting a `LoaderOptionsPlugin`
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ *
+ */
+
+module.exports = function(j, ast) {
+	const 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 => {
+			p.parent.prune();
+		});
+	}
+
+	// If there is UglifyJsPlugin, set minimize: true
+	if (findPluginsByName(j, ast, ["webpack.optimize.UglifyJsPlugin"]).size()) {
+		loaderOptions.minimize = true;
+	}
+
+	return ast
+		.find(j.ArrayExpression)
+		.filter(
+			path =>
+				safeTraverse(path, ["parent", "value", "key", "name"]) === "plugins"
+		)
+		.forEach(path => {
+			!isEmpty(loaderOptions) &&
+				createOrUpdatePluginByName(
+					j,
+					path,
+					"webpack.LoaderOptionsPlugin",
+					loaderOptions
+				);
+		});
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_loaders_loaders.js.html b/docs/migrate_loaders_loaders.js.html new file mode 100644 index 00000000000..832791e0a30 --- /dev/null +++ b/docs/migrate_loaders_loaders.js.html @@ -0,0 +1,430 @@ + + + + + JSDoc: Source: migrate/loaders/loaders.js + + + + + + + + + + +
+ +

Source: migrate/loaders/loaders.js

+ + + + + + +
+
+
const utils = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Transform for loaders. Transforms pre- and postLoaders into enforce options,
+ * moves loader configuration into rules array, transforms query strings and
+ * props into loader options, and adds -loader suffix to loader names.
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+
+module.exports = function(j, ast) {
+	/**
+	 * Creates an Array expression out of loaders string
+	 *
+	 *
+	 * For syntaxes like
+	 *
+	 * {
+	 *   loader: 'style!css`
+	 * }
+	 *
+	 * or
+	 *
+	 * {
+	 *   loaders: ['style', 'css']
+	 * }
+	 *
+	 * or
+	 *
+	 * loaders: [{
+	 *   loader: 'style'
+	 * },
+	 * {
+	 *   loader: 'css',
+	 * }]
+	 *
+	 * it should generate
+	 *
+	 * {
+	 *   use: [{
+	 *     loader: 'style'
+	 *   },
+	 *   {
+	 *     loader: 'css'
+	 *   }]
+	 * }
+	 *
+	 * @param  {Node} path - object expression ast
+	 * @returns {Node} path - object expression ast with array expression instead of loaders string
+	 */
+
+	const createArrayExpressionFromArray = function(path) {
+		const value = path.value;
+		// Find paths with `loaders` keys in the given Object
+		const paths = value.properties.filter(prop =>
+			prop.key.name.startsWith("loader")
+		);
+		// For each pair of key and value
+		paths.forEach(pair => {
+			// 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 = pair.value;
+				pair.value = j.arrayExpression(
+					pairValue.elements.map(arrElement => {
+						// 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 = pair.value;
+				pair.value = j.arrayExpression(
+					literalValue.value.split("!").map(loader => {
+						return j.objectExpression([
+							utils.createProperty(j, "loader", loader)
+						]);
+					})
+				);
+			}
+		});
+		return path;
+	};
+
+	/**
+	 *
+	 * Puts query parameters from loader value into options object
+	 *
+	 * @param {Node} p - object expression ast for loader object
+	 * @returns {Node} objectExpression - an new object expression ast containing the query parameters
+	 */
+
+	const createLoaderWithQuery = p => {
+		let properties = p.value.properties;
+		let loaderValue = properties.reduce(
+			(val, prop) => (prop.key.name === "loader" ? prop.value.value : val),
+			""
+		);
+		let loader = loaderValue.split("?")[0];
+		let query = loaderValue.split("?")[1];
+		let options = query.split("&").map(option => {
+			const param = option.split("=");
+			const key = param[0];
+			const val = param[1] || true; // No value in query string means it is truthy value
+			return j.objectProperty(j.identifier(key), utils.createLiteral(j, val));
+		});
+		let loaderProp = utils.createProperty(j, "loader", loader);
+		let queryProp = j.property(
+			"init",
+			j.identifier("options"),
+			j.objectExpression(options)
+		);
+		return j.objectExpression([loaderProp, queryProp]);
+	};
+
+	/**
+	 *
+	 * Determine whether a loader has a query string
+	 *
+	 * @param {Node} p - object expression ast for loader object
+	 * @returns {Boolean} hasLoaderQueryString - whether the loader object contains a query string
+	 */
+
+	const findLoaderWithQueryString = p => {
+		return p.value.properties.reduce((predicate, prop) => {
+			return (
+				(utils.safeTraverse(prop, ["value", "value", "indexOf"]) &&
+					prop.value.value.indexOf("?") > -1) ||
+				predicate
+			);
+		}, false);
+	};
+
+	/**
+	 * Check if the identifier is the `loaders` prop in the `module` object.
+	 * If the path value is `loaders` and it’s located in `module` object
+	 * we assume it’s the loader's section.
+	 *
+	 * @param {Node} path - identifier ast
+	 * @returns {Boolean} isLoadersProp - whether the identifier is the `loaders` prop in the `module` object
+	 */
+
+	const checkForLoader = path =>
+		path.value.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
+	 *
+	 * @param {Node} p - object expression ast that has a key for either 'preLoaders' or 'postLoaders'
+	 * @returns {Node} p - object expression with a `loaders` object and appropriate `enforce` properties
+	 */
+
+	const fitIntoLoaders = p => {
+		let loaders;
+		p.value.properties.map(prop => {
+			const keyName = prop.key.name;
+			if (keyName === "loaders") {
+				loaders = prop.value;
+			}
+		});
+		p.value.properties.map(prop => {
+			const keyName = prop.key.name;
+			if (keyName !== "loaders") {
+				const enforceVal = keyName === "preLoaders" ? "pre" : "post";
+				prop.value.elements.map(elem => {
+					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 => prop.key.name === "loaders"
+			);
+		}
+		return p;
+	};
+
+	/**
+	 * Find pre and postLoaders in the ast and put them into the `loaders` array
+	 *
+	 * @returns {Node} ast - jscodeshift ast
+	 */
+
+	const prepostLoaders = () =>
+		ast
+			.find(j.ObjectExpression)
+			.filter(p => utils.findObjWithOneOfKeys(p, ["preLoaders", "postLoaders"]))
+			.forEach(fitIntoLoaders);
+
+	/**
+	 * Convert top level `loaders` to `rules`
+	 *
+	 * @returns {Node} ast - jscodeshift ast
+	 */
+
+	const loadersToRules = () =>
+		ast
+			.find(j.Identifier)
+			.filter(checkForLoader)
+			.forEach(p => (p.value.name = "rules"));
+
+	/**
+	 * Convert `loader` and `loaders` to Array of {Rule.Use}
+	 *
+	 * @returns {Node} ast - jscodeshift ast
+	 */
+
+	const loadersToArrayExpression = () =>
+		ast
+			.find(j.ObjectExpression)
+			.filter(path => utils.findObjWithOneOfKeys(path, ["loader", "loaders"]))
+			.filter(
+				path =>
+					utils.safeTraverse(path, [
+						"parent",
+						"parent",
+						"node",
+						"key",
+						"name"
+					]) === "rules"
+			)
+			.forEach(createArrayExpressionFromArray);
+
+	/**
+	 * Find loaders with options encoded as a query string and replace the string with an options object
+	 *
+	 * i.e. for loader like
+	 *
+	 * {
+	 *   loader: 'css?modules&importLoaders=1&string=test123'
+	 * }
+	 *
+	 * it should generate
+	 * {
+	 *   loader: 'css-loader',
+	 *   options: {
+	 *     modules: true,
+	 *     importLoaders: 1,
+	 *     string: 'test123'
+	 *   }
+	 * }
+	 *
+	 * @returns {Node} ast - jscodeshift ast
+	 */
+
+	const loaderWithQueryParam = () =>
+		ast
+			.find(j.ObjectExpression)
+			.filter(p => utils.findObjWithOneOfKeys(p, ["loader"]))
+			.filter(findLoaderWithQueryString)
+			.replaceWith(createLoaderWithQuery);
+
+	/**
+	 * Find nodes with a `query` key and replace it with `options`
+	 *
+	 * i.e. for
+	 * {
+	 *   query: { ... }
+	 * }
+	 *
+	 * it should generate
+	 *
+	 * {
+	 *   options: { ... }
+	 * }
+	 *
+	 * @returns {Node} ast - jscodeshift ast
+	 */
+
+	const loaderWithQueryProp = () =>
+		ast
+			.find(j.Identifier)
+			.filter(p => p.value.name === "query")
+			.replaceWith(j.identifier("options"));
+
+	/**
+	 * Add required `-loader` suffix to a loader with missing suffix
+	 * e.g. for `babel` it should generate `babel-loader`
+	 *
+	 * @returns {Node} ast - jscodeshift ast
+	 */
+
+	const addLoaderSuffix = () =>
+		ast.find(j.ObjectExpression).forEach(path => {
+			path.value.properties.forEach(prop => {
+				if (
+					prop.key.name === "loader" &&
+					utils.safeTraverse(prop, ["value", "value"]) &&
+					!prop.value.value.endsWith("-loader")
+				) {
+					prop.value = j.literal(prop.value.value + "-loader");
+				}
+			});
+		});
+
+	/**
+	 *
+	 * Puts options object outside use object into use object
+	 *
+	 * @param {Node} p - object expression ast that has a key for either 'options' or 'use'
+	 * @returns {Node} objectExpression - an use object expression ast containing the options and loader
+	 */
+
+	const fitOptionsToUse = p => {
+		let options;
+		p.value.properties.forEach(prop => {
+			const keyName = prop.key.name;
+			if (keyName === "options") {
+				options = prop;
+			}
+		});
+
+		if (options) {
+			p.value.properties = p.value.properties.filter(
+				prop => prop.key.name !== "options"
+			);
+
+			p.value.properties.forEach(prop => {
+				const keyName = prop.key.name;
+				if (keyName === "use") {
+					prop.value.elements[0].properties.push(options);
+				}
+			});
+		}
+
+		return p;
+	};
+
+	/**
+	 * Move `options` inside the Array of {Rule.Use}
+	 *
+	 * @returns {Node} ast - jscodeshift ast
+	 */
+
+	const moveOptionsToUse = () =>
+		ast
+			.find(j.ObjectExpression)
+			.filter(p => utils.findObjWithOneOfKeys(p, ["use"]))
+			.forEach(fitOptionsToUse);
+
+	const transforms = [
+		prepostLoaders,
+		loadersToRules,
+		loadersToArrayExpression,
+		loaderWithQueryParam,
+		loaderWithQueryProp,
+		addLoaderSuffix,
+		moveOptionsToUse
+	];
+	transforms.forEach(t => t());
+
+	return ast;
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_migrate.js.html b/docs/migrate_migrate.js.html new file mode 100644 index 00000000000..ce6b4361b00 --- /dev/null +++ b/docs/migrate_migrate.js.html @@ -0,0 +1,132 @@ + + + + + JSDoc: Source: migrate/migrate.js + + + + + + + + + + +
+ +

Source: migrate/migrate.js

+ + + + + + +
+
+
const jscodeshift = require("jscodeshift");
+const pEachSeries = require("p-each-series");
+const PLazy = require("p-lazy");
+
+const loadersTransform = require("./loaders/loaders");
+const resolveTransform = require("./resolve/resolve");
+const removeJsonLoaderTransform = require("./removeJsonLoader/removeJsonLoader");
+const uglifyJsPluginTransform = require("./uglifyJsPlugin/uglifyJsPlugin");
+const loaderOptionsPluginTransform = require("./loaderOptionsPlugin/loaderOptionsPlugin");
+const bannerPluginTransform = require("./bannerPlugin/bannerPlugin");
+const extractTextPluginTransform = require("./extractTextPlugin/extractTextPlugin");
+const noEmitOnErrorsPluginTransform = require("./noEmitOnErrorsPlugin/noEmitOnErrorsPlugin");
+const removeDeprecatedPluginsTransform = require("./removeDeprecatedPlugins/removeDeprecatedPlugins");
+
+const transformsObject = {
+	loadersTransform,
+	resolveTransform,
+	removeJsonLoaderTransform,
+	uglifyJsPluginTransform,
+	loaderOptionsPluginTransform,
+	bannerPluginTransform,
+	extractTextPluginTransform,
+	noEmitOnErrorsPluginTransform,
+	removeDeprecatedPluginsTransform
+};
+
+const transformations = Object.keys(transformsObject).reduce((res, key) => {
+	res[key] = (ast, source) =>
+		transformSingleAST(ast, source, transformsObject[key]);
+	return res;
+}, {});
+
+function transformSingleAST(ast, source, transformFunction) {
+	return new PLazy((resolve, reject) => {
+		setTimeout(_ => {
+			try {
+				resolve(transformFunction(jscodeshift, ast, source));
+			} catch (err) {
+				reject(err);
+			}
+		}, 0);
+	});
+}
+
+/**
+ *
+ * Transforms a given piece of source code by applying selected transformations to the AST.
+ * By default, transforms a webpack version 1 configuration file into a webpack version 2
+ * configuration file.
+ *
+ * @param {String} source - source file contents
+ * @param {Function[]} [transforms] - List of transformation functions, defined in the
+ * order to apply them in. By default, all defined transformations.
+ * @param {Object} [options] - recast formatting options
+ * @returns {String} source — transformed source code
+ */
+
+function transform(source, transforms, options) {
+	const ast = jscodeshift(source);
+	const recastOptions = Object.assign(
+		{
+			quote: "single"
+		},
+		options
+	);
+	transforms =
+		transforms || Object.keys(transformations).map(k => transformations[k]);
+	return pEachSeries(transforms, f => f(ast, source))
+		.then(_ => {
+			return ast.toSource(recastOptions);
+		})
+		.catch(err => {
+			console.error(err);
+		});
+}
+
+module.exports = {
+	transform,
+	transformSingleAST,
+	transformations
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_moduleConcatenationPlugin_moduleConcatenationPlugin.js.html b/docs/migrate_moduleConcatenationPlugin_moduleConcatenationPlugin.js.html new file mode 100644 index 00000000000..8b36a0f1772 --- /dev/null +++ b/docs/migrate_moduleConcatenationPlugin_moduleConcatenationPlugin.js.html @@ -0,0 +1,85 @@ + + + + + JSDoc: Source: migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.js + + + + + + + + + + +
+ +

Source: migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.js

+ + + + + + +
+
+
const {
+	addOrUpdateConfigObject,
+	findAndRemovePluginByName
+} = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Transform for NamedModulesPlugin. If found, removes the
+ * plugin and sets optimizations.namedModules to true
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+module.exports = function(j, ast) {
+	// Remove old plugin
+	const root = findAndRemovePluginByName(
+		j,
+		ast,
+		"webpack.optimize.ModuleConcatenationPlugin"
+	);
+
+	// Add new optimizations option
+	root &&
+		addOrUpdateConfigObject(
+			j,
+			root,
+			"optimizations",
+			"concatenateModules",
+			j.booleanLiteral(true)
+		);
+
+	return ast;
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_namedModulesPlugin_namedModulesPlugin.js.html b/docs/migrate_namedModulesPlugin_namedModulesPlugin.js.html new file mode 100644 index 00000000000..8855ee7036e --- /dev/null +++ b/docs/migrate_namedModulesPlugin_namedModulesPlugin.js.html @@ -0,0 +1,81 @@ + + + + + JSDoc: Source: migrate/namedModulesPlugin/namedModulesPlugin.js + + + + + + + + + + +
+ +

Source: migrate/namedModulesPlugin/namedModulesPlugin.js

+ + + + + + +
+
+
const {
+	addOrUpdateConfigObject,
+	findAndRemovePluginByName
+} = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Transform for NamedModulesPlugin. If found, removes the
+ * plugin and sets optimizations.namedModules to true
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+module.exports = function(j, ast) {
+	// Remove old plugin
+	const root = findAndRemovePluginByName(j, ast, "webpack.NamedModulesPlugin");
+
+	// Add new optimizations option
+	root &&
+		addOrUpdateConfigObject(
+			j,
+			root,
+			"optimizations",
+			"namedModules",
+			j.booleanLiteral(true)
+		);
+
+	return ast;
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_noEmitOnErrorsPlugin_noEmitOnErrorsPlugin.js.html b/docs/migrate_noEmitOnErrorsPlugin_noEmitOnErrorsPlugin.js.html new file mode 100644 index 00000000000..43b39c593bb --- /dev/null +++ b/docs/migrate_noEmitOnErrorsPlugin_noEmitOnErrorsPlugin.js.html @@ -0,0 +1,85 @@ + + + + + JSDoc: Source: migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.js + + + + + + + + + + +
+ +

Source: migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.js

+ + + + + + +
+
+
const {
+	addOrUpdateConfigObject,
+	findAndRemovePluginByName
+} = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Transform for NoEmitOnErrorsPlugin. If found, removes the
+ * plugin and sets optimizations.noEmitOnErrors to true
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+module.exports = function(j, ast) {
+	// Remove old plugin
+	const root = findAndRemovePluginByName(
+		j,
+		ast,
+		"webpack.NoEmitOnErrorsPlugin"
+	);
+
+	// Add new optimizations option
+	root &&
+		addOrUpdateConfigObject(
+			j,
+			root,
+			"optimizations",
+			"noEmitOnErrors",
+			j.booleanLiteral(true)
+		);
+
+	return ast;
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_outputPath_outputPath.js.html b/docs/migrate_outputPath_outputPath.js.html new file mode 100644 index 00000000000..302a327051e --- /dev/null +++ b/docs/migrate_outputPath_outputPath.js.html @@ -0,0 +1,125 @@ + + + + + JSDoc: Source: migrate/outputPath/outputPath.js + + + + + + + + + + +
+ +

Source: migrate/outputPath/outputPath.js

+ + + + + + +
+
+
const utils = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Transform which adds `path.join` call to `output.path` literals
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+
+module.exports = function(j, ast) {
+	const literalOutputPath = ast
+		.find(j.ObjectExpression)
+		.filter(
+			p =>
+				utils.safeTraverse(p, ["parentPath", "value", "key", "name"]) ===
+				"output"
+		)
+		.find(j.Property)
+		.filter(
+			p =>
+				utils.safeTraverse(p, ["value", "key", "name"]) === "path" &&
+				utils.safeTraverse(p, ["value", "value", "type"]) === "Literal"
+		);
+
+	if (literalOutputPath) {
+		let pathVarName = "path";
+		let isPathPresent = false;
+		const pathDeclaration = ast
+			.find(j.VariableDeclarator)
+			.filter(
+				p =>
+					utils.safeTraverse(p, ["value", "init", "callee", "name"]) ===
+					"require"
+			)
+			.filter(
+				p =>
+					utils.safeTraverse(p, ["value", "init", "arguments"]) &&
+					p.value.init.arguments.reduce((isPresent, a) => {
+						return (a.type === "Literal" && a.value === "path") || isPresent;
+					}, false)
+			);
+
+		if (pathDeclaration) {
+			isPathPresent = true;
+			pathDeclaration.forEach(p => {
+				pathVarName = utils.safeTraverse(p, ["value", "id", "name"]);
+			});
+		}
+		const finalPathName = pathVarName;
+		literalOutputPath
+			.find(j.Literal)
+			.replaceWith(p => replaceWithPath(j, p, finalPathName));
+
+		if (!isPathPresent) {
+			const pathRequire = utils.getRequire(j, "path", "path");
+			return ast
+				.find(j.Program)
+				.replaceWith(p =>
+					j.program([].concat(pathRequire).concat(p.value.body))
+				);
+		}
+	}
+	return ast;
+};
+
+function replaceWithPath(j, p, pathVarName) {
+	const convertedPath = j.callExpression(
+		j.memberExpression(j.identifier(pathVarName), j.identifier("join"), false),
+		[j.identifier("__dirname"), p.value]
+	);
+	return convertedPath;
+}
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_removeDeprecatedPlugins_removeDeprecatedPlugins.js.html b/docs/migrate_removeDeprecatedPlugins_removeDeprecatedPlugins.js.html new file mode 100644 index 00000000000..4edf84ad47f --- /dev/null +++ b/docs/migrate_removeDeprecatedPlugins_removeDeprecatedPlugins.js.html @@ -0,0 +1,95 @@ + + + + + JSDoc: Source: migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.js + + + + + + + + + + +
+ +

Source: migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.js

+ + + + + + +
+
+
const chalk = require("chalk");
+const utils = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Find deprecated plugins and remove them from the `plugins` array, if possible.
+ * Otherwise, warn the user about removing deprecated plugins manually.
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+
+module.exports = function(j, ast, source) {
+	// List of deprecated plugins to remove
+	// each item refers to webpack.optimize.[NAME] construct
+	const deprecatedPlugingsList = [
+		"webpack.optimize.OccurrenceOrderPlugin",
+		"webpack.optimize.DedupePlugin"
+	];
+
+	return utils
+		.findPluginsByName(j, ast, deprecatedPlugingsList)
+		.forEach(path => {
+			// For now we only support the case where plugins are defined in an Array
+			const arrayPath = utils.safeTraverse(path, ["parent", "value"]);
+			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"]);
+				if (arrayElementsPath && arrayElementsPath.length === 1) {
+					j(path.parent.parent).remove();
+				} else {
+					j(path).remove();
+				}
+			} else {
+				console.log(`
+${chalk.red("Please remove deprecated plugins manually. ")}
+See ${chalk.underline(
+		"https://webpack.js.org/guides/migrating/"
+	)} for more information.`);
+			}
+		});
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_removeJsonLoader_removeJsonLoader.js.html b/docs/migrate_removeJsonLoader_removeJsonLoader.js.html new file mode 100644 index 00000000000..2f8209d9f66 --- /dev/null +++ b/docs/migrate_removeJsonLoader_removeJsonLoader.js.html @@ -0,0 +1,120 @@ + + + + + JSDoc: Source: migrate/removeJsonLoader/removeJsonLoader.js + + + + + + + + + + +
+ +

Source: migrate/removeJsonLoader/removeJsonLoader.js

+ + + + + + +
+
+
const utils = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Transform which removes the json loader from all possible declarations
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+
+module.exports = function(j, ast) {
+	/**
+	 *
+	 * Remove the loader with name `name` from the given NodePath
+	 *
+	 * @param {Node} path - ast to remove the loader from
+	 * @param {String} name - the name of the loader to remove
+	 *
+	 */
+
+	function removeLoaderByName(path, name) {
+		const loadersNode = path.value.value;
+		switch (loadersNode.type) {
+			case j.ArrayExpression.name: {
+				let loaders = loadersNode.elements.map(p => {
+					return utils.safeTraverse(p, ["properties", "0", "value", "value"]);
+				});
+				const loaderIndex = loaders.indexOf(name);
+				if (loaders.length && loaderIndex > -1) {
+					// Remove loader from the array
+					loaders.splice(loaderIndex, 1);
+					// and from AST
+					loadersNode.elements.splice(loaderIndex, 1);
+				}
+
+				// If there are no loaders left, remove the whole Rule object
+				if (loaders.length === 0) {
+					j(path.parent).remove();
+				}
+				break;
+			}
+			case j.Literal.name: {
+				// If only the loader with the matching name was used
+				// we can remove the whole Property node completely
+				if (loadersNode.value === name) {
+					j(path.parent).remove();
+				}
+				break;
+			}
+		}
+	}
+
+	function removeLoaders(ast) {
+		ast
+			.find(j.Property, { key: { name: "use" } })
+			.forEach(path => removeLoaderByName(path, "json-loader"));
+
+		ast
+			.find(j.Property, { key: { name: "loader" } })
+			.forEach(path => removeLoaderByName(path, "json-loader"));
+	}
+
+	const transforms = [removeLoaders];
+
+	transforms.forEach(t => t(ast));
+
+	return ast;
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_resolve_resolve.js.html b/docs/migrate_resolve_resolve.js.html new file mode 100644 index 00000000000..983c2db310b --- /dev/null +++ b/docs/migrate_resolve_resolve.js.html @@ -0,0 +1,123 @@ + + + + + JSDoc: Source: migrate/resolve/resolve.js + + + + + + + + + + +
+ +

Source: migrate/resolve/resolve.js

+ + + + + + +
+
+
/**
+ *
+ * Transform which consolidates the `resolve.root` configuration option into the `resolve.modules` array
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+
+module.exports = function transformer(j, ast) {
+	const getRootVal = p => {
+		return p.node.value.properties.filter(prop => prop.key.name === "root")[0];
+	};
+
+	const getRootIndex = p => {
+		return p.node.value.properties.reduce((rootIndex, prop, index) => {
+			return prop.key.name === "root" ? index : rootIndex;
+		}, -1);
+	};
+
+	const isModulePresent = p => {
+		const modules = p.node.value.properties.filter(
+			prop => prop.key.name === "modules"
+		);
+		return modules.length > 0 && modules[0];
+	};
+
+	/**
+	 *
+	 * Add a `modules` property to the `resolve` object or update the existing one
+	 * based on what is already in `resolve.root`
+	 *
+	 * @param {Node} p - ast node that represents the `resolve` property
+	 * @returns {Node} p - ast node that represents the updated `resolve` property
+	 */
+
+	const createModuleArray = p => {
+		const rootVal = getRootVal(p);
+		let modulesVal = null;
+		if (rootVal.value.type === "ArrayExpression") {
+			modulesVal = rootVal.value.elements;
+		} else {
+			modulesVal = [rootVal.value];
+		}
+		let module = isModulePresent(p);
+
+		if (!module) {
+			module = j.property(
+				"init",
+				j.identifier("modules"),
+				j.arrayExpression(modulesVal)
+			);
+			p.node.value.properties = p.node.value.properties.concat([module]);
+		} else {
+			module.value.elements = module.value.elements.concat(modulesVal);
+		}
+		const rootIndex = getRootIndex(p);
+		p.node.value.properties.splice(rootIndex, 1);
+		return p;
+	};
+
+	return ast
+		.find(j.Property)
+		.filter(p => {
+			return (
+				p.node.key.name === "resolve" &&
+				p.node.value.properties.filter(prop => prop.key.name === "root")
+					.length === 1
+			);
+		})
+		.forEach(createModuleArray);
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/migrate_uglifyJsPlugin_uglifyJsPlugin.js.html b/docs/migrate_uglifyJsPlugin_uglifyJsPlugin.js.html new file mode 100644 index 00000000000..fb1ec6d518e --- /dev/null +++ b/docs/migrate_uglifyJsPlugin_uglifyJsPlugin.js.html @@ -0,0 +1,174 @@ + + + + + JSDoc: Source: migrate/uglifyJsPlugin/uglifyJsPlugin.js + + + + + + + + + + +
+ +

Source: migrate/uglifyJsPlugin/uglifyJsPlugin.js

+ + + + + + +
+
+
const {
+	findPluginsByName,
+	safeTraverse,
+	createProperty,
+	getRequire,
+	findPluginsArrayAndRemoveIfEmpty
+} = require("@webpack-cli/utils/ast-utils");
+
+/**
+ *
+ * Transform which:
+ * - Removes UglifyWebpackPlugin from plugins array, if no options is passed to the plugin.
+ *	 and adds `optimization.minimize: true` to config
+ *
+ * - If any configuration is passed to UglifyWebpackPlugin
+ *   plugin instantiation is moved to `optimization.minimizer`.
+ *
+ * @param {Object} j - jscodeshift top-level import
+ * @param {Node} ast - jscodeshift ast to transform
+ * @returns {Node} ast - jscodeshift ast
+ */
+
+module.exports = function(j, ast) {
+	let pluginVariableAssignment;
+
+	const searchForRequirePlugin = ast
+		.find(j.VariableDeclarator)
+		.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 => {
+		pluginVariableAssignment = node.value.id.name;
+	});
+
+	pluginVariableAssignment = !pluginVariableAssignment
+		? "webpack.optimize.UglifyJsPlugin"
+		: pluginVariableAssignment;
+
+	findPluginsByName(j, ast, [pluginVariableAssignment]).forEach(node => {
+		let expressionContent;
+		const configBody = safeTraverse(node, ["parent", "parent", "parent"]);
+
+		// options passed to plugin
+		const pluginOptions = node.value.arguments;
+
+		/**
+		 * check if there are any options passed to UglifyWebpackPlugin
+		 * If so, they are moved to optimization.minimizer.
+		 * Otherwise, rely on default options
+		 */
+		if (pluginOptions.length) {
+			/*
+		 * If user is using UglifyJsPlugin directly from webpack
+		 * transformation must:
+		 * - remove it
+		 * - add require for uglify-webpack-plugin
+		 * - add to minimizer
+		 */
+			if (pluginVariableAssignment.includes("webpack")) {
+				// create require for uglify-webpack-plugin
+				const pathRequire = getRequire(
+					j,
+					"UglifyJsPlugin",
+					"uglifyjs-webpack-plugin"
+				);
+				// append to source code.
+				ast
+					.find(j.Program)
+					.replaceWith(p =>
+						j.program([].concat(pathRequire).concat(p.value.body))
+					);
+
+				expressionContent = j.property(
+					"init",
+					j.identifier("minimizer"),
+					j.arrayExpression([
+						j.newExpression(j.identifier("UglifyJsPlugin"), [pluginOptions[0]])
+					])
+				);
+			} else {
+				expressionContent = j.property(
+					"init",
+					j.identifier("minimizer"),
+					j.arrayExpression([node.value])
+				);
+			}
+		} else {
+			searchForRequirePlugin.forEach(node => j(node).remove());
+		}
+
+		const minimizeProperty = createProperty(j, "minimize", "true");
+		// creates optimization property at the body of the config.
+		if (expressionContent) {
+			configBody.value.properties.push(
+				j.property(
+					"init",
+					j.identifier("optimization"),
+					j.objectExpression([minimizeProperty, expressionContent])
+				)
+			);
+		} else {
+			configBody.value.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);
+
+	return ast;
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/remove_index.js.html b/docs/remove_index.js.html new file mode 100644 index 00000000000..af1cf1d7aff --- /dev/null +++ b/docs/remove_index.js.html @@ -0,0 +1,67 @@ + + + + + JSDoc: Source: remove/index.js + + + + + + + + + + +
+ +

Source: remove/index.js

+ + + + + + +
+
+
"use strict";
+
+const defaultGenerator = require("@webpack-cli/generators/remove-generator");
+const modifyHelper = require("@webpack-cli/utils/modify-config-helper");
+
+/**
+ * Is called and returns a scaffolding instance, removing properties
+ *
+ * @returns {Function} modifyHelper - A helper function that uses the action
+ * 	we're given on a generator
+ *
+ */
+
+module.exports = function() {
+	return modifyHelper("remove", defaultGenerator);
+};
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/scripts/linenumber.js b/docs/scripts/linenumber.js new file mode 100644 index 00000000000..8d52f7eafdb --- /dev/null +++ b/docs/scripts/linenumber.js @@ -0,0 +1,25 @@ +/*global document */ +(function() { + var source = document.getElementsByClassName('prettyprint source linenums'); + var i = 0; + var lineNumber = 0; + var lineId; + var lines; + var totalLines; + var anchorHash; + + if (source && source[0]) { + anchorHash = document.location.hash.substring(1); + lines = source[0].getElementsByTagName('li'); + totalLines = lines.length; + + for (; i < totalLines; i++) { + lineNumber++; + lineId = 'line' + lineNumber; + lines[i].id = lineId; + if (lineId === anchorHash) { + lines[i].className += ' selected'; + } + } + } +})(); diff --git a/docs/scripts/prettify/Apache-License-2.0.txt b/docs/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/docs/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/docs/scripts/prettify/lang-css.js b/docs/scripts/prettify/lang-css.js new file mode 100644 index 00000000000..041e1f59067 --- /dev/null +++ b/docs/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/docs/scripts/prettify/prettify.js b/docs/scripts/prettify/prettify.js new file mode 100644 index 00000000000..eef5ad7e6a0 --- /dev/null +++ b/docs/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p + + + + JSDoc: Source: serve/index.js + + + + + + + + + + +
+ +

Source: serve/index.js

+ + + + + + +
+
+
"use strict";
+
+const inquirer = require("inquirer");
+const path = require("path");
+const chalk = require("chalk");
+const spawn = require("cross-spawn");
+const List = require("@webpack-cli/webpack-scaffold").List;
+const processPromise = require("@webpack-cli/utils/resolve-packages")
+	.processPromise;
+
+/**
+ *
+ * Installs WDS using NPM with --save --dev etc
+ *
+ * @param {Object} cmd - arg to spawn with
+ * @returns {Void}
+ */
+
+const spawnNPMWithArg = cmd =>
+	spawn.sync("npm", ["install", "webpack-dev-server", cmd], {
+		stdio: "inherit"
+	});
+
+/**
+ *
+ * Installs WDS using Yarn with add etc
+ *
+ * @param {Object} cmd - arg to spawn with
+ * @returns {Void}
+ */
+
+const spawnYarnWithArg = cmd =>
+	spawn.sync("yarn", ["add", "webpack-dev-server", cmd], {
+		stdio: "inherit"
+	});
+
+/**
+ *
+ * Find the path of a given module
+ *
+ * @param {Object} dep - dependency to find
+ * @returns {String} string with given path
+ */
+
+const getRootPathModule = dep => path.resolve(process.cwd(), dep);
+
+/**
+ *
+ * Prompts for installing the devServer and running it
+ *
+ * @param {Object} args - args processed from the CLI
+ * @returns {Function} invokes the devServer API
+ */
+
+function serve() {
+	let packageJSONPath = getRootPathModule("package.json");
+	if (!packageJSONPath) {
+		console.log(
+			"\n",
+			chalk.red("✖ Could not find your package.json file"),
+			"\n"
+		);
+		process.exit(1);
+	}
+	let packageJSON = 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
+	*/
+	let hasDevServerDep = packageJSON
+		? Object.keys(packageJSON).filter(p => packageJSON[p]["webpack-dev-server"])
+		: [];
+
+	if (hasDevServerDep.length) {
+		let WDSPath = getRootPathModule(
+			"node_modules/webpack-dev-server/bin/webpack-dev-server.js"
+		);
+		if (!WDSPath) {
+			console.log(
+				"\n",
+				chalk.red(
+					"✖ Could not find the webpack-dev-server dependency in node_modules root path"
+				)
+			);
+			console.log(
+				chalk.bold.green(" ✔︎"),
+				"Try this command:",
+				chalk.bold.green("rm -rf node_modules && npm install")
+			);
+			process.exit(1);
+		}
+		return require(WDSPath);
+	} else {
+		process.stdout.write(
+			"\n" +
+				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"
+		);
+		return inquirer
+			.prompt([
+				{
+					type: "confirm",
+					name: "confirmDevserver",
+					message: "Do you want to install it? (default: Y)",
+					default: "Y"
+				}
+			])
+			.then(answer => {
+				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 => {
+							const packager = getRootPathModule("package-lock.json")
+								? "npm"
+								: "yarn";
+							let spawnAction;
+							if (depTypeAns["confirmDepType"] === "devDependency") {
+								if (packager === "yarn") {
+									spawnAction = _ => spawnYarnWithArg("--dev");
+								} else {
+									spawnAction = _ => spawnNPMWithArg("--save-dev");
+								}
+							}
+							if (depTypeAns["confirmDepType"] === "dependency") {
+								if (packager === "yarn") {
+									spawnAction = _ => spawnYarnWithArg(" ");
+								} else {
+									spawnAction = _ => spawnNPMWithArg("--save");
+								}
+							}
+							if (depTypeAns["confirmDepType"] === "optionalDependency") {
+								if (packager === "yarn") {
+									spawnAction = _ => spawnYarnWithArg("--optional");
+								} else {
+									spawnAction = _ => spawnNPMWithArg("--save-optional");
+								}
+							}
+							return processPromise(spawnAction()).then(_ => {
+								// Recursion doesn't work well with require call being cached
+								delete require.cache[require.resolve(packageJSONPath)];
+								return serve();
+							});
+						});
+				} else {
+					console.log(chalk.bold.red("✖ Serve aborted due cancelling"));
+					process.exitCode = 1;
+				}
+			})
+			.catch(err => {
+				console.log(chalk.red("✖ Serve aborted due to some errors"));
+				console.error(err);
+				process.exitCode = 1;
+			});
+	}
+}
+
+module.exports = {
+	serve,
+	getRootPathModule,
+	spawnNPMWithArg,
+	spawnYarnWithArg
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/styles/jsdoc-default.css b/docs/styles/jsdoc-default.css new file mode 100644 index 00000000000..9207bc824b9 --- /dev/null +++ b/docs/styles/jsdoc-default.css @@ -0,0 +1,358 @@ +@font-face { + font-family: 'Open Sans'; + font-weight: normal; + font-style: normal; + src: url('../fonts/OpenSans-Regular-webfont.eot'); + src: + local('Open Sans'), + local('OpenSans'), + url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), + url('../fonts/OpenSans-Regular-webfont.woff') format('woff'), + url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg'); +} + +@font-face { + font-family: 'Open Sans Light'; + font-weight: normal; + font-style: normal; + src: url('../fonts/OpenSans-Light-webfont.eot'); + src: + local('Open Sans Light'), + local('OpenSans Light'), + url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'), + url('../fonts/OpenSans-Light-webfont.woff') format('woff'), + url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg'); +} + +html +{ + overflow: auto; + background-color: #fff; + font-size: 14px; +} + +body +{ + font-family: 'Open Sans', sans-serif; + line-height: 1.5; + color: #4d4e53; + background-color: white; +} + +a, a:visited, a:active { + color: #0095dd; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +header +{ + display: block; + padding: 0px 4px; +} + +tt, code, kbd, samp { + font-family: Consolas, Monaco, 'Andale Mono', monospace; +} + +.class-description { + font-size: 130%; + line-height: 140%; + margin-bottom: 1em; + margin-top: 1em; +} + +.class-description:empty { + margin: 0; +} + +#main { + float: left; + width: 70%; +} + +article dl { + margin-bottom: 40px; +} + +article img { + max-width: 100%; +} + +section +{ + display: block; + background-color: #fff; + padding: 12px 24px; + border-bottom: 1px solid #ccc; + margin-right: 30px; +} + +.variation { + display: none; +} + +.signature-attributes { + font-size: 60%; + color: #aaa; + font-style: italic; + font-weight: lighter; +} + +nav +{ + display: block; + float: right; + margin-top: 28px; + width: 30%; + box-sizing: border-box; + border-left: 1px solid #ccc; + padding-left: 16px; +} + +nav ul { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif; + font-size: 100%; + line-height: 17px; + padding: 0; + margin: 0; + list-style-type: none; +} + +nav ul a, nav ul a:visited, nav ul a:active { + font-family: Consolas, Monaco, 'Andale Mono', monospace; + line-height: 18px; + color: #4D4E53; +} + +nav h3 { + margin-top: 12px; +} + +nav li { + margin-top: 6px; +} + +footer { + display: block; + padding: 6px; + margin-top: 12px; + font-style: italic; + font-size: 90%; +} + +h1, h2, h3, h4 { + font-weight: 200; + margin: 0; +} + +h1 +{ + font-family: 'Open Sans Light', sans-serif; + font-size: 48px; + letter-spacing: -2px; + margin: 12px 24px 20px; +} + +h2, h3.subsection-title +{ + font-size: 30px; + font-weight: 700; + letter-spacing: -1px; + margin-bottom: 12px; +} + +h3 +{ + font-size: 24px; + letter-spacing: -0.5px; + margin-bottom: 12px; +} + +h4 +{ + font-size: 18px; + letter-spacing: -0.33px; + margin-bottom: 12px; + color: #4d4e53; +} + +h5, .container-overview .subsection-title +{ + font-size: 120%; + font-weight: bold; + letter-spacing: -0.01em; + margin: 8px 0 3px 0; +} + +h6 +{ + font-size: 100%; + letter-spacing: -0.01em; + margin: 6px 0 3px 0; + font-style: italic; +} + +table +{ + border-spacing: 0; + border: 0; + border-collapse: collapse; +} + +td, th +{ + border: 1px solid #ddd; + margin: 0px; + text-align: left; + vertical-align: top; + padding: 4px 6px; + display: table-cell; +} + +thead tr +{ + background-color: #ddd; + font-weight: bold; +} + +th { border-right: 1px solid #aaa; } +tr > th:last-child { border-right: 1px solid #ddd; } + +.ancestors, .attribs { color: #999; } +.ancestors a, .attribs a +{ + color: #999 !important; + text-decoration: none; +} + +.clear +{ + clear: both; +} + +.important +{ + font-weight: bold; + color: #950B02; +} + +.yes-def { + text-indent: -1000px; +} + +.type-signature { + color: #aaa; +} + +.name, .signature { + font-family: Consolas, Monaco, 'Andale Mono', monospace; +} + +.details { margin-top: 14px; border-left: 2px solid #DDD; } +.details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } +.details dd { margin-left: 70px; } +.details ul { margin: 0; } +.details ul { list-style-type: none; } +.details li { margin-left: 30px; padding-top: 6px; } +.details pre.prettyprint { margin: 0 } +.details .object-value { padding-top: 0; } + +.description { + margin-bottom: 1em; + margin-top: 1em; +} + +.code-caption +{ + font-style: italic; + font-size: 107%; + margin: 0; +} + +.prettyprint +{ + border: 1px solid #ddd; + width: 80%; + overflow: auto; +} + +.prettyprint.source { + width: inherit; +} + +.prettyprint code +{ + font-size: 100%; + line-height: 18px; + display: block; + padding: 4px 12px; + margin: 0; + background-color: #fff; + color: #4D4E53; +} + +.prettyprint code span.line +{ + display: inline-block; +} + +.prettyprint.linenums +{ + padding-left: 70px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.prettyprint.linenums ol +{ + padding-left: 0; +} + +.prettyprint.linenums li +{ + border-left: 3px #ddd solid; +} + +.prettyprint.linenums li.selected, +.prettyprint.linenums li.selected * +{ + background-color: lightyellow; +} + +.prettyprint.linenums li * +{ + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.params .name, .props .name, .name code { + color: #4D4E53; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 100%; +} + +.params td.description > p:first-child, +.props td.description > p:first-child +{ + margin-top: 0; + padding-top: 0; +} + +.params td.description > p:last-child, +.props td.description > p:last-child +{ + margin-bottom: 0; + padding-bottom: 0; +} + +.disabled { + color: #454545; +} diff --git a/docs/styles/prettify-jsdoc.css b/docs/styles/prettify-jsdoc.css new file mode 100644 index 00000000000..5a2526e3748 --- /dev/null +++ b/docs/styles/prettify-jsdoc.css @@ -0,0 +1,111 @@ +/* JSDoc prettify.js theme */ + +/* plain text */ +.pln { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* string content */ +.str { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a keyword */ +.kwd { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a comment */ +.com { + font-weight: normal; + font-style: italic; +} + +/* a type name */ +.typ { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a literal value */ +.lit { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* punctuation */ +.pun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp open bracket */ +.opn { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp close bracket */ +.clo { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a markup tag name */ +.tag { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute name */ +.atn { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute value */ +.atv { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a declaration */ +.dec { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a variable name */ +.var { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a function name */ +.fun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} diff --git a/docs/styles/prettify-tomorrow.css b/docs/styles/prettify-tomorrow.css new file mode 100644 index 00000000000..b6f92a78db9 --- /dev/null +++ b/docs/styles/prettify-tomorrow.css @@ -0,0 +1,132 @@ +/* Tomorrow Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* Pretty printing styles. Used with prettify.js. */ +/* SPAN elements with the classes below are added by prettyprint. */ +/* plain text */ +.pln { + color: #4d4d4c; } + +@media screen { + /* string content */ + .str { + color: #718c00; } + + /* a keyword */ + .kwd { + color: #8959a8; } + + /* a comment */ + .com { + color: #8e908c; } + + /* a type name */ + .typ { + color: #4271ae; } + + /* a literal value */ + .lit { + color: #f5871f; } + + /* punctuation */ + .pun { + color: #4d4d4c; } + + /* lisp open bracket */ + .opn { + color: #4d4d4c; } + + /* lisp close bracket */ + .clo { + color: #4d4d4c; } + + /* a markup tag name */ + .tag { + color: #c82829; } + + /* a markup attribute name */ + .atn { + color: #f5871f; } + + /* a markup attribute value */ + .atv { + color: #3e999f; } + + /* a declaration */ + .dec { + color: #f5871f; } + + /* a variable name */ + .var { + color: #c82829; } + + /* a function name */ + .fun { + color: #4271ae; } } +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { + color: #060; } + + .kwd { + color: #006; + font-weight: bold; } + + .com { + color: #600; + font-style: italic; } + + .typ { + color: #404; + font-weight: bold; } + + .lit { + color: #044; } + + .pun, .opn, .clo { + color: #440; } + + .tag { + color: #006; + font-weight: bold; } + + .atn { + color: #404; } + + .atv { + color: #060; } } +/* Style */ +/* +pre.prettyprint { + background: white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 12px; + line-height: 1.5; + border: 1px solid #ccc; + padding: 10px; } +*/ + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; } + +/* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L4, +li.L5, +li.L6, +li.L7, +li.L8, +li.L9 { + /* */ } + +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { + /* */ } diff --git a/docs/update_index.js.html b/docs/update_index.js.html new file mode 100644 index 00000000000..f0b3dcdd5a3 --- /dev/null +++ b/docs/update_index.js.html @@ -0,0 +1,67 @@ + + + + + JSDoc: Source: update/index.js + + + + + + + + + + +
+ +

Source: update/index.js

+ + + + + + +
+
+
"use strict";
+
+const defaultGenerator = require("@webpack-cli/generators/update-generator");
+const modifyHelper = require("@webpack-cli/utils/modify-config-helper");
+
+/**
+ * Is called and returns a scaffolding instance, updating properties
+ *
+ * @returns {Function} modifyHelper - A helper function that uses the action
+ * 	we're given on a generator
+ *
+ */
+
+module.exports = function() {
+	return modifyHelper("update", defaultGenerator);
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_ast-utils.js.html b/docs/utils_ast-utils.js.html new file mode 100644 index 00000000000..360828e3c7b --- /dev/null +++ b/docs/utils_ast-utils.js.html @@ -0,0 +1,610 @@ + + + + + JSDoc: Source: utils/ast-utils.js + + + + + + + + + + +
+ +

Source: utils/ast-utils.js

+ + + + + + +
+
+
const validateIdentifier = require("./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
+ */
+function safeTraverse(obj, paths) {
+	let val = obj;
+	let idx = 0;
+
+	while (idx < paths.length) {
+		if (!val) {
+			return null;
+		}
+		val = val[paths[idx]];
+		idx++;
+	}
+	return val;
+}
+
+/**
+ *
+ * Traverse safely and return `type` for path object with value.value property
+ * @param {Node} path - AST node
+ * @returns {String|Boolean} type at given path.
+ */
+function safeTraverseAndGetType(path) {
+	const pathValue = safeTraverse(path, ["value", "value"]);
+	return pathValue ? pathValue.type : false;
+}
+
+// Convert nested MemberExpressions to strings like webpack.optimize.DedupePlugin
+function memberExpressionToPathString(path) {
+	if (path && path.object) {
+		return [memberExpressionToPathString(path.object), path.property.name].join(
+			"."
+		);
+	}
+	return path.name;
+}
+
+// Convert Array<string> like ['webpack', 'optimize', 'DedupePlugin'] to nested MemberExpressions
+function pathsToMemberExpression(j, paths) {
+	if (!paths.length) {
+		return null;
+	} else if (paths.length === 1) {
+		return j.identifier(paths[0]);
+	} else {
+		const first = paths.slice(0, 1);
+		const rest = paths.slice(1);
+		return j.memberExpression(
+			pathsToMemberExpression(j, rest),
+			pathsToMemberExpression(j, first)
+		);
+	}
+}
+
+/**
+ *
+ * Find paths that match `new name.space.PluginName()` for a
+ * given array of plugin names
+ *
+ * @param {any} j — jscodeshift API
+ * @param {Node} node - Node to start search from
+ * @param {String[]} pluginNamesArray - Array of plugin names like `webpack.LoaderOptionsPlugin`
+ * @returns {Node} Node that has the pluginName
+ */
+
+function findPluginsByName(j, node, pluginNamesArray) {
+	return node.find(j.NewExpression).filter(path => {
+		return pluginNamesArray.some(
+			plugin =>
+				memberExpressionToPathString(path.get("callee").value) === plugin
+		);
+	});
+}
+
+/**
+ * It lookouts for the plugins property and, if the array is empty, it removes it from the AST
+ * @param  {any} j - jscodeshift API
+ * @param  {Node} rootNode - node to start search from
+ * @returns {Node} rootNode modified AST.
+ */
+
+function findPluginsArrayAndRemoveIfEmpty(j, rootNode) {
+	return rootNode.find(j.Identifier, { name: "plugins" }).forEach(node => {
+		const elements = safeTraverse(node, [
+			"parent",
+			"value",
+			"value",
+			"elements"
+		]);
+		if (!elements.length) {
+			j(node.parent).remove();
+		}
+	});
+}
+
+/**
+ *
+ * Finds the path to the `name: []` node
+ *
+ * @param {any} j — jscodeshift API
+ * @param {Node} node - Node to start search from
+ * @param {String} propName - property to search for
+ * @returns {Node} found node and
+ */
+
+function findRootNodesByName(j, node, propName) {
+	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, key, value) {
+	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, val) {
+	let literalVal = 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
+ *
+ * @param {any} j — jscodeshift API
+ * @param {String | Boolean | Number} val
+ * @returns {Node}
+ */
+
+function createIdentifierOrLiteral(j, val) {
+	// IPath<IIdentifier> | IPath<ILiteral> doesn't work, find another way
+	let literalVal = val;
+	// We'll need String to native type conversions
+	if (typeof val === "string" || val.__paths) {
+		// 'true' => true
+		if (val === "true") {
+			literalVal = true;
+			return j.literal(literalVal);
+		}
+		// 'false' => false
+		if (val === "false") {
+			literalVal = false;
+			return j.literal(literalVal);
+		}
+		// '1' => 1
+		if (!isNaN(Number(val))) {
+			literalVal = Number(val);
+			return j.literal(literalVal);
+		}
+		if (val.__paths) {
+			let regExpVal = val.__paths[0].value.program.body[0].expression;
+			return j.literal(regExpVal.value);
+		} else {
+			// Use identifier instead
+			if (
+				!validateIdentifier.isKeyword(literalVal) ||
+				!validateIdentifier.isIdentifierStart(literalVal) ||
+				!validateIdentifier.isIdentifierChar(literalVal)
+			)
+				return j.identifier(literalVal);
+		}
+	}
+	return j.literal(literalVal);
+}
+
+/**
+ *
+ * Adds or updates the value of a key within a root
+ * webpack configuration property that's of type Object.
+ *
+ * @param {any} j — jscodeshift API
+ * @param {Node} rootNode - node of root webpack configuration
+ * @param {String} configProperty - key of an Object webpack configuration property
+ * @param {String} key - key within the configuration object to update
+ * @param {Object} value - the value to set for the key
+ * @returns {Void}
+ */
+
+function addOrUpdateConfigObject(j, rootNode, configProperty, key, value) {
+	const propertyExists = rootNode.properties.filter(
+		node => node.key.name === configProperty
+	).length;
+
+	if (propertyExists) {
+		rootNode.properties
+			.filter(path => path.key.name === configProperty)
+			.forEach(path => {
+				const newProperties = path.value.properties.filter(
+					path => path.key.name !== key
+				);
+				newProperties.push(j.objectProperty(j.identifier(key), value));
+				path.value.properties = newProperties;
+			});
+	} else {
+		rootNode.properties.push(
+			j.objectProperty(
+				j.identifier(configProperty),
+				j.objectExpression([j.objectProperty(j.identifier(key), value)])
+			)
+		);
+	}
+}
+
+/**
+ *
+ * Finds and removes a node for a given plugin name. If the plugin
+ * is the last in the plugins array, the array is also removed.
+ *
+ * @param {any} j — jscodeshift API
+ * @param {Node} node - node to start search from
+ * @param {String} pluginName - name of the plugin to remove
+ * @returns {Node | Void} - path to the root webpack configuration object if plugin is found
+ */
+
+function findAndRemovePluginByName(j, node, pluginName) {
+	let rootPath;
+
+	findPluginsByName(j, node, [pluginName])
+		.filter(path => safeTraverse(path, ["parent", "value"]))
+		.forEach(path => {
+			rootPath = safeTraverse(path, ["parent", "parent", "parent", "value"]);
+			const arrayPath = path.parent.value;
+			if (arrayPath.elements && arrayPath.elements.length === 1) {
+				j(path.parent.parent).remove();
+			} else {
+				j(path).remove();
+			}
+		});
+
+	return rootPath;
+}
+
+/**
+ *
+ * Finds or creates a node for a given plugin name string with options object
+ * If plugin declaration already exist, options are merged.
+ *
+ * @param {any} j — jscodeshift API
+ * @param {Node} rootNodePath - `plugins: []` NodePath where plugin should be added. See https://github.com/facebook/jscodeshift/wiki/jscodeshift-Documentation#nodepaths
+ * @param {String} pluginName - ex. `webpack.LoaderOptionsPlugin`
+ * @param {Object} options - plugin options
+ * @returns {Void}
+ */
+
+function createOrUpdatePluginByName(j, rootNodePath, pluginName, options) {
+	const pluginInstancePath = findPluginsByName(j, j(rootNodePath), [
+		pluginName
+	]);
+	let optionsProps;
+	if (options) {
+		optionsProps = Object.keys(options).map(key => {
+			return createProperty(j, key, options[key]);
+		});
+	}
+
+	// If plugin declaration already exist
+	if (pluginInstancePath.size()) {
+		pluginInstancePath.forEach(path => {
+			// There are options we want to pass as argument
+			if (optionsProps) {
+				const args = path.value.arguments;
+				if (args.length) {
+					// Plugin is called with object as arguments
+					// we will merge those objects
+					let currentProps = j(path)
+						.find(j.ObjectExpression)
+						.get("properties");
+
+					optionsProps.forEach(opt => {
+						// Search for same keys in the existing object
+						const existingProps = j(currentProps)
+							.find(j.Identifier)
+							.filter(path => opt.key.value === path.value.name);
+
+						if (existingProps.size()) {
+							// Replacing values for the same key
+							existingProps.forEach(path => {
+								j(path.parent).replaceWith(opt);
+							});
+						} else {
+							// Adding new key:values
+							currentProps.value.push(opt);
+						}
+					});
+				} else {
+					// Plugin is called without arguments
+					args.push(j.objectExpression(optionsProps));
+				}
+			}
+		});
+	} else {
+		let argumentsArray = [];
+		if (optionsProps) {
+			argumentsArray = [j.objectExpression(optionsProps)];
+		}
+		const loaderPluginInstance = j.newExpression(
+			pathsToMemberExpression(j, pluginName.split(".").reverse()),
+			argumentsArray
+		);
+		rootNodePath.value.elements.push(loaderPluginInstance);
+	}
+}
+
+/**
+ *
+ * Finds the variable to which a third party plugin is assigned to
+ *
+ * @param {any} j — jscodeshift API
+ * @param {Node} rootNode - `plugins: []` Root Node. See https://github.com/facebook/jscodeshift/wiki/jscodeshift-Documentation#nodepaths
+ * @param {String} pluginPackageName - ex. `extract-text-plugin`
+ * @returns {String} variable name - ex. 'const s = require(s) gives "s"`
+ */
+
+function findVariableToPlugin(j, rootNode, pluginPackageName) {
+	const moduleVarNames = rootNode
+		.find(j.VariableDeclarator)
+		.filter(j.filters.VariableDeclarator.requiresModule(pluginPackageName))
+		.nodes();
+	if (moduleVarNames.length === 0) return null;
+	return moduleVarNames.pop().id.name;
+}
+
+/**
+ *
+ * Returns true if type is given type
+ * @param {Node} path - AST node
+ * @param {String} type - node type
+ * @returns {Boolean}
+ */
+
+function isType(path, type) {
+	return path.type === type;
+}
+
+function findObjWithOneOfKeys(p, keyNames) {
+	return p.value.properties.reduce((predicate, prop) => {
+		const name = prop.key.name;
+		return keyNames.indexOf(name) > -1 || predicate;
+	}, false);
+}
+
+/**
+ *
+ * Returns constructed require symbol
+ * @param {any} j — jscodeshift API
+ * @param {String} constName - Name of require
+ * @param {String} packagePath - path of required package
+ * @returns {Node} - the created ast
+ */
+
+function getRequire(j, constName, packagePath) {
+	return j.variableDeclaration("const", [
+		j.variableDeclarator(
+			j.identifier(constName),
+			j.callExpression(j.identifier("require"), [j.literal(packagePath)])
+		)
+	]);
+}
+
+/**
+ *
+ * Recursively adds an object/property to a node
+ * @param {any} j — jscodeshift API
+ * @param {Node} p - AST node
+ * @param {String} key - key of a key/val object
+ * @param {Any} value - Any type of object
+ * @param {String} action - Action to be done on the given ast
+ * @returns {Node} - the created ast
+ */
+
+function addProperty(j, p, key, value, action) {
+	if (!p) {
+		return;
+	}
+	let valForNode;
+	if (Array.isArray(value)) {
+		let arrExp = j.arrayExpression([]);
+		if (safeTraverseAndGetType(p) === "ArrayExpression") {
+			arrExp = p.value.value;
+		}
+		value.forEach(val => {
+			addProperty(j, arrExp, null, val);
+		});
+		valForNode = arrExp;
+	} else if (
+		typeof value === "object" &&
+		!(value.__paths || value instanceof RegExp)
+	) {
+		let objectExp = j.objectExpression([]);
+		if (safeTraverseAndGetType(p) === "ObjectExpression") {
+			objectExp = p.value.value;
+		}
+		// object -> loop through it
+		Object.keys(value).forEach(prop => {
+			addProperty(j, objectExp, prop, value[prop]);
+		});
+		valForNode = objectExp;
+	} else {
+		valForNode = createIdentifierOrLiteral(j, value);
+	}
+	let pushVal;
+	if (key) {
+		pushVal = j.property("init", j.identifier(key), valForNode);
+	} else {
+		pushVal = valForNode;
+	}
+
+	// we only return the generated pushVal which will be replace the node path
+	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);
+		return p;
+	}
+	if (p.elements) {
+		p.elements.push(pushVal);
+		return p;
+	}
+	return;
+}
+
+/**
+ *
+ * Get an property named topScope from yeoman and inject it to the top scope of
+ * the config, outside module.exports
+ *
+ * @param j — jscodeshift API
+ * @param ast - jscodeshift API
+ * @param {any} value - transformation object to scaffold
+ * @param {String} action - action that indicates what to be done to the AST
+ * @returns ast - jscodeshift API
+ */
+
+function parseTopScope(j, ast, value, action) {
+	function createTopScopeProperty(p) {
+		value.forEach(n => {
+			if (
+				!p.value.body[0].declarations ||
+				n.indexOf(p.value.body[0].declarations[0].id.name) <= 0
+			) {
+				p.value.body.splice(-1, 0, n);
+			}
+		});
+	}
+	if (value) {
+		return ast.find(j.Program).filter(p => createTopScopeProperty(p));
+	} else {
+		return ast;
+	}
+}
+
+("use strict");
+
+/**
+ *
+ * Transform for merge. Finds the merge property from yeoman and creates a way
+ * for users to allow webpack-merge in their scaffold
+ *
+ * @param j — jscodeshift API
+ * @param ast - jscodeshift API
+ * @param {any} value - transformation object to scaffold
+ * @param {String} action - action that indicates what to be done to the AST
+ * @returns ast - jscodeshift API
+ */
+
+function parseMerge(j, ast, value, action) {
+	function createMergeProperty(p) {
+		// FIXME Use j.callExp()
+		let exportsDecl = p.value.body.map(n => {
+			if (n.expression) {
+				return n.expression.right;
+			}
+		});
+		const bodyLength = exportsDecl.length;
+		let newVal = {};
+		newVal.type = "ExpressionStatement";
+		newVal.expression = {
+			type: "AssignmentExpression",
+			operator: "=",
+			left: {
+				type: "MemberExpression",
+				computed: false,
+				object: j.identifier("module"),
+				property: j.identifier("exports")
+			},
+			right: j.callExpression(j.identifier("merge"), [
+				j.identifier(value),
+				exportsDecl.pop()
+			])
+		};
+		p.value.body[bodyLength - 1] = newVal;
+	}
+	if (value) {
+		return ast.find(j.Program).filter(p => createMergeProperty(p));
+	} else {
+		return ast;
+	}
+}
+
+module.exports = {
+	safeTraverse,
+	safeTraverseAndGetType,
+	createProperty,
+	findPluginsByName,
+	findRootNodesByName,
+	addOrUpdateConfigObject,
+	findAndRemovePluginByName,
+	createOrUpdatePluginByName,
+	findVariableToPlugin,
+	findPluginsArrayAndRemoveIfEmpty,
+	isType,
+	createLiteral,
+	createIdentifierOrLiteral,
+	findObjWithOneOfKeys,
+	getRequire,
+	addProperty,
+	parseTopScope,
+	parseMerge
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_copy-utils.js.html b/docs/utils_copy-utils.js.html new file mode 100644 index 00000000000..83ddc144f7a --- /dev/null +++ b/docs/utils_copy-utils.js.html @@ -0,0 +1,108 @@ + + + + + JSDoc: Source: utils/copy-utils.js + + + + + + + + + + +
+ +

Source: utils/copy-utils.js

+ + + + + + +
+
+
const path = require("path");
+
+/**
+ * Takes in a file path in the `./templates` directory. Copies that
+ * file to the destination, with the `.tpl` extension stripped.
+ *
+ * @param {Generator} generator A Yeoman Generator instance
+ * @param {string} templateDir Absolute path to template directory
+ * @returns {Function} A curried function that takes a file path and copies it
+ */
+const generatorCopy = (
+	generator,
+	templateDir
+) => /** @param {string} filePath */ filePath => {
+	const sourceParts = templateDir.split(path.delimiter);
+	sourceParts.push.apply(sourceParts, filePath.split("/"));
+	const targetParts = path.dirname(filePath).split("/");
+	targetParts.push(path.basename(filePath, ".tpl"));
+
+	generator.fs.copy(
+		path.join.apply(null, sourceParts),
+		generator.destinationPath(path.join.apply(null, targetParts))
+	);
+};
+
+/**
+ * Takes in a file path in the `./templates` directory. Copies that
+ * file to the destination, with the `.tpl` extension and `_` prefix
+ * stripped. Passes `this.props` to the template.
+ *
+ * @param {Generator} generator A Yeoman Generator instance
+ * @param {string} templateDir Absolute path to template directory
+ * @param {any} templateData An object containing the data passed to
+ * the template files.
+ * @returns {Function} A curried function that takes a file path and copies it
+ */
+const generatorCopyTpl = (
+	generator,
+	templateDir,
+	templateData
+) => /** @param {string} filePath */ filePath => {
+	const sourceParts = templateDir.split(path.delimiter);
+	sourceParts.push.apply(sourceParts, filePath.split("/"));
+	const targetParts = path.dirname(filePath).split("/");
+	targetParts.push(path.basename(filePath, ".tpl").slice(1));
+
+	generator.fs.copyTpl(
+		path.join.apply(null, sourceParts),
+		generator.destinationPath(path.join.apply(null, targetParts)),
+		templateData
+	);
+};
+
+module.exports = {
+	generatorCopy,
+	generatorCopyTpl
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_defineTest.js.html b/docs/utils_defineTest.js.html new file mode 100644 index 00000000000..37bd1b5e3d5 --- /dev/null +++ b/docs/utils_defineTest.js.html @@ -0,0 +1,168 @@ + + + + + JSDoc: Source: utils/defineTest.js + + + + + + + + + + +
+ +

Source: utils/defineTest.js

+ + + + + + +
+
+
"use strict";
+
+const fs = require("fs");
+const path = require("path");
+
+/**
+ * Utility function to run a jscodeshift script within a unit test.
+ * This makes several assumptions about the environment.
+ *
+ * Notes:
+ * - The test should be located in a subdirectory next to the transform itself.
+ *   Commonly tests are located in a directory called __tests__.
+ *
+ * - Test data should be located in a directory called __testfixtures__
+ *   alongside the transform and __tests__ directory.
+ * @param  {String} dirName          contains the name of the directory the test is located in. This
+ *                                   should normally be passed via __dirname.
+ * @param  {String} transformName    contains the filename of the transform being tested,
+ *                                   excluding the .js extension.
+ * @param  {String} [testFilePrefix] Optionally contains the name of the file with the test
+ *                                   data. If not specified, it defaults to the same value as `transformName`.
+ *                                   This will be suffixed with ".input.js" for the input file and ".output.js"
+ *                                   for the expected output. For example, if set to "foo", we will read the
+ *                                   "foo.input.js" file, pass this to the transform, and expect its output to
+ *                                   be equal to the contents of "foo.output.js".
+ * @param  {Object|Boolean|String} initOptions TBD
+ * @param  {String} action init, update or remove, decides how to format the AST
+ * @return {Function} Function that fires of the transforms
+ */
+function runSingleTransform(
+	dirName,
+	transformName,
+	testFilePrefix,
+	initOptions,
+	action
+) {
+	if (!testFilePrefix) {
+		testFilePrefix = transformName;
+	}
+	const fixtureDir = path.join(dirName, "__testfixtures__");
+	const inputPath = path.join(fixtureDir, testFilePrefix + ".input.js");
+	const source = fs.readFileSync(inputPath, "utf8");
+
+	let module;
+	// Assumes transform and test are on the same level
+	if (action) {
+		module = require(path.join(dirName, "recursive-parser" + ".js"));
+	} else {
+		module = require(path.join(dirName, transformName + ".js"));
+	}
+	// 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 = require("jscodeshift/dist/core");
+	if (module.parser) {
+		jscodeshift = jscodeshift.withParser(module.parser);
+	}
+	const ast = 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"
+	});
+}
+
+/**
+ * Handles some boilerplate around defining a simple jest/Jasmine test for a
+ * jscodeshift transform.
+ * @param  {String} dirName          contains the name of the directory the test is located in. This
+ *                                   should normally be passed via __dirname.
+ * @param  {String} transformName    contains the filename of the transform being tested,
+ *                                   excluding the .js extension.
+ * @param  {String} [testFilePrefix] Optionally contains the name of the file with the test
+ *                                   data. If not specified, it defaults to the same value as `transformName`.
+ *                                   This will be suffixed with ".input.js" for the input file and ".output.js"
+ *                                   for the expected output. For example, if set to "foo", we will read the
+ *                                   "foo.input.js" file, pass this to the transform, and expect its output to
+ *                                   be equal to the contents of "foo.output.js".
+ * @param  {any} transformObject     Object to be transformed with the transformations
+ * @param  {String} action init, update or remove, decides how to format the AST
+ * @return {Void} Jest makes sure to execute the globally defined functions
+ */
+function defineTest(
+	dirName,
+	transformName,
+	testFilePrefix,
+	transformObject,
+	action
+) {
+	const testName = testFilePrefix
+		? `transforms correctly using "${testFilePrefix}" data`
+		: "transforms correctly";
+	describe(transformName, () => {
+		it(testName, () => {
+			const output = runSingleTransform(
+				dirName,
+				transformName,
+				testFilePrefix,
+				transformObject,
+				action
+			);
+			expect(output).toMatchSnapshot();
+		});
+	});
+}
+module.exports = defineTest;
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_is-local-path.js.html b/docs/utils_is-local-path.js.html new file mode 100644 index 00000000000..87bb73eaaad --- /dev/null +++ b/docs/utils_is-local-path.js.html @@ -0,0 +1,70 @@ + + + + + JSDoc: Source: utils/is-local-path.js + + + + + + + + + + +
+ +

Source: utils/is-local-path.js

+ + + + + + +
+
+
"use strict";
+
+const fs = require("fs");
+const path = require("path");
+
+/**
+ * Attempts to detect whether the string is a local path regardless of its
+ * existence by checking its format. The point is to distinguish between
+ * paths and modules on the npm registry. This will fail for non-existent
+ * local Windows paths that begin with a drive letter, e.g. C:..\generator.js,
+ * but will succeed for any existing files and any absolute paths.
+ *
+ * @param {String} str - string to check
+ * @returns {Boolean} whether the string could be a path to a local file or directory
+ */
+
+module.exports = function(str) {
+	return path.isAbsolute(str) || /^\./.test(str) || fs.existsSync(str);
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_modify-config-helper.js.html b/docs/utils_modify-config-helper.js.html new file mode 100644 index 00000000000..27e0563c81a --- /dev/null +++ b/docs/utils_modify-config-helper.js.html @@ -0,0 +1,126 @@ + + + + + JSDoc: Source: utils/modify-config-helper.js + + + + + + + + + + +
+ +

Source: utils/modify-config-helper.js

+ + + + + + +
+
+
"use strict";
+
+const fs = require("fs");
+const path = require("path");
+const chalk = require("chalk");
+const yeoman = require("yeoman-environment");
+const runTransform = require("./scaffold");
+const Generator = require("yeoman-generator");
+
+/**
+ *
+ * Looks up the webpack.config in the user's path and runs a given
+ * generator scaffold followed up by a transform
+ *
+ * @param {String} action — action to be done (add, remove, update, init)
+ * @param {Class} name - Name for the given function
+ * @returns {Function} runTransform - Returns a transformation instance
+ */
+
+module.exports = function modifyHelperUtil(action, generator, packages) {
+	let configPath = path.resolve(process.cwd(), "webpack.config.js");
+	const webpackConfigExists = fs.existsSync(configPath);
+	if (!webpackConfigExists) {
+		configPath = null;
+	}
+	const env = yeoman.createEnv("webpack", null);
+	const generatorName = `webpack-${action}-generator`;
+
+	if (!generator) {
+		generator = class extends Generator {
+			initializing() {
+				packages.forEach(pkgPath => {
+					return this.composeWith(require.resolve(pkgPath));
+				});
+			}
+		};
+	}
+	env.registerStub(generator, generatorName);
+
+	env.run(generatorName).on("end", () => {
+		let configModule;
+		try {
+			const configPath = path.resolve(process.cwd(), ".yo-rc.json");
+			configModule = require(configPath);
+			// Change structure of the config to be transformed
+			let tmpConfig = {};
+			Object.keys(configModule).forEach(prop => {
+				const configs = Object.keys(configModule[prop].configuration);
+				configs.forEach(config => {
+					tmpConfig[config] = configModule[prop].configuration[config];
+				});
+			});
+			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 config = Object.assign(
+			{
+				configFile: !configPath ? null : fs.readFileSync(configPath, "utf8"),
+				configPath: configPath
+			},
+			configModule
+		);
+		return runTransform(config, action);
+	});
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_npm-exists.js.html b/docs/utils_npm-exists.js.html new file mode 100644 index 00000000000..07d07c976ad --- /dev/null +++ b/docs/utils_npm-exists.js.html @@ -0,0 +1,74 @@ + + + + + JSDoc: Source: utils/npm-exists.js + + + + + + + + + + +
+ +

Source: utils/npm-exists.js

+ + + + + + +
+
+
"use strict";
+
+const got = require("got");
+const constant = value => _ => value;
+
+/**
+ *
+ * Checks if the given dependency/module is registered on npm
+ *
+ * @param {String} moduleName - The dependency to be checked
+ * @returns {Promise} constant - Returns either true or false,
+ * based on if it exists or not
+ */
+
+module.exports = function npmExists(moduleName) {
+	const hostname = "https://www.npmjs.org";
+	const pkgUrl = `${hostname}/package/${moduleName}`;
+	return got(pkgUrl, {
+		method: "HEAD"
+	})
+		.then(constant(true))
+		.catch(constant(false));
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_npm-packages-exists.js.html b/docs/utils_npm-packages-exists.js.html new file mode 100644 index 00000000000..ac5f0c43a0c --- /dev/null +++ b/docs/utils_npm-packages-exists.js.html @@ -0,0 +1,114 @@ + + + + + JSDoc: Source: utils/npm-packages-exists.js + + + + + + + + + + +
+ +

Source: utils/npm-packages-exists.js

+ + + + + + +
+
+
"use strict";
+const chalk = require("chalk");
+const isLocalPath = require("./is-local-path");
+const npmExists = require("./npm-exists");
+const resolvePackages = require("./resolve-packages").resolvePackages;
+
+const WEBPACK_SCAFFOLD_PREFIX = "webpack-scaffold";
+
+/**
+ *
+ * Loops through an array and checks if a package is registered
+ * on npm and throws an error if it is not.
+ *
+ * @param {String[]} pkg - Array of packages to check existence of
+ * @returns {Array} resolvePackages - Returns an process to install the packages
+ */
+
+module.exports = function npmPackagesExists(pkg) {
+	let acceptedPackages = [];
+
+	function resolvePackagesIfReady() {
+		if (acceptedPackages.length === pkg.length)
+			return resolvePackages(acceptedPackages);
+	}
+
+	pkg.forEach(addon => {
+		if (isLocalPath(addon)) {
+			// If the addon is a path to a local folder, no name validation is necessary.
+			acceptedPackages.push(addon);
+			resolvePackagesIfReady();
+			return;
+		}
+
+		// The addon is on npm; validate name and existence
+		if (
+			addon.length <= WEBPACK_SCAFFOLD_PREFIX.length ||
+			addon.slice(0, WEBPACK_SCAFFOLD_PREFIX.length) !== WEBPACK_SCAFFOLD_PREFIX
+		) {
+			throw new TypeError(
+				chalk.bold(`${addon} isn't a valid name.\n`) +
+					chalk.red(
+						`\nIt should be prefixed with '${WEBPACK_SCAFFOLD_PREFIX}', but have different suffix.\n`
+					)
+			);
+		}
+
+		npmExists(addon)
+			.then(moduleExists => {
+				if (!moduleExists) {
+					Error.stackTraceLimit = 0;
+					throw new TypeError(`Cannot resolve location of package ${addon}.`);
+				}
+				if (moduleExists) {
+					acceptedPackages.push(addon);
+				}
+			})
+			.catch(err => {
+				console.error(err.stack || err);
+				process.exit(0);
+			})
+			.then(resolvePackagesIfReady);
+	});
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_package-manager.js.html b/docs/utils_package-manager.js.html new file mode 100644 index 00000000000..0415cfd27c4 --- /dev/null +++ b/docs/utils_package-manager.js.html @@ -0,0 +1,163 @@ + + + + + JSDoc: Source: utils/package-manager.js + + + + + + + + + + +
+ +

Source: utils/package-manager.js

+ + + + + + +
+
+
"use strict";
+
+const path = require("path");
+const fs = require("fs");
+const spawn = require("cross-spawn");
+
+const SPAWN_FUNCTIONS = {
+	npm: spawnNPM,
+	yarn: spawnYarn
+};
+
+/**
+ *
+ * Spawns a new process using npm
+ *
+ * @param {String} pkg - The dependency to be installed
+ * @param {Boolean} isNew - indicates if it needs to be updated or installed
+ * @returns {Function} spawn - Installs the package
+ */
+
+function spawnNPM(pkg, isNew) {
+	return spawn.sync("npm", [isNew ? "install" : "update", "-g", pkg], {
+		stdio: "inherit"
+	});
+}
+
+/**
+ *
+ * Spawns a new process using yarn
+ *
+ * @param {String} pkg - The dependency to be installed
+ * @param {Boolean} isNew - indicates if it needs to be updated or installed
+ * @returns {Function} spawn - Installs the package
+ */
+
+function spawnYarn(pkg, isNew) {
+	return spawn.sync("yarn", ["global", isNew ? "add" : "upgrade", pkg], {
+		stdio: "inherit"
+	});
+}
+/**
+ *
+ * Spawns a new process that installs the addon/dependency
+ *
+ * @param {String} pkg - The dependency to be installed
+ * @returns {Function} spawn - Installs the package
+ */
+
+function spawnChild(pkg) {
+	const rootPath = getPathToGlobalPackages();
+	const pkgPath = path.resolve(rootPath, pkg);
+	const packageManager = getPackageManager();
+	const isNew = !fs.existsSync(pkgPath);
+
+	return SPAWN_FUNCTIONS[packageManager](pkg, isNew);
+}
+
+/**
+ *
+ * Returns the name of package manager to use,
+ * preferring yarn over npm if available
+ *
+ * @returns {String} - The package manager name
+ */
+
+function getPackageManager() {
+	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";
+	} else if (hasLocalYarn) {
+		return "yarn";
+	} else if (spawn.sync("yarn", [" --version"], { stdio: "ignore" }).error) {
+		return "npm";
+	} else {
+		return "yarn";
+	}
+}
+
+/**
+ *
+ * Returns the path to globally installed
+ * npm packages, depending on the available
+ * package manager determined by `getPackageManager`
+ *
+ * @returns {String} path - Path to global node_modules folder
+ */
+function getPathToGlobalPackages() {
+	const manager = getPackageManager();
+
+	if (manager === "yarn") {
+		try {
+			const yarnDir = spawn
+				.sync("yarn", ["global", "dir"])
+				.stdout.toString()
+				.trim();
+			return path.join(yarnDir, "node_modules");
+		} catch (e) {
+			// Default to the global npm path below
+		}
+	}
+
+	return require("global-modules");
+}
+
+module.exports = {
+	getPackageManager,
+	getPathToGlobalPackages,
+	spawnChild
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_prop-types.js.html b/docs/utils_prop-types.js.html new file mode 100644 index 00000000000..6e15a67401d --- /dev/null +++ b/docs/utils_prop-types.js.html @@ -0,0 +1,89 @@ + + + + + JSDoc: Source: utils/prop-types.js + + + + + + + + + + +
+ +

Source: utils/prop-types.js

+ + + + + + +
+
+
/**
+ *
+ * A Set of all accepted properties
+ *
+ * @returns {Set} A new set with accepted webpack properties
+ */
+
+module.exports = new Set([
+	"amd",
+	"bail",
+	"cache",
+	"context",
+	"devServer",
+	"devtool",
+	"entry",
+	"externals",
+	"merge",
+	"mode",
+	"module",
+	"node",
+	"output",
+	"optimization",
+	"parallelism",
+	"performance",
+	"plugins",
+	"profile",
+	"recordsInputPath",
+	"recordsOutputPath",
+	"recordsPath",
+	"resolve",
+	"resolveLoader",
+	"stats",
+	"splitChunks",
+	"target",
+	"watch",
+	"watchOptions",
+	"topScope"
+]);
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_resolve-packages.js.html b/docs/utils_resolve-packages.js.html new file mode 100644 index 00000000000..c276cd54dd3 --- /dev/null +++ b/docs/utils_resolve-packages.js.html @@ -0,0 +1,149 @@ + + + + + JSDoc: Source: utils/resolve-packages.js + + + + + + + + + + +
+ +

Source: utils/resolve-packages.js

+ + + + + + +
+
+
"use strict";
+
+const path = require("path");
+const chalk = require("chalk");
+
+const modifyConfigHelper = require("./modify-config-helper");
+
+const getPathToGlobalPackages = require("./package-manager")
+	.getPathToGlobalPackages;
+const isLocalPath = require("./is-local-path");
+const spawnChild = require("./package-manager").spawnChild;
+
+/**
+ *
+ * Attaches a promise to the installation of the package
+ *
+ * @param {Function} child - The function to attach a promise to
+ * @returns {Promise} promise - Returns a promise to the installation
+ */
+
+function processPromise(child) {
+	return new Promise(function(resolve, reject) {
+		//eslint-disable-line
+		if (child.status !== 0) {
+			reject();
+		} else {
+			resolve();
+		}
+	});
+}
+
+/**
+ *
+ * Resolves and installs the packages, later sending them to @creator
+ *
+ * @param {String[]} pkg - The dependencies to be installed
+ * @returns {Function|Error} creator - Builds
+ * a webpack configuration through yeoman or throws an error
+ */
+
+function resolvePackages(pkg) {
+	Error.stackTraceLimit = 30;
+
+	let packageLocations = [];
+
+	function invokeGeneratorIfReady() {
+		if (packageLocations.length === pkg.length)
+			return modifyConfigHelper("init", null, packageLocations);
+	}
+
+	pkg.forEach(addon => {
+		// Resolve paths to modules on local filesystem
+		if (isLocalPath(addon)) {
+			let absolutePath = addon;
+
+			try {
+				absolutePath = path.resolve(process.cwd(), addon);
+				require.resolve(absolutePath);
+				packageLocations.push(absolutePath);
+			} catch (err) {
+				console.log(`Cannot find a generator at ${absolutePath}.`);
+				console.log("\nReason:\n");
+				console.error(chalk.bold.red(err));
+				process.exitCode = 1;
+			}
+
+			invokeGeneratorIfReady();
+			return;
+		}
+
+		// Resolve modules on npm registry
+		processPromise(spawnChild(addon))
+			.then(_ => {
+				try {
+					const globalPath = getPathToGlobalPackages();
+					packageLocations.push(path.resolve(globalPath, addon));
+				} catch (err) {
+					console.log("Package wasn't validated correctly..");
+					console.log("Submit an issue for", pkg, "if this persists");
+					console.log("\nReason: \n");
+					console.error(chalk.bold.red(err));
+					process.exitCode = 1;
+				}
+			})
+			.catch(err => {
+				console.log("Package couldn't be installed, aborting..");
+				console.log("\nReason: \n");
+				console.error(chalk.bold.red(err));
+				process.exitCode = 1;
+			})
+			.then(invokeGeneratorIfReady);
+	});
+}
+
+module.exports = {
+	resolvePackages,
+	processPromise
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_run-prettier.js.html b/docs/utils_run-prettier.js.html new file mode 100644 index 00000000000..7c9cf919f41 --- /dev/null +++ b/docs/utils_run-prettier.js.html @@ -0,0 +1,95 @@ + + + + + JSDoc: Source: utils/run-prettier.js + + + + + + + + + + +
+ +

Source: utils/run-prettier.js

+ + + + + + +
+
+
"use strict";
+
+const prettier = require("prettier");
+const fs = require("fs");
+const chalk = require("chalk");
+
+/**
+ *
+ * Runs prettier and later prints the output configuration
+ *
+ * @param {String} outputPath - Path to write the config to
+ * @param {Node} source - AST to write at the given path
+ * @param {Function} cb - executes a callback after execution if supplied
+ * @returns {Function} Writes a file at given location and prints messages accordingly
+ */
+
+module.exports = function runPrettier(outputPath, source, cb) {
+	function validateConfig() {
+		let prettySource;
+		let error;
+		try {
+			prettySource = prettier.format(source, {
+				singleQuote: true,
+				useTabs: true,
+				tabWidth: 1
+			});
+		} catch (err) {
+			process.stdout.write(
+				"\n" +
+					chalk.yellow(
+						`WARNING: Could not apply prettier to ${outputPath}` +
+							" due validation error, but the file has been created\n"
+					)
+			);
+			prettySource = source;
+			error = err;
+		}
+		if (cb) {
+			return cb(error);
+		}
+		return fs.writeFileSync(outputPath, prettySource, "utf8");
+	}
+	return fs.writeFile(outputPath, source, "utf8", validateConfig);
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/docs/utils_scaffold.js.html b/docs/utils_scaffold.js.html new file mode 100644 index 00000000000..d41f4d87439 --- /dev/null +++ b/docs/utils_scaffold.js.html @@ -0,0 +1,153 @@ + + + + + JSDoc: Source: utils/scaffold.js + + + + + + + + + + +
+ +

Source: utils/scaffold.js

+ + + + + + +
+
+
"use strict";
+
+const path = require("path");
+const j = require("jscodeshift");
+const chalk = require("chalk");
+const pEachSeries = require("p-each-series");
+
+const runPrettier = require("./run-prettier");
+const astTransform = require("./recursive-parser");
+const propTypes = require("./prop-types");
+
+/**
+ *
+ * Maps back transforms that needs to be run using the configuration
+ * provided.
+ *
+ * @param	{Object} transformObject 	- An Object with all transformations
+ * @param	{Object} config 			- Configuration to transform
+ * @returns {Object} - An Object with the transformations to be run
+ */
+
+function mapOptionsToTransform(config) {
+	return Object.keys(config.webpackOptions).filter(k => propTypes.has(k));
+}
+
+/**
+ *
+ * Runs the transformations from an object we get from yeoman
+ *
+ * @param	{Object} webpackProperties 	- Configuration to transform
+ * @param	{String} action 			- Action to be done on the given ast
+ * @returns {Promise} - A promise that writes each transform, runs prettier
+ * and writes the file
+ */
+
+module.exports = function runTransform(webpackProperties, action) {
+	// webpackOptions.name sent to nameTransform if match
+	const webpackConfig = Object.keys(webpackProperties).filter(p => {
+		return p !== "configFile" && p !== "configPath";
+	});
+	const initActionNotDefined = action && action !== "init" ? true : false;
+
+	webpackConfig.forEach(scaffoldPiece => {
+		const config = webpackProperties[scaffoldPiece];
+		const transformations = mapOptionsToTransform(config);
+		if (config.topScope) {
+			transformations.push("topScope");
+		}
+		if (config.merge) {
+			transformations.push("merge");
+		}
+		const ast = j(
+			initActionNotDefined
+				? webpackProperties.configFile
+				: "module.exports = {}"
+		);
+		const transformAction = action || null;
+		return pEachSeries(transformations, f => {
+			if (f === "merge" || f === "topScope") {
+				return astTransform(j, ast, f, config[f], transformAction);
+			}
+			return astTransform(j, ast, f, config.webpackOptions[f], transformAction);
+		})
+			.then(_ => {
+				let configurationName;
+				if (!config.configName) {
+					configurationName = "webpack.config.js";
+				} else {
+					configurationName = "webpack." + config.configName + ".js";
+				}
+
+				const outputPath = initActionNotDefined
+					? webpackProperties.configPath
+					: path.join(process.cwd(), configurationName);
+				const source = ast.toSource({
+					quote: "single"
+				});
+
+				runPrettier(outputPath, source);
+			})
+			.catch(err => {
+				console.error(err.message ? err.message : err);
+			});
+	});
+	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"
+				)
+		);
+	}
+};
+
+
+
+ + + + +
+ + + +
+ +
+ Documentation generated by JSDoc 3.5.5 on Sat Jun 02 2018 17:44:07 GMT+0200 (CEST) +
+ + + + + diff --git a/jsdoc.json b/jsdoc.json index 6575850244d..4574098fd53 100644 --- a/jsdoc.json +++ b/jsdoc.json @@ -1,9 +1,17 @@ { + "tags": { + "allowUnknownTags": true + }, "source": { "include": [ "packages/" ], - "includePattern": "packages/.+\\.js$" + "exclude": [ + "node_modules", + "packages/**/node_modules" + ], + "includePattern": "packages/*/.+\\.js$", + "excludePattern": "node_modules/*" } } diff --git a/package-lock.json b/package-lock.json index 272d733fc92..d0ba031edd1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7192,15 +7192,13 @@ "version": "1.0.0", "resolved": false, "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7217,22 +7215,19 @@ "version": "1.1.0", "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "resolved": false, "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -7363,15 +7358,13 @@ "version": "2.0.3", "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true, - "optional": true + "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": false, "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7388,7 +7381,6 @@ "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7404,7 +7396,6 @@ "resolved": false, "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -7513,8 +7504,7 @@ "version": "1.0.1", "resolved": false, "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -7528,7 +7518,6 @@ "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -7666,7 +7655,6 @@ "resolved": false, "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/packages/utils/ast-utils.js b/packages/utils/ast-utils.js index 574c80c18e2..b7d5a24a5b6 100644 --- a/packages/utils/ast-utils.js +++ b/packages/utils/ast-utils.js @@ -411,9 +411,7 @@ function addProperty(j, p, key, value, action) { let valForNode; if (Array.isArray(value)) { let arrExp = j.arrayExpression([]); - if ( - safeTraverseAndGetType(p) === "ArrayExpression" - ) { + if (safeTraverseAndGetType(p) === "ArrayExpression") { arrExp = p.value.value; } value.forEach(val => { @@ -425,9 +423,7 @@ function addProperty(j, p, key, value, action) { !(value.__paths || value instanceof RegExp) ) { let objectExp = j.objectExpression([]); - if ( - safeTraverseAndGetType(p) === "ObjectExpression" - ) { + if (safeTraverseAndGetType(p) === "ObjectExpression") { objectExp = p.value.value; } // object -> loop through it diff --git a/packages/utils/ast-utils.test.js b/packages/utils/ast-utils.test.js index 2e9ee539971..6b5d3114b9b 100644 --- a/packages/utils/ast-utils.test.js +++ b/packages/utils/ast-utils.test.js @@ -236,7 +236,11 @@ const a = { plugs: [] } } } }; - const traversedValue = utils.safeTraverse(p, ["parent", "value", "value"]); + const traversedValue = utils.safeTraverse(p, [ + "parent", + "value", + "value" + ]); expect(traversedValue).toEqual(type); }); }); @@ -277,15 +281,14 @@ const a = { plugs: [] } super: [ "yeah", { - loader: "'eslint-loader'", + loader: "'eslint-loader'" } ], nice: "':)'", man: "() => duper" }; - const root = ast - .find(j.ObjectExpression); + const root = ast.find(j.ObjectExpression); root.forEach(p => { utils.addProperty(j, p, "entry", propertyValue); @@ -311,18 +314,19 @@ const a = { plugs: [] } super: [ "yeah", { - loader: "'eslint-loader'", + loader: "'eslint-loader'" } ], nice: "':)'", man: "() => duper" }; - const root = ast - .find(j.ObjectExpression); + const root = ast.find(j.ObjectExpression); utils.findRootNodesByName(j, root, "entry").forEach(p => { - j(p).replaceWith(utils.addProperty(j, p, "entry", propertyValue, "add")); + j(p).replaceWith( + utils.addProperty(j, p, "entry", propertyValue, "add") + ); }); expect(ast.toSource()).toMatchSnapshot(); diff --git a/packages/utils/recursive-parser.test.js b/packages/utils/recursive-parser.test.js index ea57dac1d1f..5d13b4d7af7 100644 --- a/packages/utils/recursive-parser.test.js +++ b/packages/utils/recursive-parser.test.js @@ -2,54 +2,41 @@ const defineTest = require("./defineTest"); - -defineTest( - __dirname, - "init", - "fixture-1", - "entry", - { - objects: "are", - super: [ - "yeah", - { - test: new RegExp(/\.(js|vue)$/), - loader: "'eslint-loader'", - enforce: "'pre'", - include: ["customObj", "'Stringy'"], - options: { - formatter: "'someOption'" - } +defineTest(__dirname, "init", "fixture-1", "entry", { + objects: "are", + super: [ + "yeah", + { + test: new RegExp(/\.(js|vue)$/), + loader: "'eslint-loader'", + enforce: "'pre'", + include: ["customObj", "'Stringy'"], + options: { + formatter: "'someOption'" } - ], - nice: "':)'", - foo: "Promise.resolve()", - man: "() => duper" - } -); + } + ], + nice: "':)'", + foo: "Promise.resolve()", + man: "() => duper" +}); -defineTest( - __dirname, - "add", - "fixture-2", - "entry", - { - objects: "are not", - super: [ - "op", - { - test: new RegExp(/\.(wasm|c)$/), - loader: "'pia-loader'", - enforce: "'pre'", - include: ["asd", "'Stringy'"], - options: { - formatter: "'nao'" - } +defineTest(__dirname, "add", "fixture-2", "entry", { + objects: "are not", + super: [ + "op", + { + test: new RegExp(/\.(wasm|c)$/), + loader: "'pia-loader'", + enforce: "'pre'", + include: ["asd", "'Stringy'"], + options: { + formatter: "'nao'" } - ], - nice: "'=)'", - foo: "Promise.resolve()", - man: "() => nice!!", - mode: "super-man" - } -); + } + ], + nice: "'=)'", + foo: "Promise.resolve()", + man: "() => nice!!", + mode: "super-man" +}); diff --git a/test/binCases/configFile/plugins-precedence/webpack.config.js b/test/binCases/configFile/plugins-precedence/webpack.config.js index dd375a709f1..2eb1049ad63 100644 --- a/test/binCases/configFile/plugins-precedence/webpack.config.js +++ b/test/binCases/configFile/plugins-precedence/webpack.config.js @@ -1,4 +1,4 @@ -var DefinePlugin = process.webpackModule.DefinePlugin; +var DefinePlugin = require('webpack').DefinePlugin; var path = require("path"); module.exports = {