Skip to content

feat: allow string value for port #3354

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

Merged
merged 5 commits into from
May 28, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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: 9 additions & 1 deletion lib/options.json
Original file line number Diff line number Diff line change
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
16 changes: 14 additions & 2 deletions lib/utils/normalizeOptions.js
Original file line number Diff line number Diff line change
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,10 @@ function normalizeOptions(compiler, options, logger) {
...options.webSocketServer.options,
},
};

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

if (!options.client) {
Expand All @@ -111,10 +119,14 @@ 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
if (typeof options.client.overlay === 'undefined') {
Expand Down
15 changes: 11 additions & 4 deletions test/__snapshots__/validate-options.test.js.snap.webpack4
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading