From 75fa8a4bf1a0b7a34c88df67936470e2ada432a8 Mon Sep 17 00:00:00 2001 From: Jared Palmer Date: Sun, 27 Aug 2017 17:59:11 -0400 Subject: [PATCH] Close #284. Add custom error overlay and webpack client --- packages/razzle-dev-utils/package.json | 4 +- .../razzle-dev-utils/webpackHotDevClient.js | 385 ++++++++++++++++++ packages/razzle-dev-utils/yarn.lock | 2 +- packages/razzle/config/createConfig.js | 16 +- packages/razzle/package.json | 1 + packages/razzle/yarn.lock | 183 ++++++++- 6 files changed, 569 insertions(+), 22 deletions(-) create mode 100644 packages/razzle-dev-utils/webpackHotDevClient.js diff --git a/packages/razzle-dev-utils/package.json b/packages/razzle-dev-utils/package.json index b174e725b..0b8bf6d73 100644 --- a/packages/razzle-dev-utils/package.json +++ b/packages/razzle-dev-utils/package.json @@ -12,6 +12,8 @@ ], "dependencies": { "chalk": "1.1.3", - "react-dev-utils": "3.0.0" + "react-dev-utils": "3.0.0", + "sockjs-client": "^1.1.4", + "strip-ansi": "^4.0.0" } } diff --git a/packages/razzle-dev-utils/webpackHotDevClient.js b/packages/razzle-dev-utils/webpackHotDevClient.js new file mode 100644 index 000000000..94b96f4a7 --- /dev/null +++ b/packages/razzle-dev-utils/webpackHotDevClient.js @@ -0,0 +1,385 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +// This alternative WebpackDevServer combines the functionality of: +// https://github.com/webpack/webpack-dev-server/blob/webpack-1/client/index.js +// https://github.com/webpack/webpack/blob/webpack-1/hot/dev-server.js + +// It only supports their simplest configuration (hot updates on same server). +// It makes some opinionated choices on top, like adding a syntax error overlay +// that looks similar to our console output. The error overlay is inspired by: +// https://github.com/glenjamin/webpack-hot-middleware + +var SockJS = require('sockjs-client'); +var stripAnsi = require('strip-ansi'); +var url = require('url'); +var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); +var ansiHTML = require('react-dev-utils/ansiHTML'); + +function createOverlayIframe(onIframeLoad) { + var iframe = document.createElement('iframe'); + iframe.id = 'react-dev-utils-webpack-hot-dev-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 = 2147483647; + iframe.onload = onIframeLoad; + return iframe; +} + +function addOverlayDivTo(iframe) { + // TODO: unify these styles with react-error-overlay + iframe.contentDocument.body.style.margin = 0; + iframe.contentDocument.body.style.maxWidth = '100vw'; + + var outerDiv = iframe.contentDocument.createElement('div'); + outerDiv.id = 'react-dev-utils-webpack-hot-dev-client-overlay-div'; + outerDiv.style.width = '100%'; + outerDiv.style.height = '100%'; + outerDiv.style.boxSizing = 'border-box'; + outerDiv.style.textAlign = 'center'; + outerDiv.style.backgroundColor = 'rgb(255, 255, 255)'; + + var div = iframe.contentDocument.createElement('div'); + div.style.position = 'relative'; + div.style.display = 'inline-flex'; + div.style.flexDirection = 'column'; + div.style.height = '100%'; + div.style.width = '1024px'; + div.style.maxWidth = '100%'; + div.style.overflowX = 'hidden'; + div.style.overflowY = 'auto'; + div.style.padding = '0.5rem'; + div.style.boxSizing = 'border-box'; + div.style.textAlign = 'left'; + div.style.fontFamily = 'Consolas, Menlo, monospace'; + div.style.fontSize = '11px'; + div.style.whiteSpace = 'pre-wrap'; + div.style.wordBreak = 'break-word'; + div.style.lineHeight = '1.5'; + div.style.color = 'rgb(41, 50, 56)'; + + outerDiv.appendChild(div); + iframe.contentDocument.body.appendChild(outerDiv); + return div; +} + +function overlayHeaderStyle() { + return ( + 'font-size: 2em;' + + 'font-family: sans-serif;' + + 'font-weight: 800;' + + 'color: rgb(206, 17, 38);' + + 'white-space: pre-wrap;' + + 'margin: 0 2rem 0.75rem 0px;' + + 'flex: 0 0 auto;' + + 'max-height: 35%;' + + 'overflow: auto;' + ); +} + +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 onIframeLoad() { + 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 showErrorOverlay(message) { + ensureOverlayDivExists(function onOverlayDivReady(overlayDiv) { + // TODO: unify this with our runtime overlay + overlayDiv.innerHTML = + '
Failed to compile 😵
' + + '
' +
+      '' +
+      ansiHTML(message) +
+      '
' + + '
' + + 'This error occurred during the build time and cannot be dismissed.
' + + '
' + + 'Quick Links: Razzle GitHub ' + + '| Report an Issue ' + + '| Community Slack ' + + '| Slide into Jared\'s DMs for help
'; + }); +} + +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; +} + +console.log(process.env.PORT); +// Connect to WebpackDevServer via a socket. +var connection = new SockJS( + url.format({ + protocol: window.location.protocol, + hostname: window.location.hostname, + // port: window.location.port, + port: parseInt(process.env.PORT) + 1, + // Hardcoded in WebpackDevServer + pathname: '/sockjs-node', + }) +); + +// Unlike WebpackDevServer client, we won't try to reconnect +// to avoid spamming the console. Disconnect usually happens +// when developer stops the server. +connection.onclose = function() { + if (typeof console !== 'undefined' && typeof console.info === 'function') { + console.info( + 'The development server has disconnected.\nRefresh the page if necessary.' + ); + } +}; + +// Remember some state related to hot module replacement. +var isFirstCompilation = true; +var mostRecentCompilationHash = null; +var hasCompileErrors = false; + +function clearOutdatedErrors() { + // Clean up outdated compile errors, if any. + if (typeof console !== 'undefined' && typeof console.clear === 'function') { + if (hasCompileErrors) { + console.clear(); + } + } +} + +// Successful compilation. +function handleSuccess() { + clearOutdatedErrors(); + + var isHotUpdate = !isFirstCompilation; + isFirstCompilation = false; + hasCompileErrors = false; + + // Attempt to apply hot updates or reload. + if (isHotUpdate) { + tryApplyUpdates(function onHotUpdateSuccess() { + // Only destroy it when we're sure it's a hot update. + // Otherwise it would flicker right before the reload. + destroyErrorOverlay(); + }); + } +} + +// Compilation with warnings (e.g. ESLint). +function handleWarnings(warnings) { + clearOutdatedErrors(); + + var isHotUpdate = !isFirstCompilation; + isFirstCompilation = false; + hasCompileErrors = false; + + function printWarnings() { + // Print warnings to the console. + var formatted = formatWebpackMessages({ + warnings: warnings, + errors: [], + }); + + if (typeof console !== 'undefined' && typeof console.warn === 'function') { + for (var i = 0; i < formatted.warnings.length; i++) { + if (i === 5) { + console.warn( + 'There were more warnings in other files.\n' + + 'You can find a complete log in the terminal.' + ); + break; + } + console.warn(stripAnsi(formatted.warnings[i])); + } + } + } + + // Attempt to apply hot updates or reload. + if (isHotUpdate) { + tryApplyUpdates(function onSuccessfulHotUpdate() { + // Only print warnings if we aren't refreshing the page. + // Otherwise they'll disappear right away anyway. + printWarnings(); + // Only destroy it when we're sure it's a hot update. + // Otherwise it would flicker right before the reload. + destroyErrorOverlay(); + }); + } else { + // Print initial warnings immediately. + printWarnings(); + } +} + +// Compilation with errors (e.g. syntax error or missing modules). +function handleErrors(errors) { + clearOutdatedErrors(); + + isFirstCompilation = false; + hasCompileErrors = true; + + // "Massage" webpack messages. + var formatted = formatWebpackMessages({ + errors: errors, + warnings: [], + }); + + // Only show the first error. + showErrorOverlay(formatted.errors[0]); + + // Also log them to the console. + if (typeof console !== 'undefined' && typeof console.error === 'function') { + for (var i = 0; i < formatted.errors.length; i++) { + console.error(stripAnsi(formatted.errors[i])); + } + } + + // Do not attempt to reload now. + // We will reload on next success instead. +} + +// There is a newer version of the code available. +function handleAvailableHash(hash) { + // Update last known compilation hash. + mostRecentCompilationHash = hash; +} + +// Handle messages from the server. +connection.onmessage = function(e) { + var message = JSON.parse(e.data); + switch (message.type) { + case 'hash': + handleAvailableHash(message.data); + break; + case 'still-ok': + case 'ok': + handleSuccess(); + break; + case 'content-changed': + // Triggered when a file from `contentBase` changed. + window.location.reload(); + break; + case 'warnings': + handleWarnings(message.data); + break; + case 'errors': + handleErrors(message.data); + break; + default: + // Do nothing. + } +}; + +// Is there a newer version of this code available? +function isUpdateAvailable() { + /* globals __webpack_hash__ */ + // __webpack_hash__ is the hash of the current compilation. + // It's a global variable injected by Webpack. + return mostRecentCompilationHash !== __webpack_hash__; +} + +// Webpack disallows updates in other states. +function canApplyUpdates() { + return module.hot.status() === 'idle'; +} + +// Attempt to update code on the fly, fall back to a hard reload. +function tryApplyUpdates(onHotUpdateSuccess) { + if (!module.hot) { + // HotModuleReplacementPlugin is not in Webpack configuration. + window.location.reload(); + return; + } + + if (!isUpdateAvailable() || !canApplyUpdates()) { + return; + } + + function handleApplyUpdates(err, updatedModules) { + if (err || !updatedModules) { + window.location.reload(); + return; + } + + if (typeof onHotUpdateSuccess === 'function') { + // Maybe we want to do something. + onHotUpdateSuccess(); + } + + if (isUpdateAvailable()) { + // While we were updating, there was a new update! Do it again. + tryApplyUpdates(); + } + } + + // https://webpack.github.io/docs/hot-module-replacement.html#check + var result = module.hot.check(/* autoApply */ true, handleApplyUpdates); + + // // Webpack 2 returns a Promise instead of invoking a callback + if (result && result.then) { + result.then( + function(updatedModules) { + handleApplyUpdates(null, updatedModules); + }, + function(err) { + handleApplyUpdates(err, null); + } + ); + } +} diff --git a/packages/razzle-dev-utils/yarn.lock b/packages/razzle-dev-utils/yarn.lock index d085b46cd..67c299453 100644 --- a/packages/razzle-dev-utils/yarn.lock +++ b/packages/razzle-dev-utils/yarn.lock @@ -346,7 +346,7 @@ signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -sockjs-client@1.1.4: +sockjs-client@1.1.4, sockjs-client@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" dependencies: diff --git a/packages/razzle/config/createConfig.js b/packages/razzle/config/createConfig.js index 08323e458..b1fad1133 100644 --- a/packages/razzle/config/createConfig.js +++ b/packages/razzle/config/createConfig.js @@ -12,6 +12,7 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin'); const paths = require('./paths'); const getClientEnv = require('./env').getClientEnv; const nodePath = require('./env').nodePath; +const errorOverlayMiddleware = require('react-error-overlay/middleware'); // This is the Webpack configuration factory. It's the juice! module.exports = ( @@ -266,9 +267,8 @@ module.exports = ( // specify our client entry point /client/index.js config.entry = { client: [ - require.resolve('webpack-dev-server/client') + - `?http://${dotenv.raw.HOST}:${devServerPort}`, - require.resolve('webpack/hot/dev-server'), + require.resolve('razzle-dev-utils/webpackHotDevClient'), + require.resolve('react-error-overlay'), paths.appClientIndexJs, ], }; @@ -307,6 +307,16 @@ module.exports = ( watchOptions: { ignored: /node_modules/, }, + setup(app) { + // This lets us open files from the runtime error overlay. + app.use(errorOverlayMiddleware()); + // This service worker file is effectively a 'no-op' that will reset any + // previous service worker registered for the same host:port combination. + // We do this in development to avoid hitting the production cache if + // it used the same host and port. + // https://github.com/facebookincubator/create-react-app/issues/2272#issuecomment-302832432 + // app.use(noopServiceWorkerMiddleware()); + }, }; // Add client-only development plugins config.plugins = [ diff --git a/packages/razzle/package.json b/packages/razzle/package.json index d6f05d269..99b170c94 100644 --- a/packages/razzle/package.json +++ b/packages/razzle/package.json @@ -45,6 +45,7 @@ "postcss-loader": "^2.0.6", "razzle-dev-utils": "^0.7.5", "react-dev-utils": "3.0.0", + "react-error-overlay": "^1.0.10", "start-server-webpack-plugin": "2.2.0", "style-loader": "0.18.2", "url-loader": "0.5.9", diff --git a/packages/razzle/yarn.lock b/packages/razzle/yarn.lock index 72e434508..5286b735d 100644 --- a/packages/razzle/yarn.lock +++ b/packages/razzle/yarn.lock @@ -48,7 +48,7 @@ address@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/address/-/address-1.0.1.tgz#363f5d3f2be26d0655d8afd5a9562e4fc2194537" -address@^1.0.1: +address@1.0.2, address@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/address/-/address-1.0.2.tgz#480081e82b587ba319459fef512f516fe03d58af" @@ -92,10 +92,18 @@ anser@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/anser/-/anser-1.3.0.tgz#65b42f01119edb5a2fc8ea6f0892274cbcbec6b1" +anser@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.1.tgz#c3641863a962cebef941ea2c8706f2cb4f0716bd" + ansi-escapes@^1.1.0, ansi-escapes@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" + ansi-html@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" @@ -835,9 +843,9 @@ babel-preset-jest@^20.0.3: dependencies: babel-plugin-jest-hoist "^20.0.3" -babel-preset-razzle@0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/babel-preset-razzle/-/babel-preset-razzle-0.7.0.tgz#34e7817fe93194671d3098f09f088f124eeee125" +babel-preset-razzle@^0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/babel-preset-razzle/-/babel-preset-razzle-0.7.5.tgz#c02920774136289d5aaa5d15e2360ea15fed9ec5" dependencies: babel-plugin-dynamic-import-node "1.0.1" babel-plugin-syntax-dynamic-import "6.18.0" @@ -873,6 +881,13 @@ babel-register@^6.24.1: mkdirp "^0.5.1" source-map-support "^0.4.2" +babel-runtime@6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + babel-runtime@^6.18.0, babel-runtime@^6.22.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.25.0.tgz#33b98eaa5d482bb01a8d1aa6b437ad2b01aec41c" @@ -1169,7 +1184,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.1: +chalk@^2.0.0, chalk@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" dependencies: @@ -1417,7 +1432,7 @@ cross-spawn@4.0.2: lru-cache "^4.0.1" which "^1.2.9" -cross-spawn@^5.0.1: +cross-spawn@5.1.0, cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -1633,6 +1648,13 @@ detect-node@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127" +detect-port-alt@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.3.tgz#a4d2f061d757a034ecf37c514260a98750f2b131" + dependencies: + address "^1.0.1" + debug "^2.6.0" + diff@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9" @@ -1901,6 +1923,12 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + dependencies: + homedir-polyfill "^1.0.1" + express@^4.13.3: version "4.15.4" resolved "https://registry.yarnpkg.com/express/-/express-4.15.4.tgz#032e2253489cf8fce02666beca3d11ed7a2daed1" @@ -1938,7 +1966,7 @@ extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" -external-editor@^2.0.1: +external-editor@^2.0.1, external-editor@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" dependencies: @@ -2028,6 +2056,10 @@ filesize@3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.3.0.tgz#53149ea3460e3b2e024962a51648aa572cf98122" +filesize@3.5.10: + version "3.5.10" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.10.tgz#fc8fa23ddb4ef9e5e0ab6e1e64f679a24a56761f" + fill-range@^2.1.0: version "2.2.3" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" @@ -2200,6 +2232,24 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +global-modules@1.0.0, global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + global@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" @@ -2325,6 +2375,12 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" +homedir-polyfill@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" + dependencies: + parse-passwd "^1.0.0" + hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" @@ -2444,7 +2500,7 @@ inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" -ini@~1.3.0: +ini@^1.3.4, ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" @@ -2466,6 +2522,25 @@ inquirer@3.0.6: strip-ansi "^3.0.0" through "^2.3.6" +inquirer@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.1.tgz#06ceb0f540f45ca548c17d6840959878265fa175" + dependencies: + ansi-escapes "^2.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + internal-ip@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" @@ -2622,6 +2697,10 @@ is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" +is-root@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5" + is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -2640,6 +2719,10 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +is-windows@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9" + is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" @@ -3640,6 +3723,12 @@ opn@5.0.0: dependencies: is-wsl "^1.1.0" +opn@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.1.0.tgz#72ce2306a17dbea58ff1041853352b4a8fc77519" + dependencies: + is-wsl "^1.1.0" + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -3744,6 +3833,10 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + parse5@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" @@ -4250,9 +4343,9 @@ range-parser@^1.0.3, range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" -razzle-dev-utils@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/razzle-dev-utils/-/razzle-dev-utils-0.7.3.tgz#c727b2a851f772903323ec1e008df028e9d426f9" +razzle-dev-utils@^0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/razzle-dev-utils/-/razzle-dev-utils-0.7.5.tgz#56880282d396ba1cc015efc7aa8f8dc16994b8db" dependencies: chalk "1.1.3" react-dev-utils "3.0.0" @@ -4288,6 +4381,41 @@ react-dev-utils@3.0.0: strip-ansi "3.0.1" text-table "0.2.0" +react-dev-utils@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-3.1.1.tgz#09ae7209a81384248db56547e718e65bd3b20eb5" + dependencies: + address "1.0.2" + anser "1.4.1" + babel-code-frame "6.22.0" + chalk "1.1.3" + cross-spawn "5.1.0" + detect-port-alt "1.1.3" + escape-string-regexp "1.0.5" + filesize "3.5.10" + global-modules "1.0.0" + gzip-size "3.0.0" + html-entities "1.2.1" + inquirer "3.2.1" + is-root "1.0.0" + opn "5.1.0" + recursive-readdir "2.2.1" + shell-quote "1.6.1" + sockjs-client "1.1.4" + strip-ansi "3.0.1" + text-table "0.2.0" + +react-error-overlay@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-1.0.10.tgz#da8cd1eafac41afdca2a33792b23694ef6c528f1" + dependencies: + anser "1.4.1" + babel-code-frame "6.22.0" + babel-runtime "6.23.0" + react-dev-utils "^3.1.0" + settle-promise "1.0.0" + source-map "0.5.6" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -4476,6 +4604,13 @@ requires-port@1.0.x, requires-port@1.x.x: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" +resolve-dir@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" @@ -4518,6 +4653,16 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" @@ -4617,6 +4762,10 @@ setprototypeof@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" +settle-promise@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/settle-promise/-/settle-promise-1.0.0.tgz#697adb58b821f387ce2757c06efc9de5f0ee33d8" + sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.8" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.8.tgz#37068c2c476b6baf402d14a49c67f597921f634f" @@ -4698,16 +4847,16 @@ source-map-support@^0.4.2: dependencies: source-map "^0.5.6" +source-map@0.5.6, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" dependencies: amdefine ">=0.0.4" -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - source-map@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" @@ -4812,7 +4961,7 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0: +string-width@^2.0.0, string-width@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -5301,7 +5450,7 @@ which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@^1.2.12, which@^1.2.9: +which@^1.2.12, which@^1.2.14, which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: