Skip to content

Commit d0817cd

Browse files
committed
feat: improve host option
1 parent f139812 commit d0817cd

File tree

9 files changed

+59
-42
lines changed

9 files changed

+59
-42
lines changed

bin/cli-flags.js

-10
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,6 @@ module.exports = {
125125
description:
126126
'Open the default browser, or optionally specify a browser name.',
127127
},
128-
{
129-
name: 'use-local-ip',
130-
type: Boolean,
131-
configs: [
132-
{
133-
type: 'boolean',
134-
},
135-
],
136-
description: 'Open default browser with local IP.',
137-
},
138128
{
139129
name: 'open-page',
140130
type: String,

lib/Server.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,11 @@ class Server {
519519
}
520520

521521
this.server.on('error', (err) => {
522+
if (err.code === 'EADDRNOTAVAIL') {
523+
this.logger.error(
524+
`Address ${this.hostname} is not available. Try with a different value for "host" option`
525+
);
526+
}
522527
throw err;
523528
});
524529
}
@@ -726,7 +731,15 @@ class Server {
726731
}
727732

728733
listen(port, hostname, fn) {
729-
this.hostname = hostname;
734+
if (hostname === 'local-ip') {
735+
this.hostname = internalIp.v4.sync() || internalIp.v6.sync();
736+
} else if (hostname === 'local-ipv4') {
737+
this.hostname = internalIp.v4.sync();
738+
} else if (hostname === 'local-ipv6') {
739+
this.hostname = internalIp.v6.sync();
740+
} else {
741+
this.hostname = hostname;
742+
}
730743

731744
if (typeof port !== 'undefined' && port !== this.options.port) {
732745
this.logger.warn(
@@ -739,8 +752,7 @@ class Server {
739752
// eslint-disable-next-line no-shadow
740753
.then((port) => {
741754
this.port = port;
742-
743-
return this.server.listen(port, hostname, (err) => {
755+
return this.server.listen(port, this.hostname, (err) => {
744756
if (this.options.hot || this.options.liveReload) {
745757
this.createSocketServer();
746758
}

lib/options.json

+1-5
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

+1-4
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

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ exports[`Validation validation should fail validation for invalid \`hot\` config
1212
exports[`Validation validation should fail validation for invalid \`injectHot\` configuration 1`] = `
1313
"Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
1414
- configuration has an unknown property 'injectHot'. These properties are valid:
15-
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? }"
15+
object { bonjour?, client?, compress?, dev?, firewall?, headers?, historyApiFallback?, host?, hot?, http2?, https?, liveReload?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, openPage?, port?, proxy?, public?, setupExitSignals?, static?, transportMode? }"
1616
`;
1717
1818
exports[`Validation validation should fail validation for invalid \`static\` configuration 1`] = `
@@ -31,5 +31,5 @@ exports[`Validation validation should fail validation for invalid \`static\` con
3131
exports[`Validation validation should fail validation for no additional properties 1`] = `
3232
"Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
3333
- configuration has an unknown property 'additional'. These properties are valid:
34-
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? }"
34+
object { bonjour?, client?, compress?, dev?, firewall?, headers?, historyApiFallback?, host?, hot?, http2?, https?, liveReload?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, openPage?, port?, proxy?, public?, setupExitSignals?, static?, transportMode? }"
3535
`;

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

+10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ exports[`CLI --host <IPv4>: stderr 1`] = `
1717
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
1818
`;
1919
20+
exports[`CLI --host <local-ip>: stderr 1`] = `
21+
"<i> [webpack-dev-server] Project is running at http://<network-ip-v4>:<port>/ (IPv4)
22+
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
23+
`;
24+
25+
exports[`CLI --host <local-ipv4>: stderr 1`] = `
26+
"<i> [webpack-dev-server] Project is running at http://<network-ip-v4>:<port>/ (IPv4)
27+
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/public' directory"
28+
`;
29+
2030
exports[`CLI --host 0.0.0.0 (IPv4): stderr 1`] = `
2131
"<i> [webpack-dev-server] Project is running at:
2232
<i> [webpack-dev-server] Local: http://localhost:<port>/

test/cli/cli.test.js

+30
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,36 @@ describe('CLI', () => {
188188
.catch(done);
189189
});
190190

191+
it('--host <local-ip>', (done) => {
192+
testBin('--host local-ip')
193+
.then((output) => {
194+
expect(normalizeStderr(output.stderr)).toMatchSnapshot('stderr');
195+
196+
done();
197+
})
198+
.catch(done);
199+
});
200+
201+
it('--host <local-ipv4>', (done) => {
202+
testBin('--host local-ipv4')
203+
.then((output) => {
204+
expect(normalizeStderr(output.stderr)).toMatchSnapshot('stderr');
205+
206+
done();
207+
})
208+
.catch(done);
209+
});
210+
211+
it.skip('--host <local-ipv6>', (done) => {
212+
testBin('--host local-ipv6')
213+
.then((output) => {
214+
expect(normalizeStderr(output.stderr)).toMatchSnapshot('stderr');
215+
216+
done();
217+
})
218+
.catch(done);
219+
});
220+
191221
it('--host localhost --port 9999', (done) => {
192222
testBin('--host localhost --port 9999')
193223
.then((output) => {

test/options.test.js

-4
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

-14
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)