From dbe8d39fa284021795c210fb39ffd51acdae8d70 Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Mon, 7 Jan 2019 17:17:48 +0100 Subject: [PATCH 1/5] feat: implement dev-server watchOptions configuration --- index.js | 21 +++++++++++++++++++++ lib/WebpackConfig.js | 9 +++++++++ lib/config-generator.js | 9 ++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index c05e3587..3afbe597 100644 --- a/index.js +++ b/index.js @@ -588,6 +588,27 @@ class Encore { return this; } + /** + * Configure the devServer.watchOptions configuration, only when the dev server is running. + * + * https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + * https://webpack.js.org/configuration/watch/ + * + * Encore.configureDevServerWatchOptions(function(watchOptions) { + * // change the configuration + * + * watchOptions.poll = 250; + * }); + * + * @param {function} callback + * @returns {Encore} + */ + configureDevServerWatchOptions(callback) { + webpackConfig.configureDevServerWatchOptions(callback); + + return this; + } + /** * Automatically make some variables available everywhere! * diff --git a/lib/WebpackConfig.js b/lib/WebpackConfig.js index 3ecef9f9..319fcab8 100644 --- a/lib/WebpackConfig.js +++ b/lib/WebpackConfig.js @@ -94,6 +94,7 @@ class WebpackConfig { this.shouldUseSingleRuntimeChunk = null; this.shouldSplitEntryChunks = false; this.splitChunksConfigurationCallback = () => {}; + this.devServerWatchOptionsConfigurationCallback = () => {}; this.vueLoaderOptionsCallback = () => {}; this.eslintLoaderOptionsCallback = () => {}; this.tsConfigurationCallback = () => {}; @@ -395,6 +396,14 @@ class WebpackConfig { this.splitChunksConfigurationCallback = callback; } + configureDevServerWatchOptions(callback) { + if (typeof callback !== 'function') { + throw new Error('Argument 1 to configureDevServerWatchOptions() must be a callback function.'); + } + + this.devServerWatchOptionsConfigurationCallback = callback; + } + createSharedEntry(name, file) { if (this.shouldSplitEntryChunks) { throw new Error('Using splitEntryChunks() and createSharedEntry() together is not supported. Use one of these strategies only to optimize your build.'); diff --git a/lib/config-generator.js b/lib/config-generator.js index 09400d9e..a026704b 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -527,6 +527,11 @@ class ConfigGenerator { buildDevServerConfig() { const contentBase = pathUtil.getContentBase(this.webpackConfig); + const watchOptions = { + ignored: /node_modules/ + }; + + this.webpackConfig.devServerWatchOptionsConfigurationCallback(watchOptions); return { contentBase: contentBase, @@ -539,9 +544,7 @@ class ConfigGenerator { quiet: true, compress: true, historyApiFallback: true, - watchOptions: { - ignored: /node_modules/ - }, + watchOptions: watchOptions, https: this.webpackConfig.useDevServerInHttps() }; } From fd0868a19e0e06eefe2822fa6d474ee90622942f Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Mon, 7 Jan 2019 17:31:06 +0100 Subject: [PATCH 2/5] Add tests --- test/WebpackConfig.js | 25 +++++++++++++++++++++++++ test/config-generator.js | 20 ++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/test/WebpackConfig.js b/test/WebpackConfig.js index 2bd7e8a3..437f9561 100644 --- a/test/WebpackConfig.js +++ b/test/WebpackConfig.js @@ -1065,4 +1065,29 @@ describe('WebpackConfig object', () => { }).to.throw('"foo" is not a valid key'); }); }); + + describe('configureDevServerWatchOptions()', () => { + it('Pass config', () => { + const config = createConfig(); + const callback = (watchOptions) => { + watchOptions.poll = 250; + }; + + config.configureDevServerWatchOptions(callback); + + expect(config.devServerWatchOptionsConfigurationCallback).to.equal(callback); + }); + + it('Call method without a valid callback', () => { + const config = createConfig(); + + expect(() => { + config.configureDevServerWatchOptions(); + }).to.throw('Argument 1 to configureDevServerWatchOptions() must be a callback function.'); + + expect(() => { + config.configureDevServerWatchOptions({}); + }).to.throw('Argument 1 to configureDevServerWatchOptions() must be a callback function.'); + }); + }); }); diff --git a/test/config-generator.js b/test/config-generator.js index 7c97875c..2508be51 100644 --- a/test/config-generator.js +++ b/test/config-generator.js @@ -573,6 +573,26 @@ describe('The config-generator function', () => { const actualConfig = configGenerator(config); expect(actualConfig.devServer.hot).to.be.true; }); + + it('devServer with custom watch options', () => { + const config = createConfig(); + config.runtimeConfig.useDevServer = true; + config.runtimeConfig.devServerUrl = 'http://localhost:8080/'; + config.runtimeConfig.useHotModuleReplacement = true; + config.outputPath = isWindows ? 'C:\\tmp\\public' : '/tmp/public'; + config.setPublicPath('/'); + config.addEntry('main', './main'); + + config.configureDevServerWatchOptions(watchOptions => { + watchOptions.poll = 250; + }); + + const actualConfig = configGenerator(config); + expect(actualConfig.devServer.watchOptions).to.deep.equals({ + 'ignored': /node_modules/, + 'poll': 250, + }); + }); }); describe('test for addPlugin config', () => { From e6eb6e14a6421e90a22524701e015e5a98f04266 Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Mon, 7 Jan 2019 17:42:16 +0100 Subject: [PATCH 3/5] add comment for running watching mode inside a VM --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 3afbe597..f5418293 100644 --- a/index.js +++ b/index.js @@ -597,7 +597,7 @@ class Encore { * Encore.configureDevServerWatchOptions(function(watchOptions) { * // change the configuration * - * watchOptions.poll = 250; + * watchOptions.poll = 250; // useful when running inside a Virtual Machine * }); * * @param {function} callback From bc494197e4eec95c9f3bc50913cd9fc1a85f3687 Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Mon, 7 Jan 2019 17:54:53 +0100 Subject: [PATCH 4/5] Apply watchOptions to webpack config too, not only the dev server --- index.js | 10 +++++----- lib/WebpackConfig.js | 8 ++++---- lib/config-generator.js | 16 +++++++++++----- test/WebpackConfig.js | 14 +++++++------- test/config-generator.js | 23 ++++++++++++++++++++++- 5 files changed, 49 insertions(+), 22 deletions(-) diff --git a/index.js b/index.js index f5418293..bff55168 100644 --- a/index.js +++ b/index.js @@ -589,12 +589,12 @@ class Encore { } /** - * Configure the devServer.watchOptions configuration, only when the dev server is running. + * Configure the watchOptions and devServer.watchOptions configuration. * - * https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- * https://webpack.js.org/configuration/watch/ + * https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- * - * Encore.configureDevServerWatchOptions(function(watchOptions) { + * Encore.configureWatchOptions(function(watchOptions) { * // change the configuration * * watchOptions.poll = 250; // useful when running inside a Virtual Machine @@ -603,8 +603,8 @@ class Encore { * @param {function} callback * @returns {Encore} */ - configureDevServerWatchOptions(callback) { - webpackConfig.configureDevServerWatchOptions(callback); + configureWatchOptions(callback) { + webpackConfig.configureWatchOptions(callback); return this; } diff --git a/lib/WebpackConfig.js b/lib/WebpackConfig.js index 319fcab8..36542bb0 100644 --- a/lib/WebpackConfig.js +++ b/lib/WebpackConfig.js @@ -94,7 +94,7 @@ class WebpackConfig { this.shouldUseSingleRuntimeChunk = null; this.shouldSplitEntryChunks = false; this.splitChunksConfigurationCallback = () => {}; - this.devServerWatchOptionsConfigurationCallback = () => {}; + this.watchOptionsConfigurationCallback = () => {}; this.vueLoaderOptionsCallback = () => {}; this.eslintLoaderOptionsCallback = () => {}; this.tsConfigurationCallback = () => {}; @@ -396,12 +396,12 @@ class WebpackConfig { this.splitChunksConfigurationCallback = callback; } - configureDevServerWatchOptions(callback) { + configureWatchOptions(callback) { if (typeof callback !== 'function') { - throw new Error('Argument 1 to configureDevServerWatchOptions() must be a callback function.'); + throw new Error('Argument 1 to configureWatchOptions() must be a callback function.'); } - this.devServerWatchOptionsConfigurationCallback = callback; + this.watchOptionsConfigurationCallback = callback; } createSharedEntry(name, file) { diff --git a/lib/config-generator.js b/lib/config-generator.js index a026704b..24b91730 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -69,7 +69,8 @@ class ConfigGenerator { rules: this.buildRulesConfig(), }, plugins: this.buildPluginsConfig(), - optimization: this.buildOptimizationConfig() + optimization: this.buildOptimizationConfig(), + watchOptions: this.buildWatchOptionsConfig() }; if (this.webpackConfig.useSourceMaps) { @@ -525,13 +526,18 @@ class ConfigGenerator { return stats; } - buildDevServerConfig() { - const contentBase = pathUtil.getContentBase(this.webpackConfig); + buildWatchOptionsConfig() { const watchOptions = { ignored: /node_modules/ }; - this.webpackConfig.devServerWatchOptionsConfigurationCallback(watchOptions); + this.webpackConfig.watchOptionsConfigurationCallback(watchOptions); + + return watchOptions; + } + + buildDevServerConfig() { + const contentBase = pathUtil.getContentBase(this.webpackConfig); return { contentBase: contentBase, @@ -544,7 +550,7 @@ class ConfigGenerator { quiet: true, compress: true, historyApiFallback: true, - watchOptions: watchOptions, + watchOptions: this.buildWatchOptionsConfig(), https: this.webpackConfig.useDevServerInHttps() }; } diff --git a/test/WebpackConfig.js b/test/WebpackConfig.js index 437f9561..163a11db 100644 --- a/test/WebpackConfig.js +++ b/test/WebpackConfig.js @@ -1066,28 +1066,28 @@ describe('WebpackConfig object', () => { }); }); - describe('configureDevServerWatchOptions()', () => { + describe('configureWatchOptions()', () => { it('Pass config', () => { const config = createConfig(); const callback = (watchOptions) => { watchOptions.poll = 250; }; - config.configureDevServerWatchOptions(callback); + config.configureWatchOptions(callback); - expect(config.devServerWatchOptionsConfigurationCallback).to.equal(callback); + expect(config.watchOptionsConfigurationCallback).to.equal(callback); }); it('Call method without a valid callback', () => { const config = createConfig(); expect(() => { - config.configureDevServerWatchOptions(); - }).to.throw('Argument 1 to configureDevServerWatchOptions() must be a callback function.'); + config.configureWatchOptions(); + }).to.throw('Argument 1 to configureWatchOptions() must be a callback function.'); expect(() => { - config.configureDevServerWatchOptions({}); - }).to.throw('Argument 1 to configureDevServerWatchOptions() must be a callback function.'); + config.configureWatchOptions({}); + }).to.throw('Argument 1 to configureWatchOptions() must be a callback function.'); }); }); }); diff --git a/test/config-generator.js b/test/config-generator.js index 2508be51..c1acc555 100644 --- a/test/config-generator.js +++ b/test/config-generator.js @@ -583,11 +583,15 @@ describe('The config-generator function', () => { config.setPublicPath('/'); config.addEntry('main', './main'); - config.configureDevServerWatchOptions(watchOptions => { + config.configureWatchOptions(watchOptions => { watchOptions.poll = 250; }); const actualConfig = configGenerator(config); + expect(actualConfig.watchOptions).to.deep.equals({ + 'ignored': /node_modules/, + 'poll': 250, + }); expect(actualConfig.devServer.watchOptions).to.deep.equals({ 'ignored': /node_modules/, 'poll': 250, @@ -954,4 +958,21 @@ describe('The config-generator function', () => { expect(JSON.stringify(logger.getMessages().deprecation)).to.contain('the recommended setting is Encore.enableSingleRuntimeChunk()'); }); }); + + describe('Test buildWatchOptionsConfig()', () => { + it('Set webpack watch options', () => { + const config = createConfig(); + config.outputPath = '/tmp/public/build'; + config.setPublicPath('/build/'); + config.configureWatchOptions(watchOptions => { + watchOptions.poll = 250; + }); + + const actualConfig = configGenerator(config); + expect(actualConfig.watchOptions).to.deep.equals({ + ignored: /node_modules/, + poll: 250, + }); + }); + }); }); From 23f3654f4e58d61c6c7998190c67e11e76e97474 Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Mon, 7 Jan 2019 20:13:34 +0100 Subject: [PATCH 5/5] Use applyOptionsCallback --- lib/config-generator.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 24b91730..8aaf540c 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -531,9 +531,10 @@ class ConfigGenerator { ignored: /node_modules/ }; - this.webpackConfig.watchOptionsConfigurationCallback(watchOptions); - - return watchOptions; + return applyOptionsCallback( + this.webpackConfig.watchOptionsConfigurationCallback, + watchOptions + ); } buildDevServerConfig() {