Skip to content

Commit

Permalink
feat: allow string value for client.webSocketURL.port (#3354)
Browse files Browse the repository at this point in the history
  • Loading branch information
snitin315 committed May 28, 2021
1 parent 7389612 commit f5e7f8f
Show file tree
Hide file tree
Showing 9 changed files with 481 additions and 10 deletions.
10 changes: 9 additions & 1 deletion lib/options.json
Expand Up @@ -296,7 +296,15 @@
"description": "Tells clients connected to devServer to use the provided host."
},
"port": {
"type": "number",
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"minLength": 1
}
],
"description": "Tells clients connected to devServer to use the provided port."
},
"path": {
Expand Down
14 changes: 13 additions & 1 deletion lib/utils/normalizeOptions.js
Expand Up @@ -74,6 +74,10 @@ function normalizeOptions(compiler, options, logger) {
options.liveReload =
typeof options.liveReload !== 'undefined' ? options.liveReload : true;

if (typeof options.port === 'string' && options.port !== 'auto') {
options.port = Number(options.port);
}

const defaultWebSocketServerType = 'ws';
const defaultWebSocketServerOptions = { path: '/ws' };

Expand All @@ -98,6 +102,12 @@ function normalizeOptions(compiler, options, logger) {
...options.webSocketServer.options,
},
};

if (typeof options.webSocketServer.options.port === 'string') {
options.webSocketServer.options.port = Number(
options.webSocketServer.options.port
);
}
}

if (!options.client) {
Expand All @@ -111,9 +121,11 @@ function normalizeOptions(compiler, options, logger) {

options.client.webSocketURL = {
host: parsedURL.hostname,
port: parsedURL.port,
port: Number(parsedURL.port),
path: parsedURL.pathname,
};
} else if (typeof options.client.webSocketURL.port === 'string') {
options.client.webSocketURL.port = Number(options.client.webSocketURL.port);
}

// Enable client overlay by default
Expand Down
15 changes: 11 additions & 4 deletions test/__snapshots__/validate-options.test.js.snap.webpack4
Expand Up @@ -150,14 +150,21 @@ exports[`options validate should throw an error on the "client" option with '{"w

exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":""}}' value 1`] = `
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
- configuration.client.webSocketURL.port should be a number.
-> Tells clients connected to devServer to use the provided port."
- configuration.client.webSocketURL.port should be an non-empty string."
`;

exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = `
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
- configuration.client.webSocketURL.port should be a number.
-> Tells clients connected to devServer to use the provided port."
- configuration.client.webSocketURL should be one of these:
non-empty string | object { host?, port?, path? }
-> When using dev server and you're proxying dev-server, the client script does not always know where to connect to.
Details:
* configuration.client.webSocketURL.port should be one of these:
number | non-empty string
-> Tells clients connected to devServer to use the provided port.
Details:
* configuration.client.webSocketURL.port should be a number.
* configuration.client.webSocketURL.port should be a non-empty string."
`;

exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = `
Expand Down
15 changes: 11 additions & 4 deletions test/__snapshots__/validate-options.test.js.snap.webpack5
Expand Up @@ -150,14 +150,21 @@ exports[`options validate should throw an error on the "client" option with '{"w

exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":""}}' value 1`] = `
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
- configuration.client.webSocketURL.port should be a number.
-> Tells clients connected to devServer to use the provided port."
- configuration.client.webSocketURL.port should be an non-empty string."
`;

exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = `
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
- configuration.client.webSocketURL.port should be a number.
-> Tells clients connected to devServer to use the provided port."
- configuration.client.webSocketURL should be one of these:
non-empty string | object { host?, port?, path? }
-> When using dev server and you're proxying dev-server, the client script does not always know where to connect to.
Details:
* configuration.client.webSocketURL.port should be one of these:
number | non-empty string
-> Tells clients connected to devServer to use the provided port.
Details:
* configuration.client.webSocketURL.port should be a number.
* configuration.client.webSocketURL.port should be a non-empty string."
`;

exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = `
Expand Down
76 changes: 76 additions & 0 deletions test/e2e/web-socket-server-and-url.test.js
Expand Up @@ -316,6 +316,82 @@ for (const webSocketServerType of webSocketServerTypes) {
});
});

describe('should work with custom client port as string', () => {
beforeAll((done) => {
const options = {
webSocketServer: webSocketServerType,
port: port2,
host: '0.0.0.0',
client: {
webSocketURL: {
port: `${port3}`,
},
},
};

testServer.startAwaitingCompilation(config, options, done);
});

afterAll(testServer.close);

describe('browser client', () => {
it('uses correct port and path', (done) => {
runBrowser().then(({ page, browser }) => {
waitForTest(browser, page, /ws/, (websocketUrl) => {
expect(websocketUrl).toContain(
`${websocketUrlProtocol}://localhost:${port3}/ws`
);

done();
});

page.goto(`http://localhost:${port2}/main`);
});
});
});
});

