diff --git a/bin/cli-flags.js b/bin/cli-flags.js index 03042b267c..55b40ed080 100644 --- a/bin/cli-flags.js +++ b/bin/cli-flags.js @@ -21,21 +21,25 @@ module.exports = { negative: true, }, { - name: 'profile', + name: 'client-progress', type: Boolean, - describe: 'Print compilation profile data for progress steps', - }, - { - name: 'progress', - type: Boolean, - describe: 'Print compilation progress in percentage', + describe: 'Print compilation progress in percentage in the browser', group: BASIC_GROUP, + processor(opts) { + opts.client = opts.client || {}; + opts.client.progress = opts.clientProgress; + delete opts.clientProgress; + }, }, { name: 'hot-only', type: Boolean, describe: 'Do not refresh page if HMR fails', group: ADVANCED_GROUP, + processor(opts) { + opts.hot = 'only'; + delete opts.hotOnly; + }, }, { name: 'setup-exit-signals', @@ -73,6 +77,11 @@ module.exports = { group: DISPLAY_GROUP, describe: 'Log level in the browser (none, error, warn, info, log, verbose)', + processor(opts) { + opts.client = opts.client || {}; + opts.client.logging = opts.clientLogging; + delete opts.clientLogging; + }, }, { name: 'https', @@ -106,7 +115,6 @@ module.exports = { describe: 'Enable gzip compression', group: RESPONSE_GROUP, }, - // findPort is currently not set up { name: 'port', type: Number, diff --git a/bin/options.js b/bin/options.js deleted file mode 100644 index 20a0618cea..0000000000 --- a/bin/options.js +++ /dev/null @@ -1,114 +0,0 @@ -'use strict'; - -const ADVANCED_GROUP = 'Advanced options:'; -const DISPLAY_GROUP = 'Stats options:'; -const SSL_GROUP = 'SSL options:'; -const CONNECTION_GROUP = 'Connection options:'; -const RESPONSE_GROUP = 'Response options:'; -const BASIC_GROUP = 'Basic options:'; - -const options = { - bonjour: { - type: 'boolean', - describe: 'Broadcasts the server via ZeroConf networking on start', - }, - 'live-reload': { - type: 'boolean', - describe: 'Enables/Disables live reloading on changing files', - }, - profile: { - type: 'boolean', - describe: 'Print compilation profile data for progress steps', - }, - progress: { - type: 'boolean', - 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', - group: ADVANCED_GROUP, - }, - 'setup-exit-signals': { - type: 'boolean', - describe: 'Close and exit the process on SIGINT and SIGTERM', - group: ADVANCED_GROUP, - }, - stdin: { - type: 'boolean', - describe: 'close when stdin ends', - }, - open: { - type: 'string', - describe: 'Open the default browser, or optionally specify a browser name', - }, - 'use-local-ip': { - type: 'boolean', - describe: 'Open default browser with local IP', - }, - 'open-page': { - type: 'string', - describe: 'Open default browser with the specified page', - requiresArg: true, - }, - 'client-logging': { - type: 'string', - group: DISPLAY_GROUP, - describe: - 'Log level in the browser (none, error, warn, info, log, verbose)', - }, - https: { - type: 'boolean', - group: SSL_GROUP, - describe: 'HTTPS', - }, - http2: { - type: 'boolean', - group: SSL_GROUP, - describe: 'HTTP/2, must be used with HTTPS', - }, - static: { - type: 'string', - describe: 'A directory to serve static content from.', - group: RESPONSE_GROUP, - }, - 'history-api-fallback': { - type: 'boolean', - describe: 'Fallback to /index.html for Single Page Applications.', - group: RESPONSE_GROUP, - }, - compress: { - type: 'boolean', - describe: 'Enable gzip compression', - group: RESPONSE_GROUP, - }, - port: { - describe: 'The port', - group: CONNECTION_GROUP, - }, - public: { - type: 'string', - describe: 'The public hostname/ip address of the server', - group: CONNECTION_GROUP, - }, - host: { - type: 'string', - default: 'localhost', - describe: 'The hostname/ip address the server will bind to', - group: CONNECTION_GROUP, - }, - firewall: { - type: 'string', - describe: - 'Enable/disable firewall, or set hosts that are allowed to access the dev server', - group: CONNECTION_GROUP, - }, -}; - -module.exports = options; diff --git a/examples/cli/progress/webpack.config.js b/examples/cli/progress/webpack.config.js index 890054d3c0..9f8f0044d0 100644 --- a/examples/cli/progress/webpack.config.js +++ b/examples/cli/progress/webpack.config.js @@ -7,7 +7,7 @@ const { setup } = require('../../util'); module.exports = setup({ context: __dirname, entry: './app.js', - devServer: { + client: { progress: true, }, }); diff --git a/lib/Server.js b/lib/Server.js index 75fd39bc24..b0df67e0d6 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -58,7 +58,7 @@ class Server { this.options ); - if (this.options.progress) { + if (this.options.client.progress) { this.setupProgressPlugin(); } this.setupHooks(); @@ -83,12 +83,6 @@ class Server { } setupProgressPlugin() { - // for CLI output - new webpack.ProgressPlugin({ - profile: !!this.options.profile, - }).apply(this.compiler); - - // for browser console output new webpack.ProgressPlugin((percent, msg, addInfo) => { percent = Math.floor(percent * 100); @@ -569,8 +563,8 @@ class Server { this.sockWrite([connection], 'liveReload'); } - if (this.options.progress) { - this.sockWrite([connection], 'progress', this.options.progress); + if (this.options.client.progress) { + this.sockWrite([connection], 'progress', this.options.client.progress); } if (this.options.clientOverlay) { diff --git a/lib/options.json b/lib/options.json index 9e60c20ecf..a5449523c3 100644 --- a/lib/options.json +++ b/lib/options.json @@ -83,6 +83,9 @@ }, "logging": { "enum": ["none", "error", "warn", "info", "log", "verbose"] + }, + "progress": { + "type": "boolean" } }, "additionalProperties": false @@ -292,12 +295,6 @@ } ] }, - "profile": { - "type": "boolean" - }, - "progress": { - "type": "boolean" - }, "proxy": { "anyOf": [ { @@ -408,8 +405,6 @@ "openPage": "should be {String|Array} (https://webpack.js.org/configuration/dev-server/#devserveropenpage)", "overlay": "should be {Boolean|Object} (https://webpack.js.org/configuration/dev-server/#devserveroverlay)", "port": "should be {Number|String|Null} (https://webpack.js.org/configuration/dev-server/#devserverport)", - "profile": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverprofile)", - "progress": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverprogress---cli-only)", "proxy": "should be {Object|Array} (https://webpack.js.org/configuration/dev-server/#devserverproxy)", "public": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpublic)", "setupExitSignals": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserversetupexitsignals)", diff --git a/test/__snapshots__/Validation.test.js.snap b/test/__snapshots__/Validation.test.js.snap index 79840f2139..2fa14b3d38 100644 --- a/test/__snapshots__/Validation.test.js.snap +++ b/test/__snapshots__/Validation.test.js.snap @@ -39,5 +39,5 @@ exports[`Validation validation should fail validation for invalid \`static\` con exports[`Validation validation should fail validation for no additional properties 1`] = ` "Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - configuration has an unknown property 'additional'. These properties are valid: - object { bonjour?, client?, compress?, dev?, firewall?, headers?, historyApiFallback?, host?, hot?, http2?, https?, injectClient?, injectHot?, liveReload?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, openPage?, overlay?, port?, profile?, progress?, proxy?, public?, setupExitSignals?, static?, stdin?, transportMode?, useLocalIp? }" + object { bonjour?, client?, compress?, dev?, firewall?, headers?, historyApiFallback?, host?, hot?, http2?, https?, injectClient?, injectHot?, liveReload?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, openPage?, overlay?, port?, proxy?, public?, setupExitSignals?, static?, stdin?, transportMode?, useLocalIp? }" `; diff --git a/test/cli/cli.test.js b/test/cli/cli.test.js index 94b9e25c91..02f0db0f89 100644 --- a/test/cli/cli.test.js +++ b/test/cli/cli.test.js @@ -98,31 +98,6 @@ runCLITest('CLI', () => { .catch(done); }); - it('--progress', (done) => { - testBin('--progress') - .then((output) => { - expect(output.exitCode).toEqual(0); - expect(output.stderr).toContain('100%'); - // should not profile - expect(output.stderr).not.toContain( - 'ms after chunk modules optimization' - ); - done(); - }) - .catch(done); - }); - - it('--progress --profile', (done) => { - testBin('--progress --profile') - .then((output) => { - expect(output.exitCode).toEqual(0); - // should profile - expect(output.stderr).toContain('after chunk modules optimization'); - done(); - }) - .catch(done); - }); - it('--bonjour', (done) => { testBin('--bonjour') .then((output) => { diff --git a/test/client/utils/__snapshots__/createSocketUrl.test.js.snap b/test/client/utils/__snapshots__/createSocketUrl.test.js.snap index eacb9b6271..548fa88628 100644 --- a/test/client/utils/__snapshots__/createSocketUrl.test.js.snap +++ b/test/client/utils/__snapshots__/createSocketUrl.test.js.snap @@ -2,6 +2,8 @@ exports[`createSocketUrl should return the url when __resourceQuery is ?test 1`] = `"/ws"`; +exports[`createSocketUrl should return the url when __resourceQuery is file://filename 1`] = `"file://filename/ws"`; + exports[`createSocketUrl should return the url when __resourceQuery is http://0.0.0.0 1`] = `"http://localhost/ws"`; exports[`createSocketUrl should return the url when __resourceQuery is http://127.0.0.1 1`] = `"http://127.0.0.1/ws"`; @@ -22,6 +24,8 @@ exports[`createSocketUrl should return the url when __resourceQuery is undefined exports[`createSocketUrl should return the url when the current script source is ?test 1`] = `"/ws"`; +exports[`createSocketUrl should return the url when the current script source is file://filename 1`] = `"file://filename/ws"`; + exports[`createSocketUrl should return the url when the current script source is http://0.0.0.0 1`] = `"http://localhost/ws"`; exports[`createSocketUrl should return the url when the current script source is http://127.0.0.1 1`] = `"http://127.0.0.1/ws"`; diff --git a/test/client/utils/createSocketUrl.test.js b/test/client/utils/createSocketUrl.test.js index 3c3a1e952f..50a9edd3c1 100644 --- a/test/client/utils/createSocketUrl.test.js +++ b/test/client/utils/createSocketUrl.test.js @@ -11,9 +11,7 @@ describe('createSocketUrl', () => { 'https://localhost:123', 'http://user:pass@[::]:8080', 'http://127.0.0.1', - // TODO: comment out after the major release - // https://github.com/webpack/webpack-dev-server/pull/1954#issuecomment-498043376 - // 'file://filename', + 'file://filename', // eslint-disable-next-line no-undefined undefined, ]; diff --git a/test/e2e/Progress.test.js b/test/e2e/Progress.test.js index 9840b95864..8a2bf3b5c9 100644 --- a/test/e2e/Progress.test.js +++ b/test/e2e/Progress.test.js @@ -37,7 +37,9 @@ describe('client progress', () => { port, host: '0.0.0.0', hot: true, - progress: true, + client: { + progress: true, + }, }; // we need a delay between file writing and the start diff --git a/test/fixtures/schema/webpack.config.no-dev-stats.js b/test/fixtures/schema/webpack.config.no-dev-stats.js index a97e3502ff..ca283ec392 100644 --- a/test/fixtures/schema/webpack.config.no-dev-stats.js +++ b/test/fixtures/schema/webpack.config.no-dev-stats.js @@ -8,7 +8,6 @@ module.exports = { devServer: { host: '_foo', public: '_public', - progress: '_progress', publicPath: '_publicPath', hot: '_hot', clientLogging: '_clientLogging', diff --git a/test/options.test.js b/test/options.test.js index 0ab756f500..deb21fa53f 100644 --- a/test/options.test.js +++ b/test/options.test.js @@ -202,6 +202,11 @@ describe('options', () => { port: null, }, }, + { + client: { + progress: false, + }, + }, ], failure: [ 'whoops!', @@ -227,6 +232,11 @@ describe('options', () => { logging: 'silent', }, }, + { + client: { + progress: '', + }, + }, ], }, compress: { @@ -355,14 +365,6 @@ describe('options', () => { success: ['', 0, null], failure: [false], }, - profile: { - success: [false], - failure: [''], - }, - progress: { - success: [false], - failure: [''], - }, proxy: { success: [ { diff --git a/test/ports-map.js b/test/ports-map.js index 6376ff8bea..736deed6b7 100644 --- a/test/ports-map.js +++ b/test/ports-map.js @@ -37,8 +37,6 @@ const portsList = { WebsocketServer: 1, TransportMode: 1, Progress: 1, - 'progress-option': 1, - 'profile-option': 1, Iframe: 1, SocketInjection: 1, 'static-publicPath-option': 1, diff --git a/test/server/profile-option.test.js b/test/server/profile-option.test.js deleted file mode 100644 index 5a742b51c5..0000000000 --- a/test/server/profile-option.test.js +++ /dev/null @@ -1,60 +0,0 @@ -'use strict'; - -const webpack = require('webpack'); -const Server = require('../../lib/Server'); -const config = require('../fixtures/simple-config/webpack.config'); -const port = require('../ports-map')['profile-option']; - -describe('profile', () => { - describe('output', () => { - let mockStderr; - - beforeAll(() => { - mockStderr = jest - .spyOn(process.stderr, 'write') - .mockImplementation(() => {}); - }); - - it('should show percentage progress with profile data', (done) => { - config.infrastructureLogging.level = 'info'; - - const compiler = webpack(config); - const server = new Server(compiler, { - port, - // profile will only have an effect when progress is enabled - progress: true, - profile: true, - static: false, - }); - - compiler.hooks.done.tap('webpack-dev-server', () => { - const calls = mockStderr.mock.calls; - mockStderr.mockRestore(); - let foundProgress = false; - let foundProfile = false; - - calls.forEach((call) => { - const text = call[0]; - - if (text.includes('2%')) { - foundProgress = true; - } - - // this is an indicator that the profile option is enabled, - // so we should expect to find it in stderr since profile is enabled - if (text.includes('after chunk modules optimization')) { - foundProfile = true; - } - }); - - expect(foundProgress).toBeTruthy(); - expect(foundProfile).toBeTruthy(); - - server.close(done); - }); - - compiler.run(() => {}); - server.listen(port, 'localhost'); - }); - }); -}); diff --git a/test/server/progress-option.test.js b/test/server/progress-option.test.js deleted file mode 100644 index 7c0fd99618..0000000000 --- a/test/server/progress-option.test.js +++ /dev/null @@ -1,60 +0,0 @@ -'use strict'; - -const webpack = require('webpack'); -const Server = require('../../lib/Server'); -const config = require('../fixtures/simple-config/webpack.config'); -const port = require('../ports-map')['progress-option']; - -describe('progress', () => { - describe('output', () => { - let mockStderr; - - beforeAll(() => { - mockStderr = jest - .spyOn(process.stderr, 'write') - .mockImplementation(() => {}); - }); - - it('should show percentage progress without profile data', (done) => { - config.infrastructureLogging.level = 'info'; - - const compiler = webpack(config); - const server = new Server(compiler, { - port, - progress: true, - static: false, - }); - - compiler.hooks.done.tap('webpack-dev-server', () => { - const calls = mockStderr.mock.calls; - mockStderr.mockRestore(); - let foundProgress = false; - let foundProfile = false; - calls.forEach((call) => { - if (call[0].includes('2%')) { - foundProgress = true; - } - - // this is an indicator that the profile option is enabled, - // so we should expect to not find it in stderr since it is not enabled - if (call[0].includes('ms after chunk modules optimization')) { - foundProfile = true; - } - }); - expect(foundProgress).toBeTruthy(); - expect(foundProfile).toBeFalsy(); - - server.close(done); - }); - - compiler.run(() => {}); - server.listen(port, 'localhost').then((app) => { - app.on('progress-update', ({ percent, msg }) => { - expect(percent).toBeGreaterThanOrEqual(0); - expect(percent).toBeLessThanOrEqual(100); - expect(typeof msg).toEqual('string'); - }); - }); - }); - }); -});