Skip to content

Commit bfec4d2

Browse files
authored
feat: improve host option (#3112)
BREAKING CHANGE: the `useLocalIp` option was removed in favor `host: 'local-ip'`, alternative you can provide values: `local-ipv4` and `local-ipv6`
1 parent d96af16 commit bfec4d2

File tree

10 files changed

+51
-45
lines changed

10 files changed

+51
-45
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ Options:
9696
--setup-exit-signals Close and exit the process on SIGINT and SIGTERM.
9797
--no-setup-exit-signals Do not close and exit the process on SIGNIT and SIGTERM.
9898
--open [value] Open the default browser, or optionally specify a browser name.
99-
--use-local-ip Open default browser with local IP.
10099
--open-page <value...> Open default browser with the specified page.
101100
--client-logging <value> Log level in the browser (none, error, warn, info, log, verbose).
102101
--history-api-fallback Fallback to /index.html for Single Page Applications.

bin/cli-flags.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,6 @@ module.exports = {
128128
description:
129129
'Open the default browser, or optionally specify a browser name.',
130130
},
131-
{
132-
name: 'use-local-ip',
133-
type: Boolean,
134-
configs: [
135-
{
136-
type: 'boolean',
137-
},
138-
],
139-
description: 'Open default browser with local IP.',
140-
},
141131
{
142132
name: 'open-page',
143133
type: String,

lib/Server.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,8 @@ class Server {
518518
this.server = http.createServer(this.app);
519519
}
520520

521-
this.server.on('error', (err) => {
522-
throw err;
521+
this.server.on('error', (error) => {
522+
throw error;
523523
});
524524
}
525525

@@ -724,7 +724,16 @@ class Server {
724724
}
725725

726726
listen(port, hostname, fn) {
727-
this.hostname = hostname;
727+
if (hostname === 'local-ip') {
728+
this.hostname =
729+
internalIp.v4.sync() || '0.0.0.0' || internalIp.v6.sync() || '::';
730+
} else if (hostname === 'local-ipv4') {
731+
this.hostname = internalIp.v4.sync() || '0.0.0.0';
732+
} else if (hostname === 'local-ipv6') {
733+
this.hostname = internalIp.v6.sync() || '::';
734+
} else {
735+
this.hostname = hostname;
736+
}
728737

729738
if (typeof port !== 'undefined' && port !== this.options.port) {
730739
this.logger.warn(
@@ -737,8 +746,7 @@ class Server {
737746
// eslint-disable-next-line no-shadow
738747
.then((port) => {
739748
this.port = port;
740-
741-
return this.server.listen(port, hostname, (error) => {
749+
return this.server.listen(port, this.hostname, (error) => {
742750
if (this.options.hot || this.options.liveReload) {
743751
this.createSocketServer();
744752
}
@@ -944,11 +952,13 @@ class Server {
944952
if (!isFile) {
945953
return next();
946954
}
955+
947956
// Serve a page that executes the javascript
948957
const queries = req._parsedUrl.search || '';
949958
const responsePage = `<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body><script type="text/javascript" charset="utf-8" src="${_path}.js${queries}"></script></body></html>`;
959+
950960
res.send(responsePage);
951-
} catch (err) {
961+
} catch (error) {
952962
return next();
953963
}
954964
}

lib/options.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,6 @@
374374
"enum": ["sockjs", "ws"]
375375
}
376376
]
377-
},
378-
"useLocalIp": {
379-
"type": "boolean"
380377
}
381378
},
382379
"errorMessage": {
@@ -403,8 +400,7 @@
403400
"public": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpublic)",
404401
"setupExitSignals": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserversetupexitsignals)",
405402
"static": "should be {Boolean|String|Object|Array} (https://webpack.js.org/configuration/dev-server/#devserverstatic)",
406-
"transportMode": "should be {String|Object} (https://webpack.js.org/configuration/dev-server/#devservertransportmode)",
407-
"useLocalIp": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserveruselocalip)"
403+
"transportMode": "should be {String|Object} (https://webpack.js.org/configuration/dev-server/#devservertransportmode)"
408404
}
409405
},
410406
"additionalProperties": false

lib/utils/createDomain.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
'use strict';
22

33
const url = require('url');
4-
const ip = require('internal-ip');
54

65
function createDomain(options, server) {
76
const protocol = options.https ? 'https' : 'http';
87
// use location hostname and port by default in createSocketUrl
98
// ipv6 detection is not required as 0.0.0.0 is just used as a placeholder
109
let hostname;
1110

12-
if (options.useLocalIp) {
13-
hostname = ip.v4.sync() || '0.0.0.0';
14-
} else if (server) {
11+
if (server) {
1512
hostname = server.address().address;
1613
} else {
1714
hostname = '0.0.0.0';

test/__snapshots__/Validation.test.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,5 @@ exports[`Validation validation should fail validation for invalid \`static\` con
4343
exports[`Validation validation should fail validation for no additional properties 1`] = `
4444
"Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
4545
- configuration has an unknown property 'additional'. These properties are valid:
46-
object { bonjour?, client?, compress?, dev?, firewall?, headers?, historyApiFallback?, host?, hot?, http2?, https?, liveReload?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, openPage?, port?, proxy?, public?, setupExitSignals?, static?, transportMode?, useLocalIp? }"
46+
object { bonjour?, client?, compress?, dev?, firewall?, headers?, historyApiFallback?, host?, hot?, http2?, https?, liveReload?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, openPage?, port?, proxy?, public?, setupExitSignals?, static?, transportMode? }"
4747
`;

test/cli/__snapshots__/cli.test.js.snap

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ exports[`CLI --host <IPv4>: stderr 1`] = `
2020
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
2121
`;
2222
23+
exports[`CLI --host <local-ip>: stderr 1`] = `
24+
"<i> [webpack-dev-server] Project is running at:
25+
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
26+
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
27+
`;
28+
29+
exports[`CLI --host <local-ipv4>: stderr 1`] = `
30+
"<i> [webpack-dev-server] Project is running at:
31+
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
32+
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
33+
`;
34+
2335
exports[`CLI --host 0.0.0.0 (IPv4): stderr 1`] = `
2436
"<i> [webpack-dev-server] Project is running at:
2537
<i> [webpack-dev-server] Loopback: http://localhost:<port>/

test/cli/cli.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,26 @@ describe('CLI', () => {
189189
.catch(done);
190190
});
191191

192+
it('--host <local-ip>', (done) => {
193+
testBin('--host local-ip')
194+
.then((output) => {
195+
expect(normalizeStderr(output.stderr)).toMatchSnapshot('stderr');
196+
197+
done();
198+
})
199+
.catch(done);
200+
});
201+
202+
it('--host <local-ipv4>', (done) => {
203+
testBin('--host local-ipv4')
204+
.then((output) => {
205+
expect(normalizeStderr(output.stderr)).toMatchSnapshot('stderr');
206+
207+
done();
208+
})
209+
.catch(done);
210+
});
211+
192212
it('--host localhost --port 9999', (done) => {
193213
testBin('--host localhost --port 9999')
194214
.then((output) => {

test/options.test.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,10 +500,6 @@ describe('options', () => {
500500
},
501501
],
502502
},
503-
useLocalIp: {
504-
success: [false],
505-
failure: [''],
506-
},
507503
};
508504

509505
Object.keys(cases).forEach((key) => {

test/server/utils/createDomain.test.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
const webpack = require('webpack');
4-
const internalIp = require('internal-ip');
54
const Server = require('../../../lib/Server');
65
const createDomain = require('../../../lib/utils/createDomain');
76
const [port1, port2] = require('../../ports-map').createDomain;
@@ -89,19 +88,6 @@ describe('createDomain', () => {
8988
},
9089
expected: [`https://myhost.test:${port2}`],
9190
},
92-
{
93-
name: 'localIp',
94-
options: {
95-
useLocalIp: true,
96-
port: port1,
97-
},
98-
expected: [
99-
`http://${internalIp.v4.sync()}:${port1}`,
100-
`https://localhost:${port1}`,
101-
`https://127.0.0.1:${port1}`,
102-
`https://[::1]:${port1}`,
103-
],
104-
},
10591
];
10692

10793
tests.forEach((test) => {

0 commit comments

Comments
 (0)