Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add webSocketURL option #3309

Merged
merged 19 commits into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions bin/cli-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -394,16 +394,6 @@ module.exports = {
negatedDescription: 'Disable gzip compression.',
negative: true,
},
{
name: 'public',
type: String,
configs: [
{
type: 'string',
},
],
description: 'The public hostname/ip address of the server.',
},
{
name: 'firewall',
type: [Boolean, String],
Expand Down
25 changes: 10 additions & 15 deletions client-src/utils/createSocketURL.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ const url = require('url');
function createSocketURL(parsedURL) {
let { auth, hostname, protocol, port } = parsedURL;

const getURLSearchParam = (name) => {
if (parsedURL.searchParams) {
return parsedURL.searchParams.get(name);
}

return parsedURL.query && parsedURL.query[name];
};

// Node.js module parses it as `::`
// `new URL(urlString, [baseURLstring])` parses it as '[::]'
const isInAddrAny =
Expand Down Expand Up @@ -66,22 +58,25 @@ function createSocketURL(parsedURL) {
//
// All of these sock url params are optionally passed in through resourceQuery,
// so we need to fall back to the default if they are not provided
const socketURLHostname = (
getURLSearchParam('host') ||
hostname ||
'localhost'
).replace(/^\[(.*)\]$/, '$1');
const socketURLHostname = (hostname || 'localhost').replace(
/^\[(.*)\]$/,
'$1'
);

if (!port || port === '0') {
port = self.location.port;
}

const socketURLPort = getURLSearchParam('port') || port;
const socketURLPort = port;

// If path is provided it'll be passed in via the resourceQuery as a
// query param so it has to be parsed out of the querystring in order for the
// client to open the socket to the correct location.
const socketURLPathname = getURLSearchParam('path') || '/ws';
let socketURLPathname = '/ws';

if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
socketURLPathname = parsedURL.pathname;
}

return url.format({
protocol: socketURLProtocol,
Expand Down
19 changes: 13 additions & 6 deletions client-src/utils/parseURL.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ function parseURL(resourceQuery) {

if (typeof resourceQuery === 'string' && resourceQuery !== '') {
// If this bundle is inlined, use the resource query to get the correct url.
// format is like `?http://0.0.0.0:8096&port=8097&host=localhost`
// for backward compatibility we supports:
// - ?ws://0.0.0.0:8096&3Flogging=info
// - ?ws%3A%2F%2F192.168.0.5%3A8080%2F%3Flogging%3Dinfo
// Also we support `http` and `https` for backward compatibility too
options = url.parse(
resourceQuery
// strip leading `?` from query string to get a valid URL
.substr(1)
// replace first `&` with `?` to have a valid query string
.replace('&', '?'),
decodeURIComponent(
resourceQuery
// strip leading `?` from query string to get a valid URL
.substr(1)
// replace first `&` with `?` to have a valid query string
.replace('&', '?')
),
true
);
} else {
Expand All @@ -36,9 +41,11 @@ function parseURL(resourceQuery) {

if (scriptSourceURL) {
options = scriptSourceURL;
options.fromCurrentScript = true;
}
} else {
options = url.parse(self.location.href, true, true);
options.fromCurrentScript = true;
}
}

Expand Down
6 changes: 0 additions & 6 deletions examples/cli/public-protocol/app.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# CLI: Public Option
# CLI: Web Socket URL

```console
npx webpack serve --open-target --host 0.0.0.0 --public <insert local ip>:8080
npx webpack serve --open-target --host 0.0.0.0 --web-socket-url <insert-host>:8080
```

_NOTE: replace `<insert local ip>` with your local IP Address._

In order to make the server publicly accessible the client needs to know with
what host to connect to the server. If `--host 0.0.0.0` is given, the client
would try to connect to `0.0.0.0`. With the `--public` option it is possible to
would try to connect to `0.0.0.0`. With the `--web-socket-url` options it is possible to
override this.

## What Should Happen
Expand All @@ -18,4 +18,4 @@ override this.
3. Open the console in your browser's devtools.
4. Select the 'Network' tab.
5. Select the 'WS' or 'WebSockets' sub-tab.
6. Verify that the WebSocket is connecting to `<insert local ip>:8080`.
6. Verify that the WebSocket is connecting to `<insert-host>:8080`.
File renamed without changes.
6 changes: 6 additions & 0 deletions examples/cli/web-socket-url/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

const target = document.querySelector('#target');

target.innerHTML =
'Please check the ws request in devtools, it should try to connect to the protocol + server defined in the webSocketURL setting.';
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ module.exports = setup({
entry: './app.js',
devServer: {
host: '0.0.0.0',
public: 'https://localhost:8080',
client: {
webSocketURL: 'ws://localhost:8080',
},
firewall: false,
},
});
14 changes: 3 additions & 11 deletions lib/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -969,17 +969,9 @@ class Server {
}
}

// also allow public hostname if provided
if (typeof this.options.public === 'string') {
const idxPublic = this.options.public.indexOf(':');
const publicHostname =
idxPublic >= 0
? this.options.public.substr(0, idxPublic)
: this.options.public;

if (hostname === publicHostname) {
return true;
}
// Also allow if `client.webSocketURL.host` provided
if (typeof this.options.client.webSocketURL !== 'undefined') {
return this.options.client.webSocketURL.host === hostname;
}

// disallow
Expand Down
54 changes: 28 additions & 26 deletions lib/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -229,28 +229,6 @@
],
"description": "Allows to set custom transport to communicate with server."
},
"host": {
"type": "string",
"description": "Tells clients connected to devServer to use the provided host."
},
"path": {
"type": "string",
"description": "Tells clients connected to devServer to use the provided path to connect."
},
"port": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"enum": ["auto"]
}
],
"description": "Tells clients connected to devServer to use the provided port."
},
"logging": {
"enum": ["none", "error", "warn", "info", "log", "verbose"],
"decription": "Log level in the browser."
Expand Down Expand Up @@ -301,6 +279,34 @@
}
],
"description": "Tells devServer to inject a Hot Module Replacement entry."
},
"webSocketURL": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"host": {
"type": "string",
"minLength": 1,
"description": "Tells clients connected to devServer to use the provided host."
},
"port": {
"type": "number",
"description": "Tells clients connected to devServer to use the provided port."
},
"path": {
"type": "string",
"description": "Tells clients connected to devServer to use the provided path to connect."
}
}
}
],
"description": "When using dev server and you're proxying dev-server, the client script does not always know where to connect to."
}
},
"description": "Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient",
Expand Down Expand Up @@ -540,10 +546,6 @@
],
"description": "Proxying some URLs can be useful when you have a separate API backend development server and you want to send API requests on the same domain. https://webpack.js.org/configuration/dev-server/#devserverproxy"
},
"public": {
"type": "string",
"description": "When using dev server and you're proxying dev-server, the client script does not always know where to connect to. It will try to guess the URL of the server based on window.location, but if that fails you'll need to use this. https://webpack.js.org/configuration/dev-server/#devserverpublic"
},
"setupExitSignals": {
"type": "boolean",
"description": "It takes a boolean and if true (default on CLI), the server will close and exit the process on SIGINT and SIGTERM. https://webpack.js.org/configuration/dev-server/#devserversetupexitsignals"
Expand Down
Loading