From ae19fc66e86c6a0bb4834865253d2f1ea4812e7f Mon Sep 17 00:00:00 2001 From: David Paz Date: Tue, 18 Jul 2017 00:43:15 +0200 Subject: [PATCH 01/25] Refactor plugin configuration Extract encore built in plugin configuration logic into plugin utils. First step toward allowing to be able to configure plugins through options. From now own only public API with proper options is needed for most cases. --- lib/config-generator.js | 207 ++++++--------------------- lib/plugins/clean.js | 30 ++++ lib/plugins/common-chunks.js | 36 +++++ lib/plugins/delete-unused-entries.js | 26 ++++ lib/plugins/dev-server.js | 28 ++++ lib/plugins/extract-text.js | 43 ++++++ lib/plugins/friendly-errors.js | 47 ++++++ lib/plugins/loader-options.js | 38 +++++ lib/plugins/manifest.js | 35 +++++ lib/plugins/production.js | 35 +++++ lib/plugins/variable-provider.js | 22 +++ lib/plugins/versioning.js | 63 ++++++++ 12 files changed, 450 insertions(+), 160 deletions(-) create mode 100644 lib/plugins/clean.js create mode 100644 lib/plugins/common-chunks.js create mode 100644 lib/plugins/delete-unused-entries.js create mode 100644 lib/plugins/dev-server.js create mode 100644 lib/plugins/extract-text.js create mode 100644 lib/plugins/friendly-errors.js create mode 100644 lib/plugins/loader-options.js create mode 100644 lib/plugins/manifest.js create mode 100644 lib/plugins/production.js create mode 100644 lib/plugins/variable-provider.js create mode 100644 lib/plugins/versioning.js diff --git a/lib/config-generator.js b/lib/config-generator.js index 26fca25c..0c2e9aaf 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -9,28 +9,27 @@ 'use strict'; -const webpack = require('webpack'); -const ExtractTextPlugin = require('extract-text-webpack-plugin'); const extractText = require('./loaders/extract-text'); -const ManifestPlugin = require('./webpack/webpack-manifest-plugin'); -const DeleteUnusedEntriesJSPlugin = require('./webpack/delete-unused-entries-js-plugin'); -const AssetOutputDisplayPlugin = require('./friendly-errors/asset-output-display-plugin'); -const CleanWebpackPlugin = require('clean-webpack-plugin'); -const WebpackChunkHash = require('webpack-chunk-hash'); -const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); -const missingLoaderTransformer = require('./friendly-errors/transformers/missing-loader'); -const missingLoaderFormatter = require('./friendly-errors/formatters/missing-loader'); -const missingPostCssConfigTransformer = require('./friendly-errors/transformers/missing-postcss-config'); -const missingPostCssConfigFormatter = require('./friendly-errors/formatters/missing-postcss-config'); -const vueUnactivatedLoaderTransformer = require('./friendly-errors/transformers/vue-unactivated-loader-error'); -const vueUnactivatedLoaderFormatter = require('./friendly-errors/formatters/vue-unactivated-loader-error'); const pathUtil = require('./config/path-util'); +// loaders utils const cssLoaderUtil = require('./loaders/css'); const sassLoaderUtil = require('./loaders/sass'); const lessLoaderUtil = require('./loaders/less'); const babelLoaderUtil = require('./loaders/babel'); const tsLoaderUtil = require('./loaders/typescript'); const vueLoaderUtil = require('./loaders/vue'); +// plugins utils +const extractTextPluginUtil = require('./plugins/extract-text'); +const deleteUnusedEntriesPluginUtil = require('./plugins/delete-unused-entries'); +const manifestPluginUtil = require('./plugins/manifest'); +const loaderOptionsPluginUtil = require('./plugins/loader-options'); +const versioningPluginUtil = require('./plugins/versioning'); +const variableProviderPluginUtil = require('./plugins/variable-provider'); +const cleanPluginUtil = require('./plugins/clean'); +const commonChunksPluginUtil = require('./plugins/common-chunks'); +const productionPluginUtil = require('./plugins/production'); +const friendlyErrorPluginUtil = require('./plugins/friendly-errors'); +const devServerPluginUtil = require('./plugins/dev-server'); class ConfigGenerator { /** @@ -180,172 +179,60 @@ class ConfigGenerator { buildPluginsConfig() { let plugins = []; - /* - * All CSS/SCSS content (due to the loaders above) will be - * extracted into an [entrypointname].css files. The result - * is that NO css will be inlined, *except* CSS that is required - * in an async way (e.g. via require.ensure()). - * - * This may not be ideal in some cases, but it's at least - * predictable. It means that you must manually add a - * link tag for an entry point's CSS (unless no CSS file - * was imported - in which case no CSS file will be dumped). - */ - plugins.push(new ExtractTextPlugin({ - filename: this.webpackConfig.useVersioning ? '[name].[contenthash].css' : '[name].css', - // if true, async CSS (e.g. loaded via require.ensure()) - // is extracted to the entry point CSS. If false, it's - // inlined in the AJAX-loaded .js file. - allChunks: false - })); + plugins = plugins.concat( + extractTextPluginUtil.getPlugins(this.webpackConfig) + ); // register the pure-style entries that should be deleted - plugins.push(new DeleteUnusedEntriesJSPlugin( - // transform into an Array - [... this.webpackConfig.styleEntries.keys()] - )); - - /* - * Dump the manifest.json file - */ - let manifestPrefix = this.webpackConfig.manifestKeyPrefix; - if (null === manifestPrefix) { - // by convention, we remove the opening slash on the manifest keys - manifestPrefix = this.webpackConfig.publicPath.replace(/^\//,''); - } - plugins.push(new ManifestPlugin({ - basePath: manifestPrefix, - // guarantee the value uses the public path (or CDN public path) - publicPath: this.webpackConfig.getRealPublicPath(), - // always write a manifest.json file, even with webpack-dev-server - writeToFileEmit: true, - })); - - /* - * This section is a bit mysterious. The "minimize" - * true is read and used to minify the CSS. - * But as soon as this plugin is included - * at all, SASS begins to have errors, until the context - * and output options are specified. At this time, I'm - * not totally sure what's going on here - * https://github.com/jtangelder/sass-loader/issues/285 - */ - plugins.push(new webpack.LoaderOptionsPlugin({ - debug: !this.webpackConfig.isProduction(), - options: { - context: this.webpackConfig.getContext(), - output: { path: this.webpackConfig.outputPath } - } - })); - - /* - * With versioning, the "chunkhash" used in the filenames and - * the module ids (i.e. the internal names of modules that - * are required) become important. Specifically: - * - * 1) If the contents of a module don't change, then you don't want its - * internal module id to change. Otherwise, whatever file holds the - * webpack "manifest" will change because the module id will change. - * Solved by HashedModuleIdsPlugin or NamedModulesPlugin - * - * 2) Similarly, if the final contents of a file don't change, - * then we also don't want that file to have a new filename. - * The WebpackChunkHash() handles this, by making sure that - * the chunkhash is based off of the file contents. - * - * Even in the webpack community, the ideal setup seems to be - * a bit of a mystery: - * * https://github.com/webpack/webpack/issues/1315 - * * https://github.com/webpack/webpack.js.org/issues/652#issuecomment-273324529 - * * https://webpack.js.org/guides/caching/#deterministic-hashes - */ - if (this.webpackConfig.isProduction()) { - // shorter, and obfuscated module ids (versus NamedModulesPlugin) - // makes the final assets *slightly* larger, but prevents contents - // from sometimes changing when nothing really changed - plugins.push(new webpack.HashedModuleIdsPlugin()); - } else { - // human-readable module names, helps debug in HMR - // enable always when not in production for consistency - plugins.push(new webpack.NamedModulesPlugin()); - } + plugins = plugins.concat( + deleteUnusedEntriesPluginUtil.getPlugins(this.webpackConfig) + ); - if (this.webpackConfig.useVersioning) { - // enables the [chunkhash] ability - plugins.push(new WebpackChunkHash()); - } + // Dump the manifest.json file + plugins = plugins.concat( + manifestPluginUtil.getPlugins(this.webpackConfig) + ); + + plugins = plugins.concat( + loaderOptionsPluginUtil.getPlugins(this.webpackConfig) + ); + + plugins = plugins.concat( + versioningPluginUtil.getPlugins(this.webpackConfig) + ); if (Object.keys(this.webpackConfig.providedVariables).length > 0) { - plugins = plugins.concat([ - new webpack.ProvidePlugin(this.webpackConfig.providedVariables) - ]); + plugins = plugins.concat( + variableProviderPluginUtil.getPlugins(this.webpackConfig) + ); } if (this.webpackConfig.cleanupOutput) { - plugins.push( - new CleanWebpackPlugin(['**/*'], { - root: this.webpackConfig.outputPath, - verbose: false, - }) + plugins = plugins.concat( + cleanPluginUtil.getPlugins(this.webpackConfig, ['**/*']) ); } // if we're extracting a vendor chunk, set it up! if (this.webpackConfig.sharedCommonsEntryName) { - plugins = plugins.concat([ - new webpack.optimize.CommonsChunkPlugin({ - name: [ - this.webpackConfig.sharedCommonsEntryName, - /* - * Always dump a 2nd file - manifest.json that - * will contain the webpack manifest information. - * This changes frequently, and without this line, - * it would be packaged inside the "shared commons entry" - * file - e.g. vendor.js, which would prevent long-term caching. - */ - 'manifest' - ], - minChunks: Infinity, - }), - ]); + plugins = plugins.concat( + commonChunksPluginUtil.getPlugins(this.webpackConfig) + ); } if (this.webpackConfig.isProduction()) { - plugins = plugins.concat([ - new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: '"production"' - } - }), - - // todo - options here should be configurable - new webpack.optimize.UglifyJsPlugin({ - sourceMap: this.webpackConfig.useSourceMaps - }) - ]); + // todo - options here should be configurable + plugins = plugins.concat( + productionPluginUtil.getPlugins(this.webpackConfig) + ); } - const friendlyErrorsPlugin = new FriendlyErrorsWebpackPlugin({ - clearConsole: false, - additionalTransformers: [ - missingLoaderTransformer, - missingPostCssConfigTransformer, - vueUnactivatedLoaderTransformer - ], - additionalFormatters: [ - missingLoaderFormatter, - missingPostCssConfigFormatter, - vueUnactivatedLoaderFormatter - ], - compilationSuccessInfo: { - messages: [] - } - }); - plugins.push(friendlyErrorsPlugin); + plugins = plugins.concat(friendlyErrorPluginUtil.getPlugins()); if (!this.webpackConfig.useDevServer()) { - const outputPath = pathUtil.getRelativeOutputPath(this.webpackConfig); - plugins.push(new AssetOutputDisplayPlugin(outputPath, friendlyErrorsPlugin)); + plugins = plugins.concat( + devServerPluginUtil.getPlugins(this.webpackConfig) + ); } this.webpackConfig.plugins.forEach(function(plugin) { diff --git a/lib/plugins/clean.js b/lib/plugins/clean.js new file mode 100644 index 00000000..487c4440 --- /dev/null +++ b/lib/plugins/clean.js @@ -0,0 +1,30 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const CleanWebpackPlugin = require('clean-webpack-plugin'); + +/** + * @param {WebpackConfig} webpackConfig + * @param {Array} paths to clean + * @param {Object} cleanUpOptions + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig, paths, cleanUpOptions = {}) { + + let config = Object.assign({}, cleanUpOptions, { + root: webpackConfig.outputPath, + verbose: false, + }); + + return [new CleanWebpackPlugin(paths, config)]; + } +}; diff --git a/lib/plugins/common-chunks.js b/lib/plugins/common-chunks.js new file mode 100644 index 00000000..3e125178 --- /dev/null +++ b/lib/plugins/common-chunks.js @@ -0,0 +1,36 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const webpack = require('webpack'); + +/** + * @param {WebpackConfig} webpackConfig + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig) { + + return [new webpack.optimize.CommonsChunkPlugin({ + name: [ + webpackConfig.sharedCommonsEntryName, + /* + * Always dump a 2nd file - manifest.json that + * will contain the webpack manifest information. + * This changes frequently, and without this line, + * it would be packaged inside the "shared commons entry" + * file - e.g. vendor.js, which would prevent long-term caching. + */ + 'manifest' + ], + minChunks: Infinity, + })]; + } +}; diff --git a/lib/plugins/delete-unused-entries.js b/lib/plugins/delete-unused-entries.js new file mode 100644 index 00000000..2700cc2c --- /dev/null +++ b/lib/plugins/delete-unused-entries.js @@ -0,0 +1,26 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const DeleteUnusedEntriesJSPlugin = require('../webpack/delete-unused-entries-js-plugin'); + +/** + * @param {WebpackConfig} webpackConfig + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig) { + + return [new DeleteUnusedEntriesJSPlugin( + // transform into an Array + [... webpackConfig.styleEntries.keys()] + )]; + } +}; diff --git a/lib/plugins/dev-server.js b/lib/plugins/dev-server.js new file mode 100644 index 00000000..07c1995d --- /dev/null +++ b/lib/plugins/dev-server.js @@ -0,0 +1,28 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const pathUtil = require('../config/path-util'); +const AssetOutputDisplayPlugin = require('../friendly-errors/asset-output-display-plugin'); +const FriendlyErrorsPlugin = require('./friendly-errors'); + +/** + * @param {WebpackConfig} webpackConfig + * @param {Array} paths to clean + * @param {Object} cleanUpOptions + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig) { + const outputPath = pathUtil.getRelativeOutputPath(webpackConfig); + const friendlyErrorsPlugin = FriendlyErrorsPlugin.getPlugins(); + return [new AssetOutputDisplayPlugin(outputPath, friendlyErrorsPlugin[0])]; + } +}; diff --git a/lib/plugins/extract-text.js b/lib/plugins/extract-text.js new file mode 100644 index 00000000..3d737087 --- /dev/null +++ b/lib/plugins/extract-text.js @@ -0,0 +1,43 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const ExtractTextPlugin = require('extract-text-webpack-plugin'); + +/** + * @param {WebpackConfig} webpackConfig + * @param {Object} extractTextOptions Options to pass to the plugin + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig, extractTextOptions = {}) { + + /* + * All CSS/SCSS content (due to the loaders above) will be + * extracted into an [entrypointname].css files. The result + * is that NO css will be inlined, *except* CSS that is required + * in an async way (e.g. via require.ensure()). + * + * This may not be ideal in some cases, but it's at least + * predictable. It means that you must manually add a + * link tag for an entry point's CSS (unless no CSS file + * was imported - in which case no CSS file will be dumped). + */ + let config = Object.assign({}, extractTextOptions, { + filename: webpackConfig.useVersioning ? '[name].[contenthash].css' : '[name].css', + // if true, async CSS (e.g. loaded via require.ensure()) + // is extracted to the entry point CSS. If false, it's + // inlined in the AJAX-loaded .js file. + allChunks: false + }); + + return [new ExtractTextPlugin(config)]; + } +}; diff --git a/lib/plugins/friendly-errors.js b/lib/plugins/friendly-errors.js new file mode 100644 index 00000000..ea20ff5b --- /dev/null +++ b/lib/plugins/friendly-errors.js @@ -0,0 +1,47 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); +const missingLoaderTransformer = require('../friendly-errors/transformers/missing-loader'); +const missingLoaderFormatter = require('../friendly-errors/formatters/missing-loader'); +const missingPostCssConfigTransformer = require('../friendly-errors/transformers/missing-postcss-config'); +const missingPostCssConfigFormatter = require('../friendly-errors/formatters/missing-postcss-config'); +const vueUnactivatedLoaderTransformer = require('../friendly-errors/transformers/vue-unactivated-loader-error'); +const vueUnactivatedLoaderFormatter = require('../friendly-errors/formatters/vue-unactivated-loader-error'); + +/** + * @param {WebpackConfig} webpackConfig + * @param {Array} paths to clean + * @param {Object} cleanUpOptions + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins() { + const friendlyErrorsPlugin = new FriendlyErrorsWebpackPlugin({ + clearConsole: false, + additionalTransformers: [ + missingLoaderTransformer, + missingPostCssConfigTransformer, + vueUnactivatedLoaderTransformer + ], + additionalFormatters: [ + missingLoaderFormatter, + missingPostCssConfigFormatter, + vueUnactivatedLoaderFormatter + ], + compilationSuccessInfo: { + messages: [] + } + }); + + return [friendlyErrorsPlugin]; + } +}; diff --git a/lib/plugins/loader-options.js b/lib/plugins/loader-options.js new file mode 100644 index 00000000..f34cfb35 --- /dev/null +++ b/lib/plugins/loader-options.js @@ -0,0 +1,38 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const webpack = require('webpack'); + +/** + * @param {WebpackConfig} webpackConfig + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig) { + + /* + * This section is a bit mysterious. The "minimize" + * true is read and used to minify the CSS. + * But as soon as this plugin is included + * at all, SASS begins to have errors, until the context + * and output options are specified. At this time, I'm + * not totally sure what's going on here + * https://github.com/jtangelder/sass-loader/issues/285 + */ + return [new webpack.LoaderOptionsPlugin({ + debug: !webpackConfig.isProduction(), + options: { + context: webpackConfig.getContext(), + output: { path: webpackConfig.outputPath } + } + })]; + } +}; diff --git a/lib/plugins/manifest.js b/lib/plugins/manifest.js new file mode 100644 index 00000000..22fae8ea --- /dev/null +++ b/lib/plugins/manifest.js @@ -0,0 +1,35 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const ManifestPlugin = require('../webpack/webpack-manifest-plugin'); + +/** + * @param {WebpackConfig} webpackConfig + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig) { + + let manifestPrefix = webpackConfig.manifestKeyPrefix; + if (null === manifestPrefix) { + // by convention, we remove the opening slash on the manifest keys + manifestPrefix = webpackConfig.publicPath.replace(/^\//,''); + } + + return [new ManifestPlugin({ + basePath: manifestPrefix, + // guarantee the value uses the public path (or CDN public path) + publicPath: webpackConfig.getRealPublicPath(), + // always write a manifest.json file, even with webpack-dev-server + writeToFileEmit: true, + })]; + } +}; diff --git a/lib/plugins/production.js b/lib/plugins/production.js new file mode 100644 index 00000000..7889faad --- /dev/null +++ b/lib/plugins/production.js @@ -0,0 +1,35 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const webpack = require('webpack'); + +/** + * @param {WebpackConfig} webpackConfig + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig, defineOptions = {}, uglifyOptions = {}) { + + let defineConfig = Object.assign({}, defineOptions, { + 'process.env': { + NODE_ENV: '"production"' + } + }); + let define = new webpack.DefinePlugin(defineConfig); + + let uglifyConfig = Object.assign({}, uglifyOptions, { + sourceMap: webpackConfig.useSourceMaps + }); + let uglify = new webpack.optimize.UglifyJsPlugin(uglifyConfig); + + return [define, uglify]; + } +}; diff --git a/lib/plugins/variable-provider.js b/lib/plugins/variable-provider.js new file mode 100644 index 00000000..9aafd5ec --- /dev/null +++ b/lib/plugins/variable-provider.js @@ -0,0 +1,22 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const webpack = require('webpack'); + +/** + * @param {WebpackConfig} webpackConfig + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig) { + return [new webpack.ProvidePlugin(webpackConfig.providedVariables)]; + } +}; diff --git a/lib/plugins/versioning.js b/lib/plugins/versioning.js new file mode 100644 index 00000000..f498fddc --- /dev/null +++ b/lib/plugins/versioning.js @@ -0,0 +1,63 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const webpack = require('webpack'); +const WebpackChunkHash = require('webpack-chunk-hash'); + +/** + * @param {WebpackConfig} webpackConfig + * @return {Array} of plugins to add to webpack + */ +module.exports = { + getPlugins(webpackConfig) { + + let plugins = []; + + /* + * With versioning, the "chunkhash" used in the filenames and + * the module ids (i.e. the internal names of modules that + * are required) become important. Specifically: + * + * 1) If the contents of a module don't change, then you don't want its + * internal module id to change. Otherwise, whatever file holds the + * webpack "manifest" will change because the module id will change. + * Solved by HashedModuleIdsPlugin or NamedModulesPlugin + * + * 2) Similarly, if the final contents of a file don't change, + * then we also don't want that file to have a new filename. + * The WebpackChunkHash() handles this, by making sure that + * the chunkhash is based off of the file contents. + * + * Even in the webpack community, the ideal setup seems to be + * a bit of a mystery: + * * https://github.com/webpack/webpack/issues/1315 + * * https://github.com/webpack/webpack.js.org/issues/652#issuecomment-273324529 + * * https://webpack.js.org/guides/caching/#deterministic-hashes + */ + if (webpackConfig.isProduction()) { + // shorter, and obfuscated module ids (versus NamedModulesPlugin) + // makes the final assets *slightly* larger, but prevents contents + // from sometimes changing when nothing really changed + plugins.push(new webpack.HashedModuleIdsPlugin()); + } else { + // human-readable module names, helps debug in HMR + // enable always when not in production for consistency + plugins.push(new webpack.NamedModulesPlugin()); + } + + if (webpackConfig.useVersioning) { + // enables the [chunkhash] ability + plugins.push(new WebpackChunkHash()); + } + + return plugins; + } +}; From 2cd7e0ce4d966dee16bda9f86a4c61dbbcef48d0 Mon Sep 17 00:00:00 2001 From: David Paz Date: Fri, 21 Jul 2017 22:44:13 +0200 Subject: [PATCH 02/25] Rename plugin asset output display --- lib/config-generator.js | 4 ++-- lib/plugins/{dev-server.js => asset-output-display.js} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename lib/plugins/{dev-server.js => asset-output-display.js} (100%) diff --git a/lib/config-generator.js b/lib/config-generator.js index 0c2e9aaf..04520927 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -29,7 +29,7 @@ const cleanPluginUtil = require('./plugins/clean'); const commonChunksPluginUtil = require('./plugins/common-chunks'); const productionPluginUtil = require('./plugins/production'); const friendlyErrorPluginUtil = require('./plugins/friendly-errors'); -const devServerPluginUtil = require('./plugins/dev-server'); +const assetOutputDisplay = require('./plugins/asset-output-display'); class ConfigGenerator { /** @@ -231,7 +231,7 @@ class ConfigGenerator { if (!this.webpackConfig.useDevServer()) { plugins = plugins.concat( - devServerPluginUtil.getPlugins(this.webpackConfig) + assetOutputDisplay.getPlugins(this.webpackConfig) ); } diff --git a/lib/plugins/dev-server.js b/lib/plugins/asset-output-display.js similarity index 100% rename from lib/plugins/dev-server.js rename to lib/plugins/asset-output-display.js From 3e3abdbc824c53ab70e73dffdb00321dfde917e0 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 09:50:37 +0200 Subject: [PATCH 03/25] Refactor clean output plugin configuration Make module export factory method modifying the plugis array to build. --- lib/plugins/clean.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/plugins/clean.js b/lib/plugins/clean.js index 487c4440..930812f7 100644 --- a/lib/plugins/clean.js +++ b/lib/plugins/clean.js @@ -12,19 +12,24 @@ const CleanWebpackPlugin = require('clean-webpack-plugin'); /** - * @param {WebpackConfig} webpackConfig + * Updates plugins array passed adding CleanWebpackPlugin instance + * + * @param {Array} plugins to push to + * @param {WebpackConfig} webpackConfig read only variable * @param {Array} paths to clean * @param {Object} cleanUpOptions - * @return {Array} of plugins to add to webpack + * @return {void} */ -module.exports = { - getPlugins(webpackConfig, paths, cleanUpOptions = {}) { - - let config = Object.assign({}, cleanUpOptions, { - root: webpackConfig.outputPath, - verbose: false, - }); +module.exports = function(plugins, webpackConfig, paths, cleanUpOptions = {}) { - return [new CleanWebpackPlugin(paths, config)]; + if (!webpackConfig.cleanupOutput) { + return; } + + let config = Object.assign({}, cleanUpOptions, { + root: webpackConfig.outputPath, + verbose: false, + }); + + plugins.push(new CleanWebpackPlugin(paths, config)); }; From 8e7ec3d9a0ceb72bbd776cf19f03d7258c179a1e Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 09:51:53 +0200 Subject: [PATCH 04/25] Refactor config-gernerator to use clean output factory --- lib/config-generator.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 04520927..95942eb5 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -207,11 +207,7 @@ class ConfigGenerator { ); } - if (this.webpackConfig.cleanupOutput) { - plugins = plugins.concat( - cleanPluginUtil.getPlugins(this.webpackConfig, ['**/*']) - ); - } + cleanPluginUtil(plugins, this.webpackConfig, ['**/*']); // if we're extracting a vendor chunk, set it up! if (this.webpackConfig.sharedCommonsEntryName) { From 2661c81f39ff8ee5b5fa83f8072702cfbf9e56ee Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 10:28:02 +0200 Subject: [PATCH 05/25] Refactor friendly error plugin configuration --- lib/plugins/friendly-errors.js | 43 ++++++++++++++-------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/lib/plugins/friendly-errors.js b/lib/plugins/friendly-errors.js index ea20ff5b..2962855b 100644 --- a/lib/plugins/friendly-errors.js +++ b/lib/plugins/friendly-errors.js @@ -18,30 +18,23 @@ const vueUnactivatedLoaderTransformer = require('../friendly-errors/transformers const vueUnactivatedLoaderFormatter = require('../friendly-errors/formatters/vue-unactivated-loader-error'); /** - * @param {WebpackConfig} webpackConfig - * @param {Array} paths to clean - * @param {Object} cleanUpOptions - * @return {Array} of plugins to add to webpack + * @return {FriendlyErrorsWebpackPlugin} */ -module.exports = { - getPlugins() { - const friendlyErrorsPlugin = new FriendlyErrorsWebpackPlugin({ - clearConsole: false, - additionalTransformers: [ - missingLoaderTransformer, - missingPostCssConfigTransformer, - vueUnactivatedLoaderTransformer - ], - additionalFormatters: [ - missingLoaderFormatter, - missingPostCssConfigFormatter, - vueUnactivatedLoaderFormatter - ], - compilationSuccessInfo: { - messages: [] - } - }); - - return [friendlyErrorsPlugin]; - } +module.exports = function() { + return new FriendlyErrorsWebpackPlugin({ + clearConsole: false, + additionalTransformers: [ + missingLoaderTransformer, + missingPostCssConfigTransformer, + vueUnactivatedLoaderTransformer + ], + additionalFormatters: [ + missingLoaderFormatter, + missingPostCssConfigFormatter, + vueUnactivatedLoaderFormatter + ], + compilationSuccessInfo: { + messages: [] + } + }); }; From 55a321e50291d383992fda3eeb047c733ae1aa7b Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 10:29:01 +0200 Subject: [PATCH 06/25] Refactor config generator to use friendly error plugin --- lib/config-generator.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 95942eb5..d3917380 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -223,7 +223,8 @@ class ConfigGenerator { ); } - plugins = plugins.concat(friendlyErrorPluginUtil.getPlugins()); + let friendlyErrorPlugin = friendlyErrorPluginUtil(); + plugins.push(friendlyErrorPlugin); if (!this.webpackConfig.useDevServer()) { plugins = plugins.concat( From 024ac22f6f71b620fb044d42b42f2bf8a6815edf Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 10:32:01 +0200 Subject: [PATCH 07/25] Refactor asset output plugin --- lib/plugins/asset-output-display.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/plugins/asset-output-display.js b/lib/plugins/asset-output-display.js index 07c1995d..69a69f56 100644 --- a/lib/plugins/asset-output-display.js +++ b/lib/plugins/asset-output-display.js @@ -11,18 +11,20 @@ const pathUtil = require('../config/path-util'); const AssetOutputDisplayPlugin = require('../friendly-errors/asset-output-display-plugin'); -const FriendlyErrorsPlugin = require('./friendly-errors'); /** + * Updates plugins array passed adding AssetOutputDisplayPlugin instance + * + * @param {Array} plugins * @param {WebpackConfig} webpackConfig - * @param {Array} paths to clean - * @param {Object} cleanUpOptions - * @return {Array} of plugins to add to webpack + * @param {FriendlyErrorsWebpackPlugin} friendlyErrorsPlugin + * @return {void} */ -module.exports = { - getPlugins(webpackConfig) { - const outputPath = pathUtil.getRelativeOutputPath(webpackConfig); - const friendlyErrorsPlugin = FriendlyErrorsPlugin.getPlugins(); - return [new AssetOutputDisplayPlugin(outputPath, friendlyErrorsPlugin[0])]; +module.exports = function(plugins, webpackConfig, friendlyErrorsPlugin) { + if (webpackConfig.useDevServer()) { + return; } + + const outputPath = pathUtil.getRelativeOutputPath(webpackConfig); + plugins.push(new AssetOutputDisplayPlugin(outputPath, friendlyErrorsPlugin)); }; From 2cc2b0a86dc010645e419768118197a2a16ed8b9 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 10:39:10 +0200 Subject: [PATCH 08/25] Refactor config generator to use asset output display --- lib/config-generator.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index d3917380..742e11e4 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -226,11 +226,7 @@ class ConfigGenerator { let friendlyErrorPlugin = friendlyErrorPluginUtil(); plugins.push(friendlyErrorPlugin); - if (!this.webpackConfig.useDevServer()) { - plugins = plugins.concat( - assetOutputDisplay.getPlugins(this.webpackConfig) - ); - } + assetOutputDisplay(plugins, this.webpackConfig, friendlyErrorPlugin); this.webpackConfig.plugins.forEach(function(plugin) { plugins.push(plugin); From ac3f89cdfe2adb05558309d198eb2da909175111 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 11:24:00 +0200 Subject: [PATCH 09/25] Refactor common chunks configuration --- lib/config-generator.js | 4 +--- lib/plugins/common-chunks.js | 38 ++++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 742e11e4..b5b5ad96 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -211,9 +211,7 @@ class ConfigGenerator { // if we're extracting a vendor chunk, set it up! if (this.webpackConfig.sharedCommonsEntryName) { - plugins = plugins.concat( - commonChunksPluginUtil.getPlugins(this.webpackConfig) - ); + commonChunksPluginUtil(plugins, this.webpackConfig); } if (this.webpackConfig.isProduction()) { diff --git a/lib/plugins/common-chunks.js b/lib/plugins/common-chunks.js index 3e125178..e1d34d23 100644 --- a/lib/plugins/common-chunks.js +++ b/lib/plugins/common-chunks.js @@ -12,25 +12,29 @@ const webpack = require('webpack'); /** + * @param {Array} plugins * @param {WebpackConfig} webpackConfig - * @return {Array} of plugins to add to webpack + * @return {void} */ -module.exports = { - getPlugins(webpackConfig) { +module.exports = function(plugins, webpackConfig) { - return [new webpack.optimize.CommonsChunkPlugin({ - name: [ - webpackConfig.sharedCommonsEntryName, - /* - * Always dump a 2nd file - manifest.json that - * will contain the webpack manifest information. - * This changes frequently, and without this line, - * it would be packaged inside the "shared commons entry" - * file - e.g. vendor.js, which would prevent long-term caching. - */ - 'manifest' - ], - minChunks: Infinity, - })]; + if (!webpackConfig.sharedCommonsEntryName) { + return; } + + // if we're extracting a vendor chunk, set it up! + plugins.push(new webpack.optimize.CommonsChunkPlugin({ + name: [ + webpackConfig.sharedCommonsEntryName, + /* + * Always dump a 2nd file - manifest.json that + * will contain the webpack manifest information. + * This changes frequently, and without this line, + * it would be packaged inside the "shared commons entry" + * file - e.g. vendor.js, which would prevent long-term caching. + */ + 'manifest' + ], + minChunks: Infinity, + })); }; From dea32110e07f81a4e3b4667ac62367b62bec9d01 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 11:25:44 +0200 Subject: [PATCH 10/25] Refactor config generator to use comon chunks --- lib/config-generator.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index b5b5ad96..0ec70007 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -209,10 +209,7 @@ class ConfigGenerator { cleanPluginUtil(plugins, this.webpackConfig, ['**/*']); - // if we're extracting a vendor chunk, set it up! - if (this.webpackConfig.sharedCommonsEntryName) { - commonChunksPluginUtil(plugins, this.webpackConfig); - } + commonChunksPluginUtil(plugins, this.webpackConfig); if (this.webpackConfig.isProduction()) { // todo - options here should be configurable From 930bd21a56b6537fb463ba58681816e60e0fb960 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 12:08:25 +0200 Subject: [PATCH 11/25] Refactor unused entries plugin configuration --- lib/plugins/delete-unused-entries.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/plugins/delete-unused-entries.js b/lib/plugins/delete-unused-entries.js index 2700cc2c..e77a26bb 100644 --- a/lib/plugins/delete-unused-entries.js +++ b/lib/plugins/delete-unused-entries.js @@ -12,15 +12,14 @@ const DeleteUnusedEntriesJSPlugin = require('../webpack/delete-unused-entries-js-plugin'); /** + * @param {Array} plugins * @param {WebpackConfig} webpackConfig - * @return {Array} of plugins to add to webpack + * @return {void} */ -module.exports = { - getPlugins(webpackConfig) { +module.exports = function(plugins, webpackConfig) { - return [new DeleteUnusedEntriesJSPlugin( - // transform into an Array - [... webpackConfig.styleEntries.keys()] - )]; - } + plugins.push(new DeleteUnusedEntriesJSPlugin( + // transform into an Array + [... webpackConfig.styleEntries.keys()] + )); }; From 8d63ab797867014a00ae40725e5911bcd4b5f5d1 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 12:09:01 +0200 Subject: [PATCH 12/25] Refactor config generator to use unused entries --- lib/config-generator.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 0ec70007..5481fec7 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -184,9 +184,7 @@ class ConfigGenerator { ); // register the pure-style entries that should be deleted - plugins = plugins.concat( - deleteUnusedEntriesPluginUtil.getPlugins(this.webpackConfig) - ); + deleteUnusedEntriesPluginUtil(plugins, this.webpackConfig); // Dump the manifest.json file plugins = plugins.concat( From c5953cfd8da24a333a39230ad2591f7036b9d6ae Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 13:24:53 +0200 Subject: [PATCH 13/25] Refactor extract text plugin configuration --- lib/plugins/extract-text.js | 45 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/lib/plugins/extract-text.js b/lib/plugins/extract-text.js index 3d737087..9a43924c 100644 --- a/lib/plugins/extract-text.js +++ b/lib/plugins/extract-text.js @@ -12,32 +12,31 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin'); /** + * @param {Array} plugins * @param {WebpackConfig} webpackConfig * @param {Object} extractTextOptions Options to pass to the plugin - * @return {Array} of plugins to add to webpack + * @return {void} */ -module.exports = { - getPlugins(webpackConfig, extractTextOptions = {}) { +module.exports = function(plugins, webpackConfig, extractTextOptions = {}) { - /* - * All CSS/SCSS content (due to the loaders above) will be - * extracted into an [entrypointname].css files. The result - * is that NO css will be inlined, *except* CSS that is required - * in an async way (e.g. via require.ensure()). - * - * This may not be ideal in some cases, but it's at least - * predictable. It means that you must manually add a - * link tag for an entry point's CSS (unless no CSS file - * was imported - in which case no CSS file will be dumped). - */ - let config = Object.assign({}, extractTextOptions, { - filename: webpackConfig.useVersioning ? '[name].[contenthash].css' : '[name].css', - // if true, async CSS (e.g. loaded via require.ensure()) - // is extracted to the entry point CSS. If false, it's - // inlined in the AJAX-loaded .js file. - allChunks: false - }); + /* + * All CSS/SCSS content (due to the loaders above) will be + * extracted into an [entrypointname].css files. The result + * is that NO css will be inlined, *except* CSS that is required + * in an async way (e.g. via require.ensure()). + * + * This may not be ideal in some cases, but it's at least + * predictable. It means that you must manually add a + * link tag for an entry point's CSS (unless no CSS file + * was imported - in which case no CSS file will be dumped). + */ + let config = Object.assign({}, extractTextOptions, { + filename: webpackConfig.useVersioning ? '[name].[contenthash].css' : '[name].css', + // if true, async CSS (e.g. loaded via require.ensure()) + // is extracted to the entry point CSS. If false, it's + // inlined in the AJAX-loaded .js file. + allChunks: false + }); - return [new ExtractTextPlugin(config)]; - } + plugins.push(new ExtractTextPlugin(config)); }; From effd69364dc1f102802f74c4b71ca4435158e6cb Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 13:27:11 +0200 Subject: [PATCH 14/25] Refactor config generator to use extract assets --- lib/config-generator.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 5481fec7..bd1ba9c0 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -179,9 +179,7 @@ class ConfigGenerator { buildPluginsConfig() { let plugins = []; - plugins = plugins.concat( - extractTextPluginUtil.getPlugins(this.webpackConfig) - ); + extractTextPluginUtil(plugins, this.webpackConfig); // register the pure-style entries that should be deleted deleteUnusedEntriesPluginUtil(plugins, this.webpackConfig); From c2b3280b94e1df2cffb70fe33fb042e39e97c8a6 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 13:37:20 +0200 Subject: [PATCH 15/25] Refactor loader options configuration plugin --- lib/plugins/loader-options.js | 39 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/plugins/loader-options.js b/lib/plugins/loader-options.js index f34cfb35..c9cce7ae 100644 --- a/lib/plugins/loader-options.js +++ b/lib/plugins/loader-options.js @@ -12,27 +12,26 @@ const webpack = require('webpack'); /** + * @param {Array} plugins * @param {WebpackConfig} webpackConfig - * @return {Array} of plugins to add to webpack + * @return {void} */ -module.exports = { - getPlugins(webpackConfig) { +module.exports = function(plugins, webpackConfig) { - /* - * This section is a bit mysterious. The "minimize" - * true is read and used to minify the CSS. - * But as soon as this plugin is included - * at all, SASS begins to have errors, until the context - * and output options are specified. At this time, I'm - * not totally sure what's going on here - * https://github.com/jtangelder/sass-loader/issues/285 - */ - return [new webpack.LoaderOptionsPlugin({ - debug: !webpackConfig.isProduction(), - options: { - context: webpackConfig.getContext(), - output: { path: webpackConfig.outputPath } - } - })]; - } + /* + * This section is a bit mysterious. The "minimize" + * true is read and used to minify the CSS. + * But as soon as this plugin is included + * at all, SASS begins to have errors, until the context + * and output options are specified. At this time, I'm + * not totally sure what's going on here + * https://github.com/jtangelder/sass-loader/issues/285 + */ + plugins.push(new webpack.LoaderOptionsPlugin({ + debug: !webpackConfig.isProduction(), + options: { + context: webpackConfig.getContext(), + output: {path: webpackConfig.outputPath} + } + })); }; From 74489eb00f37f7ef847f80a85a3561a482a041d9 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 13:37:44 +0200 Subject: [PATCH 16/25] refactor config geerator to use loader options --- lib/config-generator.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index bd1ba9c0..83b1c3c1 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -189,9 +189,7 @@ class ConfigGenerator { manifestPluginUtil.getPlugins(this.webpackConfig) ); - plugins = plugins.concat( - loaderOptionsPluginUtil.getPlugins(this.webpackConfig) - ); + loaderOptionsPluginUtil(plugins, this.webpackConfig); plugins = plugins.concat( versioningPluginUtil.getPlugins(this.webpackConfig) From 37a6dc7e9d5173c4b7112084c3c8021dce2f6d52 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 13:42:57 +0200 Subject: [PATCH 17/25] Refactor manifest plugin configuration --- lib/plugins/manifest.js | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/plugins/manifest.js b/lib/plugins/manifest.js index 22fae8ea..97f78e31 100644 --- a/lib/plugins/manifest.js +++ b/lib/plugins/manifest.js @@ -12,24 +12,23 @@ const ManifestPlugin = require('../webpack/webpack-manifest-plugin'); /** + * @param {Array} plugins * @param {WebpackConfig} webpackConfig - * @return {Array} of plugins to add to webpack + * @return {void} */ -module.exports = { - getPlugins(webpackConfig) { +module.exports = function(plugins, webpackConfig) { - let manifestPrefix = webpackConfig.manifestKeyPrefix; - if (null === manifestPrefix) { - // by convention, we remove the opening slash on the manifest keys - manifestPrefix = webpackConfig.publicPath.replace(/^\//,''); - } - - return [new ManifestPlugin({ - basePath: manifestPrefix, - // guarantee the value uses the public path (or CDN public path) - publicPath: webpackConfig.getRealPublicPath(), - // always write a manifest.json file, even with webpack-dev-server - writeToFileEmit: true, - })]; + let manifestPrefix = webpackConfig.manifestKeyPrefix; + if (null === manifestPrefix) { + // by convention, we remove the opening slash on the manifest keys + manifestPrefix = webpackConfig.publicPath.replace(/^\//, ''); } + + plugins.push(new ManifestPlugin({ + basePath: manifestPrefix, + // guarantee the value uses the public path (or CDN public path) + publicPath: webpackConfig.getRealPublicPath(), + // always write a manifest.json file, even with webpack-dev-server + writeToFileEmit: true, + })); }; From 2e63a3463cf90456e317dd2c418190a9d7561277 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 13:43:41 +0200 Subject: [PATCH 18/25] Refactor config generator to use manifest --- lib/config-generator.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 83b1c3c1..0bab9432 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -185,9 +185,7 @@ class ConfigGenerator { deleteUnusedEntriesPluginUtil(plugins, this.webpackConfig); // Dump the manifest.json file - plugins = plugins.concat( - manifestPluginUtil.getPlugins(this.webpackConfig) - ); + manifestPluginUtil(plugins, this.webpackConfig); loaderOptionsPluginUtil(plugins, this.webpackConfig); From 52f2c96a8732bd1e196b6e07a064f8dc8157b40e Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 14:51:27 +0200 Subject: [PATCH 19/25] Refactor define and uglify configuration plugins --- lib/plugins/define.js | 34 ++++++++++++++++++++++++++++++++++ lib/plugins/production.js | 35 ----------------------------------- lib/plugins/uglify.js | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 35 deletions(-) create mode 100644 lib/plugins/define.js delete mode 100644 lib/plugins/production.js create mode 100644 lib/plugins/uglify.js diff --git a/lib/plugins/define.js b/lib/plugins/define.js new file mode 100644 index 00000000..9a5556b7 --- /dev/null +++ b/lib/plugins/define.js @@ -0,0 +1,34 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const webpack = require('webpack'); + +/** + * @param {Array} plugins + * @param {WebpackConfig} webpackConfig + * @param {Object} defineOptions + * @return {void} + */ +module.exports = function(plugins, webpackConfig, defineOptions = {}) { + + if (!webpackConfig.isProduction()) { + return; + } + + let defineConfig = Object.assign({}, defineOptions, { + 'process.env': { + NODE_ENV: '"production"' + } + }); + let define = new webpack.DefinePlugin(defineConfig); + + plugins.push(define); +}; diff --git a/lib/plugins/production.js b/lib/plugins/production.js deleted file mode 100644 index 7889faad..00000000 --- a/lib/plugins/production.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -'use strict'; - -const webpack = require('webpack'); - -/** - * @param {WebpackConfig} webpackConfig - * @return {Array} of plugins to add to webpack - */ -module.exports = { - getPlugins(webpackConfig, defineOptions = {}, uglifyOptions = {}) { - - let defineConfig = Object.assign({}, defineOptions, { - 'process.env': { - NODE_ENV: '"production"' - } - }); - let define = new webpack.DefinePlugin(defineConfig); - - let uglifyConfig = Object.assign({}, uglifyOptions, { - sourceMap: webpackConfig.useSourceMaps - }); - let uglify = new webpack.optimize.UglifyJsPlugin(uglifyConfig); - - return [define, uglify]; - } -}; diff --git a/lib/plugins/uglify.js b/lib/plugins/uglify.js new file mode 100644 index 00000000..3204fcf3 --- /dev/null +++ b/lib/plugins/uglify.js @@ -0,0 +1,32 @@ +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +'use strict'; + +const webpack = require('webpack'); + +/** + * @param {Array} plugins + * @param {WebpackConfig} webpackConfig + * @param {Object} uglifyOptions + * @return {void} + */ +module.exports = function(plugins, webpackConfig, uglifyOptions = {}) { + + if (!webpackConfig.isProduction()) { + return; + } + + let uglifyConfig = Object.assign({}, uglifyOptions, { + sourceMap: webpackConfig.useSourceMaps + }); + let uglify = new webpack.optimize.UglifyJsPlugin(uglifyConfig); + + plugins.push(uglify); +}; From 31280bbc9f25fa39e98310efc4da63bbdf98eae2 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 14:51:51 +0200 Subject: [PATCH 20/25] Refactor config generator to use define and uglify --- lib/config-generator.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 0bab9432..590add49 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -27,7 +27,8 @@ const versioningPluginUtil = require('./plugins/versioning'); const variableProviderPluginUtil = require('./plugins/variable-provider'); const cleanPluginUtil = require('./plugins/clean'); const commonChunksPluginUtil = require('./plugins/common-chunks'); -const productionPluginUtil = require('./plugins/production'); +const definePluginUtil = require('./plugins/define'); +const uglifyPluginUtil = require('./plugins/uglify'); const friendlyErrorPluginUtil = require('./plugins/friendly-errors'); const assetOutputDisplay = require('./plugins/asset-output-display'); @@ -203,12 +204,9 @@ class ConfigGenerator { commonChunksPluginUtil(plugins, this.webpackConfig); - if (this.webpackConfig.isProduction()) { - // todo - options here should be configurable - plugins = plugins.concat( - productionPluginUtil.getPlugins(this.webpackConfig) - ); - } + // todo - options here should be configurable + definePluginUtil(plugins, this.webpackConfig); + uglifyPluginUtil(plugins, this.webpackConfig); let friendlyErrorPlugin = friendlyErrorPluginUtil(); plugins.push(friendlyErrorPlugin); From 562b98ee8a1591cfba87d47e8c7c0f4be5b94498 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 15:43:34 +0200 Subject: [PATCH 21/25] Refactor variables provider configuration plugin --- lib/plugins/variable-provider.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/plugins/variable-provider.js b/lib/plugins/variable-provider.js index 9aafd5ec..f844b166 100644 --- a/lib/plugins/variable-provider.js +++ b/lib/plugins/variable-provider.js @@ -12,11 +12,12 @@ const webpack = require('webpack'); /** + * @param {Array} plugins * @param {WebpackConfig} webpackConfig * @return {Array} of plugins to add to webpack */ -module.exports = { - getPlugins(webpackConfig) { - return [new webpack.ProvidePlugin(webpackConfig.providedVariables)]; +module.exports = function(plugins, webpackConfig) { + if (Object.keys(webpackConfig.providedVariables).length > 0) { + plugins.push(new webpack.ProvidePlugin(webpackConfig.providedVariables)); } }; From 796aca6bb879e3e7311ea9288e103c26b6937483 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 15:47:14 +0200 Subject: [PATCH 22/25] Refactor config generator to use variable provider --- lib/config-generator.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 590add49..922be9d8 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -194,11 +194,7 @@ class ConfigGenerator { versioningPluginUtil.getPlugins(this.webpackConfig) ); - if (Object.keys(this.webpackConfig.providedVariables).length > 0) { - plugins = plugins.concat( - variableProviderPluginUtil.getPlugins(this.webpackConfig) - ); - } + variableProviderPluginUtil(plugins, this.webpackConfig); cleanPluginUtil(plugins, this.webpackConfig, ['**/*']); From 63972a4a1d8b538ac7ea5f1dfb167647106e87a5 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 15:53:32 +0200 Subject: [PATCH 23/25] Refactor version configuration plugin --- lib/plugins/versioning.js | 79 ++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/lib/plugins/versioning.js b/lib/plugins/versioning.js index f498fddc..42b16008 100644 --- a/lib/plugins/versioning.js +++ b/lib/plugins/versioning.js @@ -13,51 +13,46 @@ const webpack = require('webpack'); const WebpackChunkHash = require('webpack-chunk-hash'); /** + * @param {Array} plugins * @param {WebpackConfig} webpackConfig - * @return {Array} of plugins to add to webpack + * @return {void} */ -module.exports = { - getPlugins(webpackConfig) { +module.exports = function(plugins, webpackConfig) { - let plugins = []; - - /* - * With versioning, the "chunkhash" used in the filenames and - * the module ids (i.e. the internal names of modules that - * are required) become important. Specifically: - * - * 1) If the contents of a module don't change, then you don't want its - * internal module id to change. Otherwise, whatever file holds the - * webpack "manifest" will change because the module id will change. - * Solved by HashedModuleIdsPlugin or NamedModulesPlugin - * - * 2) Similarly, if the final contents of a file don't change, - * then we also don't want that file to have a new filename. - * The WebpackChunkHash() handles this, by making sure that - * the chunkhash is based off of the file contents. - * - * Even in the webpack community, the ideal setup seems to be - * a bit of a mystery: - * * https://github.com/webpack/webpack/issues/1315 - * * https://github.com/webpack/webpack.js.org/issues/652#issuecomment-273324529 - * * https://webpack.js.org/guides/caching/#deterministic-hashes - */ - if (webpackConfig.isProduction()) { - // shorter, and obfuscated module ids (versus NamedModulesPlugin) - // makes the final assets *slightly* larger, but prevents contents - // from sometimes changing when nothing really changed - plugins.push(new webpack.HashedModuleIdsPlugin()); - } else { - // human-readable module names, helps debug in HMR - // enable always when not in production for consistency - plugins.push(new webpack.NamedModulesPlugin()); - } - - if (webpackConfig.useVersioning) { - // enables the [chunkhash] ability - plugins.push(new WebpackChunkHash()); - } + /* + * With versioning, the "chunkhash" used in the filenames and + * the module ids (i.e. the internal names of modules that + * are required) become important. Specifically: + * + * 1) If the contents of a module don't change, then you don't want its + * internal module id to change. Otherwise, whatever file holds the + * webpack "manifest" will change because the module id will change. + * Solved by HashedModuleIdsPlugin or NamedModulesPlugin + * + * 2) Similarly, if the final contents of a file don't change, + * then we also don't want that file to have a new filename. + * The WebpackChunkHash() handles this, by making sure that + * the chunkhash is based off of the file contents. + * + * Even in the webpack community, the ideal setup seems to be + * a bit of a mystery: + * * https://github.com/webpack/webpack/issues/1315 + * * https://github.com/webpack/webpack.js.org/issues/652#issuecomment-273324529 + * * https://webpack.js.org/guides/caching/#deterministic-hashes + */ + if (webpackConfig.isProduction()) { + // shorter, and obfuscated module ids (versus NamedModulesPlugin) + // makes the final assets *slightly* larger, but prevents contents + // from sometimes changing when nothing really changed + plugins.push(new webpack.HashedModuleIdsPlugin()); + } else { + // human-readable module names, helps debug in HMR + // enable always when not in production for consistency + plugins.push(new webpack.NamedModulesPlugin()); + } - return plugins; + if (webpackConfig.useVersioning) { + // enables the [chunkhash] ability + plugins.push(new WebpackChunkHash()); } }; From b650032b4edea19adbbb913739b1d9377a8a6db3 Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 15:54:33 +0200 Subject: [PATCH 24/25] Refactor config generator to use versioning --- lib/config-generator.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 922be9d8..7055b5b3 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -190,9 +190,7 @@ class ConfigGenerator { loaderOptionsPluginUtil(plugins, this.webpackConfig); - plugins = plugins.concat( - versioningPluginUtil.getPlugins(this.webpackConfig) - ); + versioningPluginUtil(plugins, this.webpackConfig); variableProviderPluginUtil(plugins, this.webpackConfig); From 8098aa62e4d71eac3289edeb31858da4697a2c5d Mon Sep 17 00:00:00 2001 From: David Paz Date: Sun, 23 Jul 2017 16:08:42 +0200 Subject: [PATCH 25/25] Fix loader options linting error --- lib/plugins/loader-options.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/loader-options.js b/lib/plugins/loader-options.js index c9cce7ae..d9ae3dff 100644 --- a/lib/plugins/loader-options.js +++ b/lib/plugins/loader-options.js @@ -31,7 +31,7 @@ module.exports = function(plugins, webpackConfig) { debug: !webpackConfig.isProduction(), options: { context: webpackConfig.getContext(), - output: {path: webpackConfig.outputPath} + output: { path: webpackConfig.outputPath } } })); };