Skip to content

Refactor client #1137

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 23 commits into from
Oct 12, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f4f63a6
moving client code
shellscape Sep 29, 2017
88d48e8
adding proper entry point
shellscape Sep 29, 2017
10d0430
reworkig client build process. client -> public
shellscape Sep 29, 2017
56be65b
removing pug, cleaning up after file move
shellscape Oct 1, 2017
dcf0782
update the devclient domain for new client location
shellscape Oct 1, 2017
545cebe
prune flags inherited from webpack's yargs config
shellscape Oct 1, 2017
b25612d
update examples cmd, clean readmes
shellscape Oct 2, 2017
e0dc8aa
correct log output
shellscape Oct 2, 2017
e717492
stop minifying client scripts. no need for dev envs
shellscape Oct 2, 2017
247a207
remove jquery from project
shellscape Oct 2, 2017
121e639
refactor and clean 'live' client files
shellscape Oct 2, 2017
b3c4d45
style.css -> live.css
shellscape Oct 3, 2017
de7c961
rewriting the overlay
shellscape Oct 3, 2017
0d4dc8a
improving log style, using loglevel for prefix
shellscape Oct 4, 2017
f1e9273
refactor client/index
shellscape Oct 4, 2017
8739121
monkey patching webpack/hot/log to match formatting
shellscape Oct 4, 2017
53e3f5d
Merge branch 'beta' into refactor-client
shellscape Oct 5, 2017
7192d3f
removing branch restrictions on CI
shellscape Oct 5, 2017
2fab70a
Merge branch 'refactor-client' of github.com:webpack/webpack-dev-serv…
shellscape Oct 5, 2017
163ca43
Merge branch 'beta' into refactor-client
shellscape Oct 5, 2017
9fdd135
Merge branch 'beta' into refactor-client
shellscape Oct 6, 2017
aea2698
Merge branch 'beta' into refactor-client
shellscape Oct 9, 2017
543321b
Merge branch 'beta' into refactor-client
shellscape Oct 10, 2017
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
Prev Previous commit
Next Next commit
refactor client/index
  • Loading branch information
shellscape committed Oct 4, 2017
commit f1e92731ae82e94c12ccf676d57c3782a7ec5045
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
},
"rules": {
"comma-dangle": ["error", "never"],
"curly": ["error"],
"consistent-return": "off",
"no-param-reassign": "off",
"no-underscore-dangle": "off",
Expand Down
2 changes: 1 addition & 1 deletion examples/modus-iframe/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
document.write("It's working.");

// This results in a warning:
if (!window) require(`./${window}parseable.js`);
// if (!window) require(`./${window}parseable.js`);

// This results in an error:
// if (!window) require('test');
2 changes: 2 additions & 0 deletions lib/client/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"window": true
},
"rules": {
"brace-style": ["error", "1tbs", { "allowSingleLine": false }],
"curly": ["error"],
"import/no-extraneous-dependencies": ["off"],
"import/no-webpack-loader-syntax": ["off"],
"import/no-unresolved": ["off"],
Expand Down
188 changes: 98 additions & 90 deletions lib/client/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,81 @@
/* eslint prefer-destructuring: off */

const url = require('url');
// const log = require('loglevel').getLogger('webpack-dev-server');
const log = require('./log');
const socket = require('./socket');
const overlay = require('./overlay');

const INFO = 'info';
const WARNING = 'warning';
const ERROR = 'error';
const NONE = 'none';

let hot = false;
let initial = true;
let currentHash = '';
let useWarningOverlay = false;
let useErrorOverlay = false;
let useProgress = false;
let urlParts;
let hotReload = true;
let isUnloading = false;

function getCurrentScriptSource() {
// `document.currentScript` is the most accurate way to find the current script,
// but is not supported in all browsers.
if (document.currentScript) { return document.currentScript.getAttribute('src'); }
if (document.currentScript) {
return document.currentScript.getAttribute('src');
}
// Fall back to getting all scripts in the document.
const scriptElements = document.scripts || [];
const currentScript = scriptElements[scriptElements.length - 1];
if (currentScript) { return currentScript.getAttribute('src'); }
if (currentScript) {
return currentScript.getAttribute('src');
}
// Fail as there was no script to use.
throw new Error('webpack-dev-server: Failed to get current script source.');
}

let urlParts;
let hotReload = true;
function reload() {
if (isUnloading || !hotReload) {
return;
}
if (hot) {
log.info('App hot update...');
// eslint-disable-next-line global-require
const hotEmitter = require('webpack/hot/emitter');
hotEmitter.emit('webpackHotUpdate', currentHash);
if (typeof self !== 'undefined' && self.window) {
// broadcast update to window
self.postMessage('webpackHotUpdate' + currentHash, '*');
}
} else {
log.info('App updated. Reloading...');
self.location.reload();
}
}

function publish(type, data) {
if (typeof self !== 'undefined' &&
(typeof WorkerGlobalScope === 'undefined' || !(self instanceof WorkerGlobalScope))) {
self.postMessage({
type: 'webpack' + type,
data: data
}, '*');
}
}

log.setDefaultLevel(INFO);

self.addEventListener('beforeunload', function beforeUnload() {
isUnloading = true;
});

if (typeof window !== 'undefined') {
const qs = window.location.search.toLowerCase();
hotReload = qs.indexOf('hotreload=false') === -1;
}

if (typeof __resourceQuery === 'string' && __resourceQuery) {
// If this bundle is inlined, use the resource query to get the correct url.
urlParts = url.parse(__resourceQuery.substr(1));
Expand All @@ -42,35 +94,28 @@ if (!urlParts.port || urlParts.port === '0') {
urlParts.port = self.location.port;
}

let hot = false;
let initial = true;
let currentHash = '';
let useWarningOverlay = false;
let useErrorOverlay = false;
let useProgress = false;

const INFO = 'info';
const WARNING = 'warning';
const ERROR = 'error';
const NONE = 'none';

// Set the default log level
log.setDefaultLevel(INFO);
let hostname = urlParts.hostname;
let protocol = urlParts.protocol;

// Send messages to the outside, so plugins can consume it.
function sendMsg(type, data) {
if (
typeof self !== 'undefined' &&
(typeof WorkerGlobalScope === 'undefined' ||
!(self instanceof WorkerGlobalScope))
) {
self.postMessage({
type: 'webpack' + type,
data: data
}, '*');
// check ipv4 and ipv6 `all hostname`
if (hostname === '0.0.0.0' || hostname === '::') {
// why do we need this check?
// hostname n/a for file protocol (example, when using electron, ionic)
// see: https://github.com/webpack/webpack-dev-server/pull/384
// eslint-disable-next-line no-bitwise
if (self.location.hostname && !!~self.location.protocol.indexOf('http')) {
hostname = self.location.hostname;
}
}

// `hostname` can be empty when the script path is relative. In that case, specifying
// a protocol would result in an invalid URL.
// When https is used in the app, secure websockets are always necessary
// because the browser doesn't accept non-secure websockets.
if (hostname && (self.location.protocol === 'https:' || urlParts.hostname === '0.0.0.0')) {
protocol = self.location.protocol;
}

const onSocketMsg = {
hot: function msgHot() {
hot = true;
Expand All @@ -79,16 +124,20 @@ const onSocketMsg = {
invalid: function msgInvalid() {
log.info('App updated. Recompiling...');
// fixes #1042. overlay doesn't clear if errors are fixed but warnings remain.
if (useWarningOverlay || useErrorOverlay) overlay.clear();
sendMsg('Invalid');
if (useWarningOverlay || useErrorOverlay) {
overlay.clear();
}
publish('Invalid');
},
hash: function msgHash(hash) {
currentHash = hash;
},
'still-ok': function stillOk() {
log.info('Nothing changed.');
if (useWarningOverlay || useErrorOverlay) overlay.clear();
sendMsg('StillOk');
if (useWarningOverlay || useErrorOverlay) {
overlay.clear();
}
publish('StillOk');
},
'log-level': function logLevel(level) {
const hotCtx = require.context('webpack/hot', false, /^\.\/log$/);
Expand Down Expand Up @@ -131,29 +180,35 @@ const onSocketMsg = {
if (useProgress) log.info('' + data.percent + '% - ' + data.msg + '.');
},
ok: function msgOk() {
sendMsg('Ok');
if (useWarningOverlay || useErrorOverlay) overlay.clear();
if (initial) return initial = false; // eslint-disable-line no-return-assign
reloadApp();
publish('Ok');
if (useWarningOverlay || useErrorOverlay) {
overlay.clear();
}
if (initial) {
return initial = false; // eslint-disable-line no-return-assign
}
reload();
},
'content-changed': function contentChanged() {
log.info('Content base changed. Reloading...');
self.location.reload();
},
warnings: function msgWarnings(warnings) {
log.warn('Warnings while compiling.');
sendMsg('Warnings', warnings);
for (let i = 0; i < warnings.length; i++) { log.warn(warnings[i]); }
publish('Warnings', warnings);
for (let i = 0; i < warnings.length; i++) {
log.warn(warnings[i]);
}
if (useWarningOverlay) {
overlay.showMessage(warnings);
}

if (initial) return initial = false; // eslint-disable-line no-return-assign
reloadApp();
reload();
},
errors: function msgErrors(errors) {
log.error('Errors while compiling. Reload prevented.');
sendMsg('Errors', errors);
publish('Errors', errors);
for (let i = 0; i < errors.length; i++) {
log.error(errors[i]);
}
Expand All @@ -166,33 +221,10 @@ const onSocketMsg = {
},
close: function msgClose() {
log.error('Disconnected!');
sendMsg('Close');
publish('Close');
}
};

let hostname = urlParts.hostname;
let protocol = urlParts.protocol;


// check ipv4 and ipv6 `all hostname`
if (hostname === '0.0.0.0' || hostname === '::') {
// why do we need this check?
// hostname n/a for file protocol (example, when using electron, ionic)
// see: https://github.com/webpack/webpack-dev-server/pull/384
// eslint-disable-next-line no-bitwise
if (self.location.hostname && !!~self.location.protocol.indexOf('http')) {
hostname = self.location.hostname;
}
}

// `hostname` can be empty when the script path is relative. In that case, specifying
// a protocol would result in an invalid URL.
// When https is used in the app, secure websockets are always necessary
// because the browser doesn't accept non-secure websockets.
if (hostname && (self.location.protocol === 'https:' || urlParts.hostname === '0.0.0.0')) {
protocol = self.location.protocol;
}

const socketUrl = url.format({
protocol: protocol,
auth: urlParts.auth,
Expand All @@ -202,27 +234,3 @@ const socketUrl = url.format({
});

socket(socketUrl, onSocketMsg);

let isUnloading = false;
self.addEventListener('beforeunload', function beforeUnload() {
isUnloading = true;
});

function reloadApp() {
if (isUnloading || !hotReload) {
return;
}
if (hot) {
log.info('App hot update...');
// eslint-disable-next-line global-require
const hotEmitter = require('webpack/hot/emitter');
hotEmitter.emit('webpackHotUpdate', currentHash);
if (typeof self !== 'undefined' && self.window) {
// broadcast update to window
self.postMessage('webpackHotUpdate' + currentHash, '*');
}
} else {
log.info('App updated. Reloading...');
self.location.reload();
}
}
8 changes: 6 additions & 2 deletions lib/client/js/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ function socket(url, handlers) {
};

sock.onclose = function onclose() {
if (retries === 0) { handlers.close(); }
if (retries === 0) {
handlers.close();
}

// Try to reconnect.
sock = null;
Expand All @@ -35,7 +37,9 @@ function socket(url, handlers) {
sock.onmessage = function onmessage(e) {
// This assumes that all data sent via the websocket is JSON.
const msg = JSON.parse(e.data);
if (handlers[msg.type]) { handlers[msg.type](msg.data); }
if (handlers[msg.type]) {
handlers[msg.type](msg.data);
}
};
}

Expand Down