Skip to content

Commit

Permalink
feat(server): add transport mode
Browse files Browse the repository at this point in the history
  • Loading branch information
knagaitsev committed Jul 23, 2019
1 parent 05bdb0c commit 2b6ea2e
Show file tree
Hide file tree
Showing 18 changed files with 923 additions and 780 deletions.
35 changes: 22 additions & 13 deletions lib/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,29 @@ class Server {

this.log = _log || createLogger(options);

// set serverMode default
if (this.options.serverMode === undefined) {
this.options.serverMode = 'sockjs';
} else {
this.log.warn(
'serverMode is an experimental option, meaning its usage could potentially change without warning'
);
}
// set clientMode default
if (this.options.clientMode === undefined) {
this.options.clientMode = 'sockjs';
if (this.options.transportMode === undefined) {
this.options.transportMode = {
server: 'sockjs',
client: 'sockjs',
};
} else {
switch (typeof this.options.transportMode) {
case 'string':
this.options.transportMode = {
server: this.options.transportMode,
client: this.options.transportMode,
};
break;
// if not a string, it is an object
default:
this.options.transportMode.server =
this.options.transportMode.server || 'sockjs';
this.options.transportMode.client =
this.options.transportMode.client || 'sockjs';
}

this.log.warn(
'clientMode is an experimental option, meaning its usage could potentially change without warning'
'transportMode is an experimental option, meaning its usage could potentially change without warning'
);
}

Expand Down Expand Up @@ -686,7 +695,7 @@ class Server {

if (!headers) {
this.log.warn(
'serverMode implementation must pass headers to the callback of onConnection(f) ' +
'transportMode.server implementation must pass headers to the callback of onConnection(f) ' +
'via f(connection, headers) in order for clients to pass a headers security check'
);
}
Expand Down
41 changes: 26 additions & 15 deletions lib/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@
"warning"
]
},
"clientMode": {
"type": "string"
},
"compress": {
"type": "boolean"
},
Expand Down Expand Up @@ -303,16 +300,6 @@
"serveIndex": {
"type": "boolean"
},
"serverMode": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Function"
}
]
},
"serverSideRender": {
"type": "boolean"
},
Expand Down Expand Up @@ -364,6 +351,31 @@
}
]
},
"transportMode": {
"anyOf": [
{
"type": "object",
"properties": {
"client": {
"type": "string"
},
"server": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Function"
}
]
}
}
},
{
"enum": ["sockjs", "ws"]
}
]
},
"useLocalIp": {
"type": "boolean"
},
Expand Down Expand Up @@ -396,7 +408,6 @@
"ca": "should be {String|Buffer}",
"cert": "should be {String|Buffer}",
"clientLogLevel": "should be {String} and equal to one of the allowed values\n\n [ 'none', 'silent', 'info', 'debug', 'trace', 'error', 'warning', 'warn' ]\n\n (https://webpack.js.org/configuration/dev-server/#devserverclientloglevel)",
"clientMode": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverclientmode)",
"compress": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devservercompress)",
"contentBase": "should be {Number|String|Array} (https://webpack.js.org/configuration/dev-server/#devservercontentbase)",
"disableHostCheck": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverdisablehostcheck)",
Expand Down Expand Up @@ -438,7 +449,6 @@
"reporter": "should be {Function} (https://github.com/webpack/webpack-dev-middleware#reporter)",
"requestCert": "should be {Boolean}",
"serveIndex": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverserveindex)",
"serverMode": "should be {String|Function} (https://webpack.js.org/configuration/dev-server/#devserverservermode)",
"serverSideRender": "should be {Boolean} (https://github.com/webpack/webpack-dev-middleware#serversiderender)",
"setup": "should be {Function} (https://webpack.js.org/configuration/dev-server/#devserversetup)",
"sockHost": "should be {String|Null} (https://webpack.js.org/configuration/dev-server/#devserversockhost)",
Expand All @@ -447,6 +457,7 @@
"socket": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserversocket)",
"staticOptions": "should be {Object} (https://webpack.js.org/configuration/dev-server/#devserverstaticoptions)",
"stats": "should be {Object|Boolean} (https://webpack.js.org/configuration/dev-server/#devserverstats-)",
"transportMode": "should be {String|Object} (https://webpack.js.org/configuration/dev-server/#devservertransportmode)",
"useLocalIp": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserveruselocalip)",
"warn": "should be {Function}",
"watchContentBase": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverwatchcontentbase)",
Expand Down
10 changes: 5 additions & 5 deletions lib/utils/getSocketClientPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
function getSocketClientPath(options) {
let ClientImplementation;
let clientImplFound = true;
switch (typeof options.clientMode) {
switch (typeof options.transportMode.client) {
case 'string':
// could be 'sockjs', 'ws', or a path that should be required
if (options.clientMode === 'sockjs') {
if (options.transportMode.client === 'sockjs') {
ClientImplementation = require('../../client/clients/SockJSClient');
} else if (options.clientMode === 'ws') {
} else if (options.transportMode.client === 'ws') {
ClientImplementation = require('../../client/clients/WebsocketClient');
} else {
try {
// eslint-disable-next-line import/no-dynamic-require
ClientImplementation = require(options.clientMode);
ClientImplementation = require(options.transportMode.client);
} catch (e) {
clientImplFound = false;
}
Expand All @@ -25,7 +25,7 @@ function getSocketClientPath(options) {

if (!clientImplFound) {
throw new Error(
"clientMode must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to " +
"transportMode.client must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to " +
'a JS file which exports a class extending BaseClient (webpack-dev-server/client-src/clients/BaseClient) ' +
'via require.resolve(...)'
);
Expand Down
12 changes: 6 additions & 6 deletions lib/utils/getSocketServerImplementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
function getSocketServerImplementation(options) {
let ServerImplementation;
let serverImplFound = true;
switch (typeof options.serverMode) {
switch (typeof options.transportMode.server) {
case 'string':
// could be 'sockjs', in the future 'ws', or a path that should be required
if (options.serverMode === 'sockjs') {
if (options.transportMode.server === 'sockjs') {
ServerImplementation = require('../servers/SockJSServer');
} else if (options.serverMode === 'ws') {
} else if (options.transportMode.server === 'ws') {
ServerImplementation = require('../servers/WebsocketServer');
} else {
try {
// eslint-disable-next-line import/no-dynamic-require
ServerImplementation = require(options.serverMode);
ServerImplementation = require(options.transportMode.server);
} catch (e) {
serverImplFound = false;
}
Expand All @@ -22,15 +22,15 @@ function getSocketServerImplementation(options) {
case 'function':
// potentially do more checks here to confirm that the user implemented this properlly
// since errors could be difficult to understand
ServerImplementation = options.serverMode;
ServerImplementation = options.transportMode.server;
break;
default:
serverImplFound = false;
}

if (!serverImplFound) {
throw new Error(
"serverMode must be a string denoting a default implementation (e.g. 'sockjs', 'ws'), a full path to " +
"transportMode.server must be a string denoting a default implementation (e.g. 'sockjs', 'ws'), a full path to " +
'a JS file which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer) ' +
'via require.resolve(...), or the class itself which extends BaseServer'
);
Expand Down
7 changes: 3 additions & 4 deletions test/e2e/Client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,17 @@ const cssFilePath = resolve(__dirname, '../fixtures/reload-config/main.css');
describe('reload', () => {
const modes = [
{
title: 'hot with default clientMode (sockjs)',
title: 'hot with default transportMode.client (sockjs)',
options: {
hot: true,
},
shouldRefresh: false,
},
{
title: 'hot with clientMode ws',
title: 'hot with transportMode.client ws',
options: {
hot: true,
clientMode: 'ws',
serverMode: require.resolve('../../lib/servers/WebsocketServer'),
transportMode: 'ws',
},
shouldRefresh: false,
},
Expand Down
3 changes: 1 addition & 2 deletions test/e2e/ProvidePlugin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ describe('ProvidePlugin', () => {
port,
host: '0.0.0.0',
inline: true,
clientMode: 'ws',
serverMode: require.resolve('../../lib/servers/WebsocketServer'),
transportMode: 'ws',
watchOptions: {
poll: true,
},
Expand Down
18 changes: 10 additions & 8 deletions test/e2e/ClientMode.test.js → test/e2e/TransportMode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,35 @@
const testServer = require('../helpers/test-server');
const config = require('../fixtures/client-config/webpack.config');
const runBrowser = require('../helpers/run-browser');
const port = require('../ports-map').ClientMode;
const port = require('../ports-map').TransportMode;
const {
initConsoleDelay,
awaitServerCloseDelay,
} = require('../helpers/puppeteer-constants');

describe('clientMode', () => {
describe('transportMode client', () => {
const modes = [
{
title: 'sockjs',
options: {
clientMode: 'sockjs',
transportMode: 'sockjs',
},
},
{
title: 'ws',
options: {
clientMode: 'ws',
serverMode: require.resolve('../../lib/servers/WebsocketServer'),
transportMode: 'ws',
},
},
{
title: 'custom client',
options: {
clientMode: require.resolve(
'../fixtures/custom-client/CustomSockJSClient'
),
transportMode: {
server: 'sockjs',
client: require.resolve(
'../fixtures/custom-client/CustomSockJSClient'
),
},
},
},
];
Expand Down
50 changes: 38 additions & 12 deletions test/options.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,6 @@ describe('options', () => {
],
failure: ['whoops!'],
},
clientMode: {
success: ['sockjs', require.resolve('../client/clients/SockJSClient')],
failure: [false],
},
compress: {
success: [true],
failure: [''],
Expand Down Expand Up @@ -361,14 +357,6 @@ describe('options', () => {
success: [true],
failure: [''],
},
serverMode: {
success: [
'sockjs',
require.resolve('../lib/servers/SockJSServer'),
SockJSServer,
],
failure: [false],
},
serverSideRender: {
success: [true],
failure: [''],
Expand Down Expand Up @@ -410,6 +398,44 @@ describe('options', () => {
],
failure: ['whoops!', null],
},
transportMode: {
success: [
'ws',
'sockjs',
{
server: 'sockjs',
},
{
server: require.resolve('../lib/servers/SockJSServer'),
},
{
server: SockJSServer,
},
{
client: 'sockjs',
},
{
client: require.resolve('../client/clients/SockJSClient'),
},
{
server: SockJSServer,
client: require.resolve('../client/clients/SockJSClient'),
},
],
failure: [
'nonexistent-implementation',
null,
{
notAnOption: true,
},
{
server: false,
},
{
client: () => {},
},
],
},
useLocalIp: {
success: [false],
failure: [''],
Expand Down
5 changes: 2 additions & 3 deletions test/ports-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@ const portsList = {
'open-option': 1,
'port-option': 1,
'proxy-option': 4,
'serverMode-option': 1,
'transportMode-option': 1,
'sockPath-option': 1,
'stats-option': 1,
ProvidePlugin: 1,
WebsocketClient: 1,
WebsocketServer: 1,
ClientMode: 1,
'clientMode-option': 1,
TransportMode: 1,
Progress: 1,
'progress-option': 1,
'profile-option': 1,
Expand Down

0 comments on commit 2b6ea2e

Please sign in to comment.