Skip to content

[WIP]: make browser tab should open via Node API #1657

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

Closed
wants to merge 1 commit into from
Closed
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
68 changes: 2 additions & 66 deletions bin/webpack-dev-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
*/
const debug = require('debug')('webpack-dev-server');

const fs = require('fs');
const net = require('net');

const portfinder = require('portfinder');
const importLocal = require('import-local');

Expand All @@ -26,12 +23,11 @@ const webpack = require('webpack');

const options = require('./options');

const { colors, status, version, bonjour } = require('./utils');
const { colors, version } = require('./utils');

const Server = require('../lib/Server');

const addEntries = require('../lib/utils/addEntries');
const createDomain = require('../lib/utils/createDomain');
const createLogger = require('../lib/utils/createLogger');
const createConfig = require('../lib/utils/createConfig');

Expand Down Expand Up @@ -152,11 +148,6 @@ function startDevServer(config, options) {
}).apply(compiler);
}

const suffix =
options.inline !== false || options.lazy === true
? '/'
: '/webpack-dev-server/';

try {
server = new Server(compiler, options, log);
} catch (err) {
Expand All @@ -169,62 +160,7 @@ function startDevServer(config, options) {
throw err;
}

if (options.socket) {
server.listeningApp.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
const clientSocket = new net.Socket();

clientSocket.on('error', (err) => {
if (err.code === 'ECONNREFUSED') {
// No other server listening on this socket so it can be safely removed
fs.unlinkSync(options.socket);

server.listen(options.socket, options.host, (error) => {
if (error) {
throw error;
}
});
}
});

clientSocket.connect({ path: options.socket }, () => {
throw new Error('This socket is already used');
});
}
});

server.listen(options.socket, options.host, (err) => {
if (err) {
throw err;
}
// chmod 666 (rw rw rw)
const READ_WRITE = 438;

fs.chmod(options.socket, READ_WRITE, (err) => {
if (err) {
throw err;
}

const uri = createDomain(options, server.listeningApp) + suffix;

status(uri, options, log, argv.color);
});
});
} else {
server.listen(options.port, options.host, (err) => {
if (err) {
throw err;
}

if (options.bonjour) {
bonjour(options);
}

const uri = createDomain(options, server.listeningApp) + suffix;

status(uri, options, log, argv.color);
});
}
server.listen();
}

processOptions(config);
168 changes: 115 additions & 53 deletions lib/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const historyApiFallback = require('connect-history-api-fallback');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');

const { bonjour, status } = require('../bin/utils');
const createDomain = require('../lib/utils/createDomain');
const createLogger = require('./utils/createLogger');
const createCertificate = require('./utils/createCertificate');

Expand Down Expand Up @@ -91,6 +93,7 @@ class Server {
throw new Error("'filename' option must be set in lazy mode.");
}

this.options = options;
this.hot = options.hot || options.hotOnly;
this.headers = options.headers;
this.progress = options.progress;
Expand Down Expand Up @@ -754,82 +757,141 @@ class Server {
}

// delegate listen call and init sockjs
listen(port, hostname, fn) {
listen(
port = this.options.socket || this.options.port,
hostname = this.options.host,
fn
) {
const suffix =
this.options.inline !== false || this.options.lazy === true
? '/'
: '/webpack-dev-server/';

this.hostname = hostname;

const returnValue = this.listeningApp.listen(port, hostname, (err) => {
const socket = sockjs.createServer({
// Use provided up-to-date sockjs-client
sockjs_url: '/__webpack_dev_server__/sockjs.bundle.js',
// Limit useless logs
log: (severity, line) => {
if (severity === 'error') {
this.log.error(line);
} else {
this.log.debug(line);
const { socket, bonjour: bonjourValue } = this.options;

if (err) {
throw err;
}

if (socket) {
this.listeningApp.listeningApp.on('error', (e) => {
if (e.code === 'EADDRINUSE') {
const clientSocket = new net.Socket();

clientSocket.on('error', (err) => {
if (err.code === 'ECONNREFUSED') {
// No other server listening on this socket so it can be safely removed
fs.unlinkSync(socket);

if (e) {
throw e;
}
}
});

clientSocket.connect({ path: socket }, () => {
throw new Error('This socket is already used');
});
}
},
});
});

socket.on('connection', (connection) => {
if (!connection) {
return;
}
// chmod 666 (rw rw rw)
const READ_WRITE = 438;

if (
!this.checkHost(connection.headers) ||
!this.checkOrigin(connection.headers)
) {
this.sockWrite([connection], 'error', 'Invalid Host/Origin header');
fs.chmod(socket, READ_WRITE, (err) => {
if (err) {
throw err;
}

connection.close();
const uri = createDomain(this.options, this.listeningApp) + suffix;

return;
status(uri, options, log, color); // TODO: fix
});
} else {
if (bonjourValue) {
bonjour(this.options);
}

this.sockets.push(connection);
const uri = createDomain(this.options, this.listeningApp) + suffix;

connection.on('close', () => {
const idx = this.sockets.indexOf(connection);
status(uri, this.options, this.log, this.color);

if (idx >= 0) {
this.sockets.splice(idx, 1);
}
const socket = sockjs.createServer({
// Use provided up-to-date sockjs-client
sockjs_url: '/__webpack_dev_server__/sockjs.bundle.js',
// Limit useless logs
log: (severity, line) => {
if (severity === 'error') {
this.log.error(line);
} else {
this.log.debug(line);
}
},
});

if (this.hot) {
this.sockWrite([connection], 'hot');
}
socket.on('connection', (connection) => {
if (!connection) {
return;
}

if (this.progress) {
this.sockWrite([connection], 'progress', this.progress);
}
if (
!this.checkHost(connection.headers) ||
!this.checkOrigin(connection.headers)
) {
this.sockWrite([connection], 'error', 'Invalid Host/Origin header');

if (this.clientOverlay) {
this.sockWrite([connection], 'overlay', this.clientOverlay);
}
connection.close();

if (this.clientLogLevel) {
this.sockWrite([connection], 'log-level', this.clientLogLevel);
}
return;
}

if (!this._stats) {
return;
}
this.sockets.push(connection);

this._sendStats([connection], this._stats.toJson(STATS), true);
});
connection.on('close', () => {
const idx = this.sockets.indexOf(connection);

socket.installHandlers(this.listeningApp, {
prefix: this.sockPath,
});
if (idx >= 0) {
this.sockets.splice(idx, 1);
}
});

if (this.hot) {
this.sockWrite([connection], 'hot');
}

if (fn) {
fn.call(this.listeningApp, err);
if (this.progress) {
this.sockWrite([connection], 'progress', this.progress);
}

if (this.clientOverlay) {
this.sockWrite([connection], 'overlay', this.clientOverlay);
}

if (this.clientLogLevel) {
this.sockWrite([connection], 'log-level', this.clientLogLevel);
}

if (!this._stats) {
return;
}

this._sendStats([connection], this._stats.toJson(STATS), true);
});

socket.installHandlers(this.listeningApp, {
prefix: this.sockPath,
});

if (fn) {
fn.call(this.listeningApp, err);
}
}
});

return returnValue;
return returnValue;
});
}

close(cb) {
Expand Down