Skip to content

Commit

Permalink
feat: add support for WDS client.webSocketURL (#529)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmmmwh authored Nov 8, 2021
1 parent 48fa80e commit cc18673
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 9 deletions.
51 changes: 42 additions & 9 deletions lib/utils/getAdditionalEntries.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,52 @@ function getAdditionalEntries({ devServer, options }) {
let resourceQuery = {};

if (devServer) {
const { sockHost, sockPath, sockPort, host, path, port, https, http2 } = devServer;
const { client, https, http2, sockHost, sockPath, sockPort } = devServer;
let { host, path, port } = devServer;

(sockHost || host) && (resourceQuery.sockHost = sockHost ? sockHost : host);
(sockPath || path) && (resourceQuery.sockPath = sockPath ? sockPath : path);
(sockPort || port) && (resourceQuery.sockPort = sockPort ? sockPort : port);
resourceQuery.sockProtocol = https || http2 ? 'https' : 'http';
let protocol = https || http2 ? 'https' : 'http';
if (sockHost) host = sockHost;
if (sockPath) path = sockPath;
if (sockPort) port = sockPort;

if (client && client.webSocketURL != null) {
let parsedUrl = client.webSocketURL;
if (typeof parsedUrl === 'string') parsedUrl = new URL(parsedUrl);

let auth;
if (parsedUrl.username) {
auth = parsedUrl.username;
if (parsedUrl.password) {
auth += ':' + parsedUrl.password;
}
}

if (parsedUrl.hostname != null) {
host = [auth != null && auth, parsedUrl.hostname].filter(Boolean).join('@');
}
if (parsedUrl.pathname != null) {
path = parsedUrl.pathname;
}
if (parsedUrl.port != null) {
port = String(parsedUrl.port) !== '0' ? parsedUrl.port : undefined;
}
if (parsedUrl.protocol != null) {
protocol = parsedUrl.protocol !== 'auto' ? parsedUrl.protocol.replace(':', '') : 'ws';
}
}

if (host) resourceQuery.sockHost = host;
if (path) resourceQuery.sockPath = path;
if (port) resourceQuery.sockPort = port;
resourceQuery.sockProtocol = protocol;
}

if (options.overlay) {
options.overlay.sockHost && (resourceQuery.sockHost = options.overlay.sockHost);
options.overlay.sockPath && (resourceQuery.sockPath = options.overlay.sockPath);
options.overlay.sockPort && (resourceQuery.sockPort = options.overlay.sockPort);
options.overlay.sockProtocol && (resourceQuery.sockProtocol = options.overlay.sockProtocol);
const { sockHost, sockPath, sockPort, sockProtocol } = options.overlay;
if (sockHost) resourceQuery.sockHost = sockHost;
if (sockPath) resourceQuery.sockPath = sockPath;
if (sockPort) resourceQuery.sockPort = sockPort;
if (sockProtocol) resourceQuery.sockProtocol = sockProtocol;
}

// We don't need to URI encode the resourceQuery as it will be parsed by Webpack
Expand Down
80 changes: 80 additions & 0 deletions test/unit/getAdditionalEntries.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,84 @@ describe('getAdditionalEntries', () => {
],
});
});

it('should use the devServer client.webSocketURL if it is an object', () => {
expect(
getAdditionalEntries({
options: DEFAULT_OPTIONS,
devServer: {
client: {
webSocketURL: {
hostname: 'localhost',
pathname: '/socket',
password: 'password',
protocol: 'ws',
port: 8080,
username: 'username',
},
},
},
})
).toStrictEqual({
prependEntries: [ReactRefreshEntry],
overlayEntries: [
`${ErrorOverlayEntry}?sockHost=username:password@localhost&sockPath=/socket&sockPort=8080&sockProtocol=ws`,
],
});
});

it('should handle devServer client.webSocketURL magic values', () => {
expect(
getAdditionalEntries({
options: DEFAULT_OPTIONS,
devServer: {
client: {
webSocketURL: {
hostname: '0.0.0.0',
pathname: '/socket',
protocol: 'auto',
port: 0,
},
},
},
})
).toStrictEqual({
prependEntries: [ReactRefreshEntry],
overlayEntries: [`${ErrorOverlayEntry}?sockHost=0.0.0.0&sockPath=/socket&sockProtocol=ws`],
});
});

it('should handle devServer client.webSocketURL missing values', () => {
expect(
getAdditionalEntries({
options: DEFAULT_OPTIONS,
devServer: {
client: {
webSocketURL: {},
},
},
})
).toStrictEqual({
prependEntries: [ReactRefreshEntry],
overlayEntries: [`${ErrorOverlayEntry}?sockProtocol=http`],
});
});

it('should use the devServer client.webSocketURL if it is a string', () => {
expect(
getAdditionalEntries({
options: DEFAULT_OPTIONS,
devServer: {
client: {
webSocketURL: 'ws://localhost:8080/socket',
},
},
})
).toStrictEqual({
prependEntries: [ReactRefreshEntry],
overlayEntries: [
`${ErrorOverlayEntry}?sockHost=localhost&sockPath=/socket&sockPort=8080&sockProtocol=ws`,
],
});
});
});

0 comments on commit cc18673

Please sign in to comment.