diff --git a/lib/options.json b/lib/options.json index 395a22a288..461462fad3 100644 --- a/lib/options.json +++ b/lib/options.json @@ -140,7 +140,14 @@ }, "properties": { "bonjour": { - "type": "boolean", + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "object" + } + ], "description": "Broadcasts the server via ZeroConf networking on start. https://webpack.js.org/configuration/dev-server/#devserverbonjour" }, "client": { diff --git a/lib/utils/runBonjour.js b/lib/utils/runBonjour.js index 3add365d53..825c15af81 100644 --- a/lib/utils/runBonjour.js +++ b/lib/utils/runBonjour.js @@ -1,14 +1,15 @@ 'use strict'; -function runBonjour({ port }) { +function runBonjour(options) { const bonjour = require('bonjour')(); const os = require('os'); - + const { https, port } = options; bonjour.publish({ name: `Webpack Dev Server ${os.hostname()}:${port}`, port, - type: 'http', + type: https ? 'https' : 'http', subtypes: ['webpack'], + ...options.bonjour, }); process.on('exit', () => { diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack4 b/test/__snapshots__/validate-options.test.js.snap.webpack4 index 58f733149f..3e050e0408 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack4 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack4 @@ -2,8 +2,13 @@ exports[`options validate should throw an error on the "bonjour" option with '' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.bonjour should be a boolean. - -> Broadcasts the server via ZeroConf networking on start. https://webpack.js.org/configuration/dev-server/#devserverbonjour" + - configuration.bonjour should be one of these: + boolean | object { … } + -> Broadcasts the server via ZeroConf networking on start. https://webpack.js.org/configuration/dev-server/#devserverbonjour + Details: + * configuration.bonjour should be a boolean. + * configuration.bonjour should be an object: + object { … }" `; exports[`options validate should throw an error on the "client" option with '{"host":true,"path":"","port":8080}' value 1`] = ` diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack5 b/test/__snapshots__/validate-options.test.js.snap.webpack5 index 58f733149f..3e050e0408 100644 --- a/test/__snapshots__/validate-options.test.js.snap.webpack5 +++ b/test/__snapshots__/validate-options.test.js.snap.webpack5 @@ -2,8 +2,13 @@ exports[`options validate should throw an error on the "bonjour" option with '' value 1`] = ` "ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema. - - configuration.bonjour should be a boolean. - -> Broadcasts the server via ZeroConf networking on start. https://webpack.js.org/configuration/dev-server/#devserverbonjour" + - configuration.bonjour should be one of these: + boolean | object { … } + -> Broadcasts the server via ZeroConf networking on start. https://webpack.js.org/configuration/dev-server/#devserverbonjour + Details: + * configuration.bonjour should be a boolean. + * configuration.bonjour should be an object: + object { … }" `; exports[`options validate should throw an error on the "client" option with '{"host":true,"path":"","port":8080}' value 1`] = ` diff --git a/test/server/bonjour-option.test.js b/test/server/bonjour-option.test.js index da975c73c2..23d6fbf93b 100644 --- a/test/server/bonjour-option.test.js +++ b/test/server/bonjour-option.test.js @@ -19,31 +19,97 @@ describe('bonjour option', () => { }); }); - beforeEach((done) => { - server = testServer.start( - config, - { - bonjour: true, + afterEach(() => { + mockPublish.mockReset(); + mockUnpublishAll.mockReset(); + }); + + describe('http', () => { + beforeEach((done) => { + server = testServer.start( + config, + { + bonjour: true, + port, + }, + done + ); + }); + + afterEach((done) => { + server.close(done); + }); + + it('should call bonjour with correct params', () => { + expect(mockPublish).toHaveBeenCalledTimes(1); + expect(mockPublish).toHaveBeenCalledWith({ + name: `Webpack Dev Server ${os.hostname()}:${port}`, port, - }, - done - ); + type: 'http', + subtypes: ['webpack'], + }); + expect(mockUnpublishAll).toHaveBeenCalledTimes(0); + }); }); - afterEach((done) => { - mockPublish.mockReset(); - mockUnpublishAll.mockReset(); - server.close(done); + describe('https option', () => { + beforeEach((done) => { + server = testServer.start( + config, + { + bonjour: true, + port, + https: true, + }, + done + ); + }); + + afterEach((done) => { + server.close(done); + }); + + it('bonjour should use https when passed in option', () => { + expect(mockPublish).toHaveBeenCalledTimes(1); + expect(mockPublish).toHaveBeenCalledWith({ + name: `Webpack Dev Server ${os.hostname()}:${port}`, + port, + type: 'https', + subtypes: ['webpack'], + }); + expect(mockUnpublishAll).toHaveBeenCalledTimes(0); + }); }); - it('should call bonjour with correct params', () => { - expect(mockPublish).toHaveBeenCalledTimes(1); - expect(mockPublish).toHaveBeenCalledWith({ - name: `Webpack Dev Server ${os.hostname()}:${port}`, - port, - type: 'http', - subtypes: ['webpack'], + describe('bonjour object', () => { + beforeEach((done) => { + server = testServer.start( + config, + { + bonjour: { + type: 'https', + protocol: 'udp', + }, + port, + }, + done + ); + }); + + afterEach((done) => { + server.close(done); + }); + + it('applies bonjour options', () => { + expect(mockPublish).toHaveBeenCalledTimes(1); + expect(mockPublish).toHaveBeenCalledWith({ + name: `Webpack Dev Server ${os.hostname()}:${port}`, + port, + type: 'https', + protocol: 'udp', + subtypes: ['webpack'], + }); + expect(mockUnpublishAll).toHaveBeenCalledTimes(0); }); - expect(mockUnpublishAll).toHaveBeenCalledTimes(0); }); }); diff --git a/test/validate-options.test.js b/test/validate-options.test.js index dcfe28b5fd..eaabf2c05f 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -23,7 +23,7 @@ const tests = { failure: [false], }, bonjour: { - success: [false, true], + success: [false, true, { type: 'https' }], failure: [''], }, client: {