describe('should work with custom client.webSocketURL.port and webSocketServer.options.port both as string', () => {
beforeAll((done) => {
const options = {
webSocketServer: {
type: webSocketServerType,
options: {
host: '0.0.0.0',
port: `${port2}`,
},
},
port: port2,
host: '0.0.0.0',
client: {
webSocketURL: {
port: `${port3}`,
},
},
};

testServer.startAwaitingCompilation(config, options, done);
});

afterAll(testServer.close);

describe('browser client', () => {
it('uses correct port and path', (done) => {
runBrowser().then(({ page, browser }) => {
waitForTest(browser, page, /ws/, (websocketUrl) => {
expect(websocketUrl).toContain(
`${websocketUrlProtocol}://localhost:${port3}/ws`
);

done();
});

page.goto(`http://localhost:${port2}/main`);
});
});
});
});

describe('should work with custom client host', () => {
beforeAll((done) => {
const options = {
Expand Down
150 changes: 150 additions & 0 deletions test/server/utils/__snapshots__/normalizeOptions.test.js.snap.webpack4
Expand Up @@ -109,6 +109,44 @@ Object {
}
`;

exports[`normalizeOptions client host and string port should set correct options 1`] = `
Object {
"allowedHosts": "auto",
"client": Object {
"hotEntry": true,
"overlay": true,
"webSocketURL": Object {
"host": "my.host",
"port": 9000,
},
},
"compress": true,
"devMiddleware": Object {},
"hot": true,
"liveReload": true,
"setupExitSignals": true,
"static": Array [
Object {
"directory": "CWD",
"publicPath": Array [
"/",
],
"serveIndex": Object {
"icons": true,
},
"staticOptions": Object {},
"watch": Object {},
},
],
"webSocketServer": Object {
"options": Object {
"path": "/ws",
},
"type": "ws",
},
}
`;

exports[`normalizeOptions client path should set correct options 1`] = `
Object {
"allowedHosts": "auto",
Expand Down Expand Up @@ -219,6 +257,82 @@ Object {
}
`;

exports[`normalizeOptions client.transport ws string and webSocketServer object should set correct options 1`] = `
Object {
"allowedHosts": "auto",
"client": Object {
"hotEntry": true,
"overlay": true,
"transport": "ws",
"webSocketURL": Object {},
},
"compress": true,
"devMiddleware": Object {},
"hot": true,
"liveReload": true,
"setupExitSignals": true,
"static": Array [
Object {
"directory": "CWD",
"publicPath": Array [
"/",
],
"serveIndex": Object {
"icons": true,
},
"staticOptions": Object {},
"watch": Object {},
},
],
"webSocketServer": Object {
"options": Object {
"host": "myhost",
"path": "/ws",
"port": 8080,
},
"type": "ws",
},
}
`;

exports[`normalizeOptions client.transport ws string and webSocketServer object with port as string should set correct options 1`] = `
Object {
"allowedHosts": "auto",
"client": Object {
"hotEntry": true,
"overlay": true,
"transport": "ws",
"webSocketURL": Object {},
},
"compress": true,
"devMiddleware": Object {},
"hot": true,
"liveReload": true,
"setupExitSignals": true,
"static": Array [
Object {
"directory": "CWD",
"publicPath": Array [
"/",
],
"serveIndex": Object {
"icons": true,
},
"staticOptions": Object {},
"watch": Object {},
},
],
"webSocketServer": Object {
"options": Object {
"host": "myhost",
"path": "/ws",
"port": 8080,
},
"type": "ws",
},
}
`;

exports[`normalizeOptions client.transport ws string and webSocketServer ws string should set correct options 1`] = `
Object {
"allowedHosts": "auto",
Expand Down Expand Up @@ -575,6 +689,42 @@ Object {
}
`;

exports[`normalizeOptions port string should set correct options 1`] = `
Object {
"allowedHosts": "auto",
"client": Object {
"hotEntry": true,
"overlay": true,
"webSocketURL": Object {},
},
"compress": true,
"devMiddleware": Object {},
"hot": true,
"liveReload": true,
"port": 9000,
"setupExitSignals": true,
"static": Array [
Object {
"directory": "CWD",
"publicPath": Array [
"/",
],
"serveIndex": Object {
"icons": true,
},
"staticOptions": Object {},
"watch": Object {},
},
],
"webSocketServer": Object {
"options": Object {
"path": "/ws",
},
"type": "ws",
},
}
`;

exports[`normalizeOptions single compiler watchOptions is object should set correct options 1`] = `
Object {
"allowedHosts": "auto",
Expand Down

0 comments on commit f5e7f8f

Please sign in to comment.