diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index 4ab436d6a0..8001c4f57f 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -22,13 +22,10 @@ const Server = require('../lib/Server'); const colors = require('../lib/utils/colors'); const createConfig = require('../lib/utils/createConfig'); -const createDomain = require('../lib/utils/createDomain'); const createLogger = require('../lib/utils/createLogger'); const defaultTo = require('../lib/utils/defaultTo'); const findPort = require('../lib/utils/findPort'); const getVersions = require('../lib/utils/getVersions'); -const runBonjour = require('../lib/utils/runBonjour'); -const status = require('../lib/utils/status'); const tryParseInt = require('../lib/utils/tryParseInt'); let server; @@ -159,11 +156,6 @@ function startDevServer(config, options) { }).apply(compiler); } - const suffix = - options.inline !== false || options.lazy === true - ? '/' - : '/webpack-dev-server/'; - try { server = new Server(compiler, options, log); } catch (err) { @@ -200,52 +192,27 @@ function startDevServer(config, options) { } }); - server.listen(options.socket, options.host, (err) => { + runServer(); + } else if (options.port) { + runServer(); + } else { + // only run port finder if no port as been specified + findPort(server, DEFAULT_PORT, defaultPortRetry, (err, port) => { if (err) { throw err; } - // chmod 666 (rw rw rw) - const READ_WRITE = 438; - - fs.chmod(options.socket, READ_WRITE, (err) => { - if (err) { - throw err; - } - - const uri = createDomain(options, server.listeningApp) + suffix; - - status(uri, options, log, argv.color); - }); + options.port = port; + runServer(); }); - return; } - const startServer = () => { + function runServer() { server.listen(options.port, options.host, (err) => { if (err) { throw err; } - if (options.bonjour) { - runBonjour(options); - } - const uri = createDomain(options, server.listeningApp) + suffix; - status(uri, options, log, argv.color); }); - }; - - if (options.port) { - startServer(); - return; } - - // only run port finder if no port as been specified - findPort(server, DEFAULT_PORT, defaultPortRetry, (err, port) => { - if (err) { - throw err; - } - options.port = port; - startServer(); - }); } processOptions(config); diff --git a/examples/api/simple/server.js b/examples/api/simple/server.js index eed5090f45..0f0bc323b0 100644 --- a/examples/api/simple/server.js +++ b/examples/api/simple/server.js @@ -6,6 +6,7 @@ const webpackConfig = require('./webpack.config'); const compiler = Webpack(webpackConfig); const devServerOptions = Object.assign({}, webpackConfig.devServer, { + open: true, stats: { colors: true, }, diff --git a/lib/Server.js b/lib/Server.js index 2be6a5fdbc..2c5ef5f402 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -27,6 +27,9 @@ const validateOptions = require('schema-utils'); const updateCompiler = require('./utils/updateCompiler'); const createLogger = require('./utils/createLogger'); const getCertificate = require('./utils/getCertificate'); +const status = require('./utils/status'); +const createDomain = require('./utils/createDomain'); +const runBonjour = require('./utils/runBonjour'); const routes = require('./utils/routes'); const schema = require('./options.json'); @@ -809,6 +812,41 @@ class Server { prefix: this.sockPath, }); + if (this.options.bonjour) { + runBonjour(this.options); + } + + const showStatus = () => { + const suffix = + this.options.inline !== false || this.options.lazy === true + ? '/' + : '/webpack-dev-server/'; + + const uri = `${createDomain(this.options, this.listeningApp)}${suffix}`; + + status( + uri, + this.options, + this.log, + this.options.stats && this.options.stats.colors + ); + }; + + if (this.options.socket) { + // chmod 666 (rw rw rw) + const READ_WRITE = 438; + + fs.chmod(this.options.socket, READ_WRITE, (err) => { + if (err) { + throw err; + } + + showStatus(); + }); + } else { + showStatus(); + } + if (fn) { fn.call(this.listeningApp, err); } diff --git a/lib/utils/status.js b/lib/utils/status.js index f9acb1aa6c..4c552a4639 100644 --- a/lib/utils/status.js +++ b/lib/utils/status.js @@ -3,6 +3,7 @@ const open = require('opn'); const colors = require('./colors'); +// TODO: don't emit logs when webpack-dev-server is used via Node.js API function status(uri, options, log, useColor) { const contentBase = Array.isArray(options.contentBase) ? options.contentBase.join(', ') @@ -51,7 +52,7 @@ function status(uri, options, log, useColor) { openMessage += `: ${options.open}`; } - open(uri + (options.openPage || ''), openOptions).catch(() => { + open(`${uri}${options.openPage || ''}`, openOptions).catch(() => { log.warn( `${openMessage}. If you are running in a headless environment, please do not use the --open flag` ); diff --git a/test/Server.test.js b/test/Server.test.js index 1c4a17bb78..bb87ba7994 100644 --- a/test/Server.test.js +++ b/test/Server.test.js @@ -3,6 +3,15 @@ const { relative, sep } = require('path'); const webpack = require('webpack'); const request = require('supertest'); +// Mock opn before loading Server +jest.mock('opn'); +// eslint-disable-next-line import/newline-after-import +const opn = require('opn'); +opn.mockImplementation(() => { + return { + catch: jest.fn(), + }; +}); const Server = require('../lib/Server'); const config = require('./fixtures/simple-config/webpack.config'); const helper = require('./helper'); @@ -189,6 +198,26 @@ describe('Server', () => { server.listen(8080, 'localhost'); }); }); + + it('should open', () => { + return new Promise((res) => { + const compiler = webpack(config); + const server = new Server(compiler, { + open: true, + }); + + compiler.hooks.done.tap('webpack-dev-server', () => { + expect(opn.mock.calls[0]).toEqual(['http://localhost:8080/', {}]); + expect(opn.mock.invocationCallOrder[0]).toEqual(1); + server.close(() => { + res(); + }); + }); + + compiler.run(() => {}); + server.listen(8080, 'localhost'); + }); + }); }); describe('host', () => {