forked from webpack/webpack-dev-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add transpiled client from client-src so that git+https or github: remote works while installing package.
- Loading branch information
Rohan Bhanderi
committed
Nov 1, 2018
1 parent
7cdfb74
commit 5757663
Showing
9 changed files
with
454 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
npm-debug.log | ||
node_modules | ||
/client | ||
/coverage | ||
/ssl/*.pem | ||
.idea/ | ||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,253 @@ | ||
'use strict'; | ||
|
||
/* global __resourceQuery WorkerGlobalScope self */ | ||
/* eslint prefer-destructuring: off */ | ||
|
||
var url = require('url'); | ||
var stripAnsi = require('strip-ansi'); | ||
var log = require('loglevel').getLogger('webpack-dev-server'); | ||
var socket = require('./socket'); | ||
var overlay = require('./overlay'); | ||
|
||
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'); | ||
} | ||
// Fall back to getting all scripts in the document. | ||
var scriptElements = document.scripts || []; | ||
var currentScript = scriptElements[scriptElements.length - 1]; | ||
if (currentScript) { | ||
return currentScript.getAttribute('src'); | ||
} | ||
// Fail as there was no script to use. | ||
throw new Error('[WDS] Failed to get current script source.'); | ||
} | ||
|
||
var urlParts = void 0; | ||
var hotReload = true; | ||
if (typeof window !== 'undefined') { | ||
var 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)); | ||
} else { | ||
// Else, get the url from the <script> this file was called with. | ||
var scriptHost = getCurrentScriptSource(); | ||
// eslint-disable-next-line no-useless-escape | ||
scriptHost = scriptHost.replace(/\/[^\/]+$/, ''); | ||
urlParts = url.parse(scriptHost || '/', false, true); | ||
} | ||
|
||
if (!urlParts.port || urlParts.port === '0') { | ||
urlParts.port = self.location.port; | ||
} | ||
|
||
var _hot = false; | ||
var initial = true; | ||
var currentHash = ''; | ||
var useWarningOverlay = false; | ||
var useErrorOverlay = false; | ||
var useProgress = false; | ||
|
||
var INFO = 'info'; | ||
var WARNING = 'warning'; | ||
var ERROR = 'error'; | ||
var NONE = 'none'; | ||
|
||
// Set the default log level | ||
log.setDefaultLevel(INFO); | ||
|
||
// 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 | ||
}, '*'); | ||
} | ||
} | ||
|
||
var onSocketMsg = { | ||
hot: function hot() { | ||
_hot = true; | ||
log.info('[WDS] Hot Module Replacement enabled.'); | ||
}, | ||
invalid: function invalid() { | ||
log.info('[WDS] App updated. Recompiling...'); | ||
// fixes #1042. overlay doesn't clear if errors are fixed but warnings remain. | ||
if (useWarningOverlay || useErrorOverlay) overlay.clear(); | ||
sendMsg('Invalid'); | ||
}, | ||
hash: function hash(_hash) { | ||
currentHash = _hash; | ||
}, | ||
|
||
'still-ok': function stillOk() { | ||
log.info('[WDS] Nothing changed.'); | ||
if (useWarningOverlay || useErrorOverlay) overlay.clear(); | ||
sendMsg('StillOk'); | ||
}, | ||
'log-level': function logLevel(level) { | ||
var hotCtx = require.context('webpack/hot', false, /^\.\/log$/); | ||
if (hotCtx.keys().indexOf('./log') !== -1) { | ||
hotCtx('./log').setLogLevel(level); | ||
} | ||
switch (level) { | ||
case INFO: | ||
case ERROR: | ||
log.setLevel(level); | ||
break; | ||
case WARNING: | ||
// loglevel's warning name is different from webpack's | ||
log.setLevel('warn'); | ||
break; | ||
case NONE: | ||
log.disableAll(); | ||
break; | ||
default: | ||
log.error('[WDS] Unknown clientLogLevel \'' + level + '\''); | ||
} | ||
}, | ||
overlay: function overlay(value) { | ||
if (typeof document !== 'undefined') { | ||
if (typeof value === 'boolean') { | ||
useWarningOverlay = false; | ||
useErrorOverlay = value; | ||
} else if (value) { | ||
useWarningOverlay = value.warnings; | ||
useErrorOverlay = value.errors; | ||
} | ||
} | ||
}, | ||
progress: function progress(_progress) { | ||
if (typeof document !== 'undefined') { | ||
useProgress = _progress; | ||
} | ||
}, | ||
|
||
'progress-update': function progressUpdate(data) { | ||
if (useProgress) log.info('[WDS] ' + data.percent + '% - ' + data.msg + '.'); | ||
}, | ||
ok: function ok() { | ||
sendMsg('Ok'); | ||
if (useWarningOverlay || useErrorOverlay) overlay.clear(); | ||
if (initial) return initial = false; // eslint-disable-line no-return-assign | ||
reloadApp(); | ||
}, | ||
|
||
'content-changed': function contentChanged() { | ||
log.info('[WDS] Content base changed. Reloading...'); | ||
self.location.reload(); | ||
}, | ||
warnings: function warnings(_warnings) { | ||
log.warn('[WDS] Warnings while compiling.'); | ||
var strippedWarnings = _warnings.map(function (warning) { | ||
return stripAnsi(warning); | ||
}); | ||
sendMsg('Warnings', strippedWarnings); | ||
for (var i = 0; i < strippedWarnings.length; i++) { | ||
log.warn(strippedWarnings[i]); | ||
} | ||
if (useWarningOverlay) overlay.showMessage(_warnings); | ||
|
||
if (initial) return initial = false; // eslint-disable-line no-return-assign | ||
reloadApp(); | ||
}, | ||
errors: function errors(_errors) { | ||
log.error('[WDS] Errors while compiling. Reload prevented.'); | ||
var strippedErrors = _errors.map(function (error) { | ||
return stripAnsi(error); | ||
}); | ||
sendMsg('Errors', strippedErrors); | ||
for (var i = 0; i < strippedErrors.length; i++) { | ||
log.error(strippedErrors[i]); | ||
} | ||
if (useErrorOverlay) overlay.showMessage(_errors); | ||
initial = false; | ||
}, | ||
error: function error(_error) { | ||
log.error(_error); | ||
}, | ||
close: function close() { | ||
log.error('[WDS] Disconnected!'); | ||
sendMsg('Close'); | ||
} | ||
}; | ||
|
||
var hostname = urlParts.hostname; | ||
var 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; | ||
} | ||
|
||
var socketUrl = url.format({ | ||
protocol: protocol, | ||
auth: urlParts.auth, | ||
hostname: hostname, | ||
port: urlParts.port, | ||
pathname: urlParts.path == null || urlParts.path === '/' ? '/sockjs-node' : urlParts.path | ||
}); | ||
|
||
socket(socketUrl, onSocketMsg); | ||
|
||
var isUnloading = false; | ||
self.addEventListener('beforeunload', function () { | ||
isUnloading = true; | ||
}); | ||
|
||
function reloadApp() { | ||
if (isUnloading || !hotReload) { | ||
return; | ||
} | ||
if (_hot) { | ||
log.info('[WDS] App hot update...'); | ||
// eslint-disable-next-line global-require | ||
var hotEmitter = require('webpack/hot/emitter'); | ||
hotEmitter.emit('webpackHotUpdate', currentHash); | ||
if (typeof self !== 'undefined' && self.window) { | ||
// broadcast update to window | ||
self.postMessage('webpackHotUpdate' + currentHash, '*'); | ||
} | ||
} else { | ||
var rootWindow = self; | ||
// use parent window for reload (in case we're in an iframe with no valid src) | ||
var intervalId = self.setInterval(function () { | ||
if (rootWindow.location.protocol !== 'about:') { | ||
// reload immediately if protocol is valid | ||
applyReload(rootWindow, intervalId); | ||
} else { | ||
rootWindow = rootWindow.parent; | ||
if (rootWindow.parent === rootWindow) { | ||
// if parent equals current window we've reached the root which would continue forever, so trigger a reload anyways | ||
applyReload(rootWindow, intervalId); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
function applyReload(rootWindow, intervalId) { | ||
clearInterval(intervalId); | ||
log.info('[WDS] App updated. Reloading...'); | ||
rootWindow.location.reload(); | ||
} | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"/><script type="text/javascript" charset="utf-8" src="/__webpack_dev_server__/live.bundle.js"></script></head><body></body></html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
'use strict'; | ||
|
||
// The error overlay is inspired (and mostly copied) from Create React App (https://github.com/facebookincubator/create-react-app) | ||
// They, in turn, got inspired by webpack-hot-middleware (https://github.com/glenjamin/webpack-hot-middleware). | ||
|
||
var ansiHTML = require('ansi-html'); | ||
var Entities = require('html-entities').AllHtmlEntities; | ||
|
||
var entities = new Entities(); | ||
|
||
var colors = { | ||
reset: ['transparent', 'transparent'], | ||
black: '181818', | ||
red: 'E36049', | ||
green: 'B3CB74', | ||
yellow: 'FFD080', | ||
blue: '7CAFC2', | ||
magenta: '7FACCA', | ||
cyan: 'C3C2EF', | ||
lightgrey: 'EBE7E3', | ||
darkgrey: '6D7891' | ||
}; | ||
ansiHTML.setColors(colors); | ||
|
||
function createOverlayIframe(onIframeLoad) { | ||
var iframe = document.createElement('iframe'); | ||
iframe.id = 'webpack-dev-server-client-overlay'; | ||
iframe.src = 'about:blank'; | ||
iframe.style.position = 'fixed'; | ||
iframe.style.left = 0; | ||
iframe.style.top = 0; | ||
iframe.style.right = 0; | ||
iframe.style.bottom = 0; | ||
iframe.style.width = '100vw'; | ||
iframe.style.height = '100vh'; | ||
iframe.style.border = 'none'; | ||
iframe.style.zIndex = 9999999999; | ||
iframe.onload = onIframeLoad; | ||
return iframe; | ||
} | ||
|
||
function addOverlayDivTo(iframe) { | ||
var div = iframe.contentDocument.createElement('div'); | ||
div.id = 'webpack-dev-server-client-overlay-div'; | ||
div.style.position = 'fixed'; | ||
div.style.boxSizing = 'border-box'; | ||
div.style.left = 0; | ||
div.style.top = 0; | ||
div.style.right = 0; | ||
div.style.bottom = 0; | ||
div.style.width = '100vw'; | ||
div.style.height = '100vh'; | ||
div.style.backgroundColor = 'rgba(0, 0, 0, 0.85)'; | ||
div.style.color = '#E8E8E8'; | ||
div.style.fontFamily = 'Menlo, Consolas, monospace'; | ||
div.style.fontSize = 'large'; | ||
div.style.padding = '2rem'; | ||
div.style.lineHeight = '1.2'; | ||
div.style.whiteSpace = 'pre-wrap'; | ||
div.style.overflow = 'auto'; | ||
iframe.contentDocument.body.appendChild(div); | ||
return div; | ||
} | ||
|
||
var overlayIframe = null; | ||
var overlayDiv = null; | ||
var lastOnOverlayDivReady = null; | ||
|
||
function ensureOverlayDivExists(onOverlayDivReady) { | ||
if (overlayDiv) { | ||
// Everything is ready, call the callback right away. | ||
onOverlayDivReady(overlayDiv); | ||
return; | ||
} | ||
|
||
// Creating an iframe may be asynchronous so we'll schedule the callback. | ||
// In case of multiple calls, last callback wins. | ||
lastOnOverlayDivReady = onOverlayDivReady; | ||
|
||
if (overlayIframe) { | ||
// We're already creating it. | ||
return; | ||
} | ||
|
||
// Create iframe and, when it is ready, a div inside it. | ||
overlayIframe = createOverlayIframe(function () { | ||
overlayDiv = addOverlayDivTo(overlayIframe); | ||
// Now we can talk! | ||
lastOnOverlayDivReady(overlayDiv); | ||
}); | ||
|
||
// Zalgo alert: onIframeLoad() will be called either synchronously | ||
// or asynchronously depending on the browser. | ||
// We delay adding it so `overlayIframe` is set when `onIframeLoad` fires. | ||
document.body.appendChild(overlayIframe); | ||
} | ||
|
||
function showMessageOverlay(message) { | ||
ensureOverlayDivExists(function (div) { | ||
// Make it look similar to our terminal. | ||
div.innerHTML = '<span style="color: #' + colors.red + '">Failed to compile.</span><br><br>' + ansiHTML(entities.encode(message)); | ||
}); | ||
} | ||
|
||
function destroyErrorOverlay() { | ||
if (!overlayDiv) { | ||
// It is not there in the first place. | ||
return; | ||
} | ||
|
||
// Clean up and reset internal state. | ||
document.body.removeChild(overlayIframe); | ||
overlayDiv = null; | ||
overlayIframe = null; | ||
lastOnOverlayDivReady = null; | ||
} | ||
|
||
// Successful compilation. | ||
exports.clear = function handleSuccess() { | ||
destroyErrorOverlay(); | ||
}; | ||
|
||
// Compilation with errors (e.g. syntax error or missing modules). | ||
exports.showMessage = function handleMessage(messages) { | ||
showMessageOverlay(messages[0]); | ||
}; |
Oops, something went wrong.