diff --git a/bin/options.js b/bin/options.js index 2c9c761310..46cbd33b6c 100644 --- a/bin/options.js +++ b/bin/options.js @@ -35,6 +35,11 @@ const options = { describe: 'Print compilation progress in percentage', group: BASIC_GROUP, }, + hot: { + type: 'boolean', + describe: 'Enables/disables HMR', + group: ADVANCED_GROUP, + }, 'hot-only': { type: 'boolean', describe: 'Do not refresh page if HMR fails', diff --git a/lib/utils/createConfig.js b/lib/utils/createConfig.js index 3b573536b6..83e742a181 100644 --- a/lib/utils/createConfig.js +++ b/lib/utils/createConfig.js @@ -73,10 +73,11 @@ function createConfig(config, argv, { port }) { process.stdin.resume(); } - // TODO https://github.com/webpack/webpack-dev-server/issues/616 (v4) - // We should prefer CLI arg under config, now we always prefer `hot` from `devServer` - if (!options.hot) { - options.hot = argv.hot; + const hasHot = typeof argv.hot !== 'undefined'; + const hasHotOnly = typeof argv.hotOnly !== 'undefined'; + + if (hasHot || hasHotOnly) { + options.hot = hasHotOnly ? 'only' : argv.hot; } // TODO https://github.com/webpack/webpack-dev-server/issues/616 (v4) diff --git a/test/cli/cli.test.js b/test/cli/cli.test.js index 16eee7a75b..a44ddf7016 100644 --- a/test/cli/cli.test.js +++ b/test/cli/cli.test.js @@ -6,6 +6,36 @@ const execa = require('execa'); const testBin = require('../helpers/test-bin'); describe('CLI', () => { + it('--hot', (done) => { + testBin('--hot') + .then((output) => { + expect(output.exitCode).toEqual(0); + expect(output.stderr).toContain('/hot/dev-server'); + done(); + }) + .catch(done); + }); + + it('--no-hot', (done) => { + testBin('--no-hot') + .then((output) => { + expect(output.exitCode).toEqual(0); + expect(output.stderr).not.toContain('/hot/dev-server'); + done(); + }) + .catch(done); + }); + + it('--hot-only', (done) => { + testBin('--hot-only') + .then((output) => { + expect(output.exitCode).toEqual(0); + expect(output.stderr).toContain('/hot/only-dev-server'); + done(); + }) + .catch(done); + }); + it('--progress', (done) => { testBin('--progress') .then((output) => { diff --git a/test/server/utils/__snapshots__/createConfig.test.js.snap b/test/server/utils/__snapshots__/createConfig.test.js.snap index 97c0416c79..ad9811f066 100644 --- a/test/server/utils/__snapshots__/createConfig.test.js.snap +++ b/test/server/utils/__snapshots__/createConfig.test.js.snap @@ -293,7 +293,55 @@ Object { } `; -exports[`createConfig hot option (in devServer config) 1`] = ` +exports[`createConfig hot only option (in devServer config) 1`] = ` +Object { + "hot": "only", + "port": 8080, + "publicPath": "/", + "stats": Object { + "cached": false, + "cachedAssets": false, + }, +} +`; + +exports[`createConfig hot only option 1`] = ` +Object { + "hot": "only", + "port": 8080, + "publicPath": "/", + "stats": Object { + "cached": false, + "cachedAssets": false, + }, +} +`; + +exports[`createConfig hot option (false) (in devServer config) 1`] = ` +Object { + "hot": false, + "port": 8080, + "publicPath": "/", + "stats": Object { + "cached": false, + "cachedAssets": false, + }, +} +`; + +exports[`createConfig hot option (false) 1`] = ` +Object { + "hot": false, + "port": 8080, + "publicPath": "/", + "stats": Object { + "cached": false, + "cachedAssets": false, + }, +} +`; + +exports[`createConfig hot option (true) (in devServer config) 1`] = ` Object { "hot": true, "port": 8080, @@ -305,7 +353,7 @@ Object { } `; -exports[`createConfig hot option 1`] = ` +exports[`createConfig hot option (true) 1`] = ` Object { "hot": true, "port": 8080, @@ -875,7 +923,7 @@ Object { "disableHostCheck": "_disableHostCheck", "historyApiFallback": "_historyApiFallback", "host": "_foo", - "hot": "_hot", + "hot": true, "https": "_https", "open": "_open", "openPage": "_openPage", @@ -901,7 +949,7 @@ Object { "disableHostCheck": "_disableHostCheck", "historyApiFallback": "_historyApiFallback", "host": "_foo", - "hot": "_hot", + "hot": true, "https": "_https", "open": "_open", "openPage": "_openPage", diff --git a/test/server/utils/createConfig.test.js b/test/server/utils/createConfig.test.js index a68cc6c16e..554000bc17 100644 --- a/test/server/utils/createConfig.test.js +++ b/test/server/utils/createConfig.test.js @@ -298,7 +298,7 @@ describe('createConfig', () => { expect(config).toMatchSnapshot(); }); - it('hot option', () => { + it('hot option (true)', () => { const config = createConfig( webpackConfig, Object.assign({}, argv, { hot: true }), @@ -308,7 +308,17 @@ describe('createConfig', () => { expect(config).toMatchSnapshot(); }); - it('hot option (in devServer config)', () => { + it('hot option (false)', () => { + const config = createConfig( + webpackConfig, + Object.assign({}, argv, { hot: false }), + { port: 8080 } + ); + + expect(config).toMatchSnapshot(); + }); + + it('hot option (true) (in devServer config)', () => { const config = createConfig( Object.assign({}, webpackConfig, { devServer: { hot: true }, @@ -320,6 +330,42 @@ describe('createConfig', () => { expect(config).toMatchSnapshot(); }); + it('hot option (false) (in devServer config)', () => { + const config = createConfig( + Object.assign({}, webpackConfig, { + devServer: { hot: false }, + }), + // eslint-disable-next-line no-undefined + Object.assign({}, argv, { hot: undefined }), + { port: 8080 } + ); + + expect(config).toMatchSnapshot(); + }); + + it('hot only option', () => { + const config = createConfig( + webpackConfig, + Object.assign({}, argv, { hotOnly: true }), + { port: 8080 } + ); + + expect(config).toMatchSnapshot(); + }); + + it('hot only option (in devServer config)', () => { + const config = createConfig( + Object.assign({}, webpackConfig, { + devServer: { hot: 'only' }, + }), + // eslint-disable-next-line no-undefined + Object.assign({}, argv, { hot: undefined }), + { port: 8080 } + ); + + expect(config).toMatchSnapshot(); + }); + it('clientLogLevel option', () => { const config = createConfig( webpackConfig,