From 92a79f4203588dc97724526362d11b55ceb14e40 Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Sun, 17 Sep 2017 13:03:49 +0530 Subject: [PATCH 01/11] Make error overlay to run in the context of the iframe --- packages/react-error-overlay/package.json | 13 +-- .../react-error-overlay/src/iframeScript.js | 57 ++++++++++++ packages/react-error-overlay/src/index.js | 87 ++++++++----------- .../react-error-overlay/webpack.config.js | 27 ++++++ 4 files changed, 129 insertions(+), 55 deletions(-) create mode 100644 packages/react-error-overlay/src/iframeScript.js create mode 100644 packages/react-error-overlay/webpack.config.js diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index 7640d1c5d92..90bd685f6e0 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -5,10 +5,10 @@ "main": "lib/index.js", "scripts": { "prepublishOnly": "npm run build:prod && npm test", - "start": "rimraf lib/ && cross-env NODE_ENV=development npm run build -- --watch", - "test": "flow && jest", - "build": "rimraf lib/ && babel src/ -d lib/", - "build:prod": "rimraf lib/ && cross-env NODE_ENV=production babel src/ -d lib/" + "start": "rimraf lib/ && cross-env NODE_ENV=development webpack --config webpack.config.js -w & NODE_ENV=development babel src/ -d lib/ -w", + "test": "flow && cross-env NODE_ENV=test jest", + "build": "rimraf lib/ && cross-env NODE_ENV=development babel src/ -d lib/ && cross-env NODE_ENV=production webpack --config webpack.config.js", + "build:prod": "rimraf lib/ && cross-env NODE_ENV=production babel src/ -d lib/ && cross-env NODE_ENV=production webpack --config webpack.config.js" }, "repository": "facebookincubator/create-react-app", "license": "MIT", @@ -33,12 +33,14 @@ "dependencies": { "anser": "1.4.1", "babel-code-frame": "6.22.0", + "babel-loader": "^7.1.2", "babel-runtime": "6.26.0", "html-entities": "1.2.1", "react": "^15 || ^16", "react-dom": "^15 || ^16", "settle-promise": "1.0.0", - "source-map": "0.5.6" + "source-map": "0.5.6", + "webpack": "^3.6.0" }, "devDependencies": { "babel-cli": "6.24.1", @@ -54,6 +56,7 @@ "flow-bin": "^0.54.0", "jest": "20.0.4", "jest-fetch-mock": "1.2.1", + "raw-loader": "^0.5.1", "rimraf": "^2.6.1" }, "jest": { diff --git a/packages/react-error-overlay/src/iframeScript.js b/packages/react-error-overlay/src/iframeScript.js new file mode 100644 index 00000000000..adcdc7fa1db --- /dev/null +++ b/packages/react-error-overlay/src/iframeScript.js @@ -0,0 +1,57 @@ +/** + * 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. + */ +import React from 'react'; +import ReactDOM from 'react-dom'; +import CompileErrorContainer from './containers/CompileErrorContainer'; +import RuntimeErrorContainer from './containers/RuntimeErrorContainer'; +import { overlayStyle } from './styles'; +import { applyStyles } from './utils/dom/css'; + +let iframeRoot = null; + +function render({ + currentBuildError, + currentRuntimeErrorRecords, + dismissRuntimeErrors, + launchEditorEndpoint, +}) { + if (currentBuildError) { + return ; + } + if (currentRuntimeErrorRecords.length > 0) { + return ( + + ); + } + return null; +} + +window.updateContent = function updateContent(errorOverlayProps) { + let renderedElement = render(errorOverlayProps); + + if (renderedElement === null) { + ReactDOM.unmountComponentAtNode(iframeRoot); + return false; + } + // Update the overlay + ReactDOM.render(renderedElement, iframeRoot); + return true; +}; + +document.body.style.margin = '0'; +// Keep popup within body boundaries for iOS Safari +document.body.style['max-width'] = '100vw'; +iframeRoot = document.createElement('div'); +applyStyles(iframeRoot, overlayStyle); +document.body.appendChild(iframeRoot); +window.parent.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__.iframeReady(); diff --git a/packages/react-error-overlay/src/index.js b/packages/react-error-overlay/src/index.js index 23f9e783885..ae834f7a087 100644 --- a/packages/react-error-overlay/src/index.js +++ b/packages/react-error-overlay/src/index.js @@ -6,15 +6,15 @@ */ /* @flow */ -import React from 'react'; -import type { Element } from 'react'; -import ReactDOM from 'react-dom'; -import CompileErrorContainer from './containers/CompileErrorContainer'; -import RuntimeErrorContainer from './containers/RuntimeErrorContainer'; import { listenToRuntimeErrors } from './listenToRuntimeErrors'; -import { iframeStyle, overlayStyle } from './styles'; +import { iframeStyle } from './styles'; import { applyStyles } from './utils/dom/css'; +/* eslint-disable import/no-webpack-loader-syntax */ +//$FlowFixMe +import iframeScript from 'raw-loader!./bundle.js'; +/* eslint-enable import/no-webpack-loader-syntax */ + import type { ErrorRecord } from './listenToRuntimeErrors'; type RuntimeReportingOptions = {| @@ -25,8 +25,8 @@ type RuntimeReportingOptions = {| let iframe: null | HTMLIFrameElement = null; let isLoadingIframe: boolean = false; +var isIframeReady: boolean = false; -let renderedElement: null | Element = null; let currentBuildError: null | string = null; let currentRuntimeErrorRecords: Array = []; let currentRuntimeErrorOptions: null | RuntimeReportingOptions = null; @@ -88,15 +88,14 @@ export function stopReportingRuntimeErrors() { } function update() { - renderedElement = render(); // Loading iframe can be either sync or async depending on the browser. if (isLoadingIframe) { // Iframe is loading. // First render will happen soon--don't need to do anything. return; } - if (iframe) { - // Iframe has already loaded. + if (isIframeReady) { + // Iframe is ready. // Just update it. updateIframeContent(); return; @@ -108,58 +107,46 @@ function update() { loadingIframe.onload = function() { const iframeDocument = loadingIframe.contentDocument; if (iframeDocument != null && iframeDocument.body != null) { - iframeDocument.body.style.margin = '0'; - // Keep popup within body boundaries for iOS Safari - iframeDocument.body.style['max-width'] = '100vw'; - const iframeRoot = iframeDocument.createElement('div'); - applyStyles(iframeRoot, overlayStyle); - iframeDocument.body.appendChild(iframeRoot); - - // Ready! Now we can update the UI. iframe = loadingIframe; - isLoadingIframe = false; - updateIframeContent(); + const script = loadingIframe.contentWindow.document.createElement( + 'script' + ); + script.type = 'text/javascript'; + script.innerHTML = iframeScript; + iframeDocument.body.appendChild(script); } }; const appDocument = window.document; appDocument.body.appendChild(loadingIframe); } -function render() { - if (currentBuildError) { - return ; - } - if (currentRuntimeErrorRecords.length > 0) { - if (!currentRuntimeErrorOptions) { - throw new Error('Expected options to be injected.'); - } - return ( - - ); +function updateIframeContent() { + if (!currentRuntimeErrorOptions) { + throw new Error('Expected options to be injected.'); } - return null; -} -function updateIframeContent() { - if (iframe === null) { + if (!iframe) { throw new Error('Iframe has not been created yet.'); } - const iframeBody = iframe.contentDocument.body; - if (!iframeBody) { - throw new Error('Expected iframe to have a body.'); - } - const iframeRoot = iframeBody.firstChild; - if (renderedElement === null) { - // Destroy iframe and force it to be recreated on next error + + const isRendered = iframe.contentWindow.updateContent({ + currentBuildError, + currentRuntimeErrorRecords, + dismissRuntimeErrors, + launchEditorEndpoint: currentRuntimeErrorOptions.launchEditorEndpoint, + }); + + if (!isRendered) { window.document.body.removeChild(iframe); - ReactDOM.unmountComponentAtNode(iframeRoot); iframe = null; - return; + isIframeReady = false; } - // Update the overlay - ReactDOM.render(renderedElement, iframeRoot); } + +window.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__ = + window.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__ || {}; +window.__REACT_ERROR_OVERLAY_GLOBAL_HOOK__.iframeReady = function iframeReady() { + isIframeReady = true; + isLoadingIframe = false; + updateIframeContent(); +}; diff --git a/packages/react-error-overlay/webpack.config.js b/packages/react-error-overlay/webpack.config.js new file mode 100644 index 00000000000..2ed9c386b58 --- /dev/null +++ b/packages/react-error-overlay/webpack.config.js @@ -0,0 +1,27 @@ +var path = require('path'); +var webpack = require('webpack'); + +module.exports = { + devtool: 'cheap-module-source-map', + entry: './src/iframeScript.js', + output: { + path: path.join(__dirname, './lib'), + filename: 'bundle.js', + }, + module: { + rules: [ + { + test: /\.js$/, + include: path.resolve(__dirname, './src'), + use: [ + { + loader: 'babel-loader', + options: { + cacheDirectory: true, + }, + }, + ], + }, + ], + }, +}; From 0a2acf58dca00fad72d9247e12cc8d2595b8f2fa Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Sat, 23 Sep 2017 23:38:43 +0530 Subject: [PATCH 02/11] Configure webpack to build the entire package --- packages/react-error-overlay/build.js | 50 +++++++++++++++++++ packages/react-error-overlay/package.json | 8 +-- packages/react-error-overlay/src/index.js | 2 +- .../webpack.config.iframe.js | 27 ++++++++++ .../react-error-overlay/webpack.config.js | 11 +++- 5 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 packages/react-error-overlay/build.js create mode 100644 packages/react-error-overlay/webpack.config.iframe.js diff --git a/packages/react-error-overlay/build.js b/packages/react-error-overlay/build.js new file mode 100644 index 00000000000..90db0ef3692 --- /dev/null +++ b/packages/react-error-overlay/build.js @@ -0,0 +1,50 @@ +const webpack = require('webpack'); +const chalk = require('chalk'); +const webpackConfig = require('./webpack.config.js'); +const iframeWebpackConfig = require('./webpack.config.iframe.js'); +const rimraf = require('rimraf'); + +function build(config, name, callback) { + console.log(chalk.cyan('Compiling ' + name)); + webpack(config).run((error, stats) => { + if (error) { + console.log(chalk.red('Failed to compile.')); + console.log(error.message || error); + console.log(); + return; + } + + if (stats.compilation.errors.length) { + console.log(chalk.red('Failed to compile.')); + console.log(stats.toString({ all: false, errors: true })); + return; + } + + if (stats.compilation.warnings.length) { + console.log(chalk.yellow('Compiled with warnings.')); + console.log(stats.toString({ all: false, warnings: true })); + } + + console.log( + stats.toString({ colors: true, modules: false, version: false }) + ); + console.log(); + + callback(stats); + }); +} + +function runBuildSteps() { + build(iframeWebpackConfig, 'iframeScript.js', () => { + build(webpackConfig, 'index.js', () => { + console.log(chalk.bold.green('Compiled successfully!')); + }); + }); +} + +// Clean up lib folder +rimraf('lib/', () => { + console.log('Cleaned up the lib folder.'); + console.log(); + runBuildSteps(); +}); diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index 90bd685f6e0..64226e06a73 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -5,10 +5,10 @@ "main": "lib/index.js", "scripts": { "prepublishOnly": "npm run build:prod && npm test", - "start": "rimraf lib/ && cross-env NODE_ENV=development webpack --config webpack.config.js -w & NODE_ENV=development babel src/ -d lib/ -w", + "start": "cross-env NODE_ENV=development node build.js", "test": "flow && cross-env NODE_ENV=test jest", - "build": "rimraf lib/ && cross-env NODE_ENV=development babel src/ -d lib/ && cross-env NODE_ENV=production webpack --config webpack.config.js", - "build:prod": "rimraf lib/ && cross-env NODE_ENV=production babel src/ -d lib/ && cross-env NODE_ENV=production webpack --config webpack.config.js" + "build": "cross-env NODE_ENV=development node build.js", + "build:prod": "cross-env NODE_ENV=production node build.js" }, "repository": "facebookincubator/create-react-app", "license": "MIT", @@ -43,9 +43,9 @@ "webpack": "^3.6.0" }, "devDependencies": { - "babel-cli": "6.24.1", "babel-eslint": "7.2.3", "babel-preset-react-app": "^3.0.3", + "chalk": "^2.1.0", "cross-env": "5.0.5", "eslint": "4.4.1", "eslint-config-react-app": "^2.0.1", diff --git a/packages/react-error-overlay/src/index.js b/packages/react-error-overlay/src/index.js index ae834f7a087..542c111b5b1 100644 --- a/packages/react-error-overlay/src/index.js +++ b/packages/react-error-overlay/src/index.js @@ -12,7 +12,7 @@ import { applyStyles } from './utils/dom/css'; /* eslint-disable import/no-webpack-loader-syntax */ //$FlowFixMe -import iframeScript from 'raw-loader!./bundle.js'; +import iframeScript from 'raw-loader!iframeScript'; /* eslint-enable import/no-webpack-loader-syntax */ import type { ErrorRecord } from './listenToRuntimeErrors'; diff --git a/packages/react-error-overlay/webpack.config.iframe.js b/packages/react-error-overlay/webpack.config.iframe.js new file mode 100644 index 00000000000..8c69ba186be --- /dev/null +++ b/packages/react-error-overlay/webpack.config.iframe.js @@ -0,0 +1,27 @@ +var path = require('path'); +var webpack = require('webpack'); + +module.exports = { + devtool: 'cheap-module-source-map', + entry: './src/iframeScript.js', + output: { + path: path.join(__dirname, './lib'), + filename: 'iframe-bundle.js', + }, + module: { + rules: [ + { + test: /\.js$/, + include: path.resolve(__dirname, './src'), + use: [ + { + loader: 'babel-loader', + options: { + cacheDirectory: true, + }, + }, + ], + }, + ], + }, +}; diff --git a/packages/react-error-overlay/webpack.config.js b/packages/react-error-overlay/webpack.config.js index 2ed9c386b58..61a528ff5cc 100644 --- a/packages/react-error-overlay/webpack.config.js +++ b/packages/react-error-overlay/webpack.config.js @@ -3,10 +3,12 @@ var webpack = require('webpack'); module.exports = { devtool: 'cheap-module-source-map', - entry: './src/iframeScript.js', + entry: './src/index.js', output: { path: path.join(__dirname, './lib'), - filename: 'bundle.js', + filename: 'index.js', + library: 'ReactErrorOverlay', + libraryTarget: 'umd', }, module: { rules: [ @@ -24,4 +26,9 @@ module.exports = { }, ], }, + resolve: { + alias: { + iframeScript$: path.resolve(__dirname, './lib/iframe-bundle.js'), + }, + }, }; From 0b48c898f52250d0027cde7db779f7e6b71f0e44 Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Sun, 24 Sep 2017 00:03:40 +0530 Subject: [PATCH 03/11] Remove inline raw-loder config --- packages/react-error-overlay/src/index.js | 7 +++---- packages/react-error-overlay/webpack.config.js | 4 ++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/react-error-overlay/src/index.js b/packages/react-error-overlay/src/index.js index 542c111b5b1..d0981c01408 100644 --- a/packages/react-error-overlay/src/index.js +++ b/packages/react-error-overlay/src/index.js @@ -10,10 +10,9 @@ import { listenToRuntimeErrors } from './listenToRuntimeErrors'; import { iframeStyle } from './styles'; import { applyStyles } from './utils/dom/css'; -/* eslint-disable import/no-webpack-loader-syntax */ -//$FlowFixMe -import iframeScript from 'raw-loader!iframeScript'; -/* eslint-enable import/no-webpack-loader-syntax */ +// Importing iframe-bundle generated in the pre build step as +// a text using webpack raw-loader. See webpack.config.js file. +import iframeScript from 'iframeScript'; import type { ErrorRecord } from './listenToRuntimeErrors'; diff --git a/packages/react-error-overlay/webpack.config.js b/packages/react-error-overlay/webpack.config.js index 61a528ff5cc..4ab90de19ea 100644 --- a/packages/react-error-overlay/webpack.config.js +++ b/packages/react-error-overlay/webpack.config.js @@ -12,6 +12,10 @@ module.exports = { }, module: { rules: [ + { + test: /iframe-bundle\.js$/, + use: 'raw-loader', + }, { test: /\.js$/, include: path.resolve(__dirname, './src'), From f569f45f30ad7b19b8fba530fc250d50021d7cfb Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Sun, 24 Sep 2017 01:53:59 +0530 Subject: [PATCH 04/11] Configure watch mode for error-overlay webpack build --- packages/react-error-overlay/build.js | 31 ++++++++++++++++++++++- packages/react-error-overlay/package.json | 3 ++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/react-error-overlay/build.js b/packages/react-error-overlay/build.js index 90db0ef3692..9728ec395c0 100644 --- a/packages/react-error-overlay/build.js +++ b/packages/react-error-overlay/build.js @@ -3,6 +3,10 @@ const chalk = require('chalk'); const webpackConfig = require('./webpack.config.js'); const iframeWebpackConfig = require('./webpack.config.iframe.js'); const rimraf = require('rimraf'); +const chokidar = require('chokidar'); + +const args = process.argv.slice(2); +const watchMode = args[0] === '--watch' || args[0] === '-w'; function build(config, name, callback) { console.log(chalk.cyan('Compiling ' + name)); @@ -38,13 +42,38 @@ function runBuildSteps() { build(iframeWebpackConfig, 'iframeScript.js', () => { build(webpackConfig, 'index.js', () => { console.log(chalk.bold.green('Compiled successfully!')); + console.log(); + console.log(); }); }); } +function setupWatch() { + const watcher = chokidar.watch('./src', { + ignoreInitial: true, + }); + + watcher.on('change', runBuildSteps); + watcher.on('add', runBuildSteps); + + watcher.on('ready', () => { + runBuildSteps(); + }); + + process.on('SIGINT', function() { + watcher.close(); + process.exit(0); + }); + + watcher.on('error', error => { + console.error('Watcher failure', error); + process.exit(1); + }); +} + // Clean up lib folder rimraf('lib/', () => { console.log('Cleaned up the lib folder.'); console.log(); - runBuildSteps(); + watchMode ? setupWatch() : runBuildSteps(); }); diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index 64226e06a73..86b7945a788 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "scripts": { "prepublishOnly": "npm run build:prod && npm test", - "start": "cross-env NODE_ENV=development node build.js", + "start": "cross-env NODE_ENV=development node build.js --watch", "test": "flow && cross-env NODE_ENV=test jest", "build": "cross-env NODE_ENV=development node build.js", "build:prod": "cross-env NODE_ENV=production node build.js" @@ -46,6 +46,7 @@ "babel-eslint": "7.2.3", "babel-preset-react-app": "^3.0.3", "chalk": "^2.1.0", + "chokidar": "^1.7.0", "cross-env": "5.0.5", "eslint": "4.4.1", "eslint-config-react-app": "^2.0.1", From a52592f4263a2eafaa614582b24fab591c757cdf Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Sun, 24 Sep 2017 02:21:33 +0530 Subject: [PATCH 05/11] Add pollyfills to the error-overlay iframe script --- packages/react-error-overlay/package.json | 2 ++ .../react-error-overlay/src/iframeScript.js | 1 + .../src/utils/pollyfills.js | 21 +++++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 packages/react-error-overlay/src/utils/pollyfills.js diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index 86b7945a788..7d6178aaa0a 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -36,6 +36,8 @@ "babel-loader": "^7.1.2", "babel-runtime": "6.26.0", "html-entities": "1.2.1", + "object-assign": "^4.1.1", + "promise": "^8.0.1", "react": "^15 || ^16", "react-dom": "^15 || ^16", "settle-promise": "1.0.0", diff --git a/packages/react-error-overlay/src/iframeScript.js b/packages/react-error-overlay/src/iframeScript.js index adcdc7fa1db..2eae9108f82 100644 --- a/packages/react-error-overlay/src/iframeScript.js +++ b/packages/react-error-overlay/src/iframeScript.js @@ -6,6 +6,7 @@ * 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. */ +import './utils/pollyfills.js'; import React from 'react'; import ReactDOM from 'react-dom'; import CompileErrorContainer from './containers/CompileErrorContainer'; diff --git a/packages/react-error-overlay/src/utils/pollyfills.js b/packages/react-error-overlay/src/utils/pollyfills.js new file mode 100644 index 00000000000..3d02eab33f8 --- /dev/null +++ b/packages/react-error-overlay/src/utils/pollyfills.js @@ -0,0 +1,21 @@ +/** + * 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'; + +if (typeof Promise === 'undefined') { + // Rejection tracking prevents a common issue where React gets into an + // inconsistent state due to an error, but it gets swallowed by a Promise, + // and the user has no idea what causes React's erratic future behavior. + require('promise/lib/rejection-tracking').enable(); + window.Promise = require('promise/lib/es6-extensions.js'); +} + +// Object.assign() is commonly used with React. +// It will use the native implementation if it's present and isn't buggy. +Object.assign = require('object-assign'); From 483e631494c7093bb1dfccfeda3fff31f5a6c2e2 Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Sun, 24 Sep 2017 02:26:30 +0530 Subject: [PATCH 06/11] Add header comment --- packages/react-error-overlay/build.js | 10 ++++++++++ packages/react-error-overlay/src/iframeScript.js | 1 + .../react-error-overlay/webpack.config.iframe.js | 13 +++++++++++-- packages/react-error-overlay/webpack.config.js | 13 +++++++++++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/packages/react-error-overlay/build.js b/packages/react-error-overlay/build.js index 9728ec395c0..7495de67187 100644 --- a/packages/react-error-overlay/build.js +++ b/packages/react-error-overlay/build.js @@ -1,3 +1,13 @@ +/** + * 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'; + const webpack = require('webpack'); const chalk = require('chalk'); const webpackConfig = require('./webpack.config.js'); diff --git a/packages/react-error-overlay/src/iframeScript.js b/packages/react-error-overlay/src/iframeScript.js index 2eae9108f82..912ef86a07a 100644 --- a/packages/react-error-overlay/src/iframeScript.js +++ b/packages/react-error-overlay/src/iframeScript.js @@ -6,6 +6,7 @@ * 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. */ + import './utils/pollyfills.js'; import React from 'react'; import ReactDOM from 'react-dom'; diff --git a/packages/react-error-overlay/webpack.config.iframe.js b/packages/react-error-overlay/webpack.config.iframe.js index 8c69ba186be..1df5a363f88 100644 --- a/packages/react-error-overlay/webpack.config.iframe.js +++ b/packages/react-error-overlay/webpack.config.iframe.js @@ -1,5 +1,14 @@ -var path = require('path'); -var webpack = require('webpack'); +/** + * 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'; + +const path = require('path'); module.exports = { devtool: 'cheap-module-source-map', diff --git a/packages/react-error-overlay/webpack.config.js b/packages/react-error-overlay/webpack.config.js index 4ab90de19ea..bfbd845fb06 100644 --- a/packages/react-error-overlay/webpack.config.js +++ b/packages/react-error-overlay/webpack.config.js @@ -1,5 +1,14 @@ -var path = require('path'); -var webpack = require('webpack'); +/** + * 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'; + +const path = require('path'); module.exports = { devtool: 'cheap-module-source-map', From fd248f7e4c795c0209741186d187d3b48366f7cd Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Sun, 24 Sep 2017 11:03:30 +0530 Subject: [PATCH 07/11] Configure to fail CI on error or warning --- packages/react-error-overlay/build.js | 26 ++++++++++++------- packages/react-error-overlay/package.json | 2 +- .../src/utils/pollyfills.js | 2 -- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/react-error-overlay/build.js b/packages/react-error-overlay/build.js index 7495de67187..fdb64a73210 100644 --- a/packages/react-error-overlay/build.js +++ b/packages/react-error-overlay/build.js @@ -6,8 +6,6 @@ * 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'; - const webpack = require('webpack'); const chalk = require('chalk'); const webpackConfig = require('./webpack.config.js'); @@ -18,6 +16,11 @@ const chokidar = require('chokidar'); const args = process.argv.slice(2); const watchMode = args[0] === '--watch' || args[0] === '-w'; +const isCI = + process.env.CI && + (typeof process.env.CI !== 'string' || + process.env.CI.toLowerCase() !== 'false'); + function build(config, name, callback) { console.log(chalk.cyan('Compiling ' + name)); webpack(config).run((error, stats) => { @@ -25,13 +28,11 @@ function build(config, name, callback) { console.log(chalk.red('Failed to compile.')); console.log(error.message || error); console.log(); - return; } if (stats.compilation.errors.length) { console.log(chalk.red('Failed to compile.')); console.log(stats.toString({ all: false, errors: true })); - return; } if (stats.compilation.warnings.length) { @@ -39,6 +40,16 @@ function build(config, name, callback) { console.log(stats.toString({ all: false, warnings: true })); } + // Fail the build if running in a CI server + if ( + error || + stats.compilation.errors.length || + stats.compilation.warnings.length + ) { + isCI && process.exit(1); + return; + } + console.log( stats.toString({ colors: true, modules: false, version: false }) ); @@ -51,9 +62,7 @@ function build(config, name, callback) { function runBuildSteps() { build(iframeWebpackConfig, 'iframeScript.js', () => { build(webpackConfig, 'index.js', () => { - console.log(chalk.bold.green('Compiled successfully!')); - console.log(); - console.log(); + console.log(chalk.bold.green('Compiled successfully!\n\n')); }); }); } @@ -83,7 +92,6 @@ function setupWatch() { // Clean up lib folder rimraf('lib/', () => { - console.log('Cleaned up the lib folder.'); - console.log(); + console.log('Cleaned up the lib folder.\n'); watchMode ? setupWatch() : runBuildSteps(); }); diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index 7d6178aaa0a..cda4e68d2cc 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -33,7 +33,6 @@ "dependencies": { "anser": "1.4.1", "babel-code-frame": "6.22.0", - "babel-loader": "^7.1.2", "babel-runtime": "6.26.0", "html-entities": "1.2.1", "object-assign": "^4.1.1", @@ -47,6 +46,7 @@ "devDependencies": { "babel-eslint": "7.2.3", "babel-preset-react-app": "^3.0.3", + "babel-loader": "^7.1.2", "chalk": "^2.1.0", "chokidar": "^1.7.0", "cross-env": "5.0.5", diff --git a/packages/react-error-overlay/src/utils/pollyfills.js b/packages/react-error-overlay/src/utils/pollyfills.js index 3d02eab33f8..cd59a252dcc 100644 --- a/packages/react-error-overlay/src/utils/pollyfills.js +++ b/packages/react-error-overlay/src/utils/pollyfills.js @@ -6,8 +6,6 @@ * 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'; - if (typeof Promise === 'undefined') { // Rejection tracking prevents a common issue where React gets into an // inconsistent state due to an error, but it gets swallowed by a Promise, From 7796f54d8a12ee4231b4f339a17c65212b68e927 Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Sun, 24 Sep 2017 11:55:44 +0530 Subject: [PATCH 08/11] Suppress flowtype error on importing iframe-bundle --- packages/react-error-overlay/src/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-error-overlay/src/index.js b/packages/react-error-overlay/src/index.js index d0981c01408..52ff9199bcb 100644 --- a/packages/react-error-overlay/src/index.js +++ b/packages/react-error-overlay/src/index.js @@ -12,6 +12,7 @@ import { applyStyles } from './utils/dom/css'; // Importing iframe-bundle generated in the pre build step as // a text using webpack raw-loader. See webpack.config.js file. +// $FlowFixMe import iframeScript from 'iframeScript'; import type { ErrorRecord } from './listenToRuntimeErrors'; From 272c491be84117dd118dedc959bf6ea4422c3825 Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Mon, 25 Sep 2017 05:30:21 +0530 Subject: [PATCH 09/11] Change webpack to a dev dependency and pin some versions --- packages/react-error-overlay/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index cda4e68d2cc..82ae43ec628 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -35,13 +35,12 @@ "babel-code-frame": "6.22.0", "babel-runtime": "6.26.0", "html-entities": "1.2.1", - "object-assign": "^4.1.1", - "promise": "^8.0.1", + "object-assign": "4.1.1", + "promise": "8.0.1", "react": "^15 || ^16", "react-dom": "^15 || ^16", "settle-promise": "1.0.0", - "source-map": "0.5.6", - "webpack": "^3.6.0" + "source-map": "0.5.6" }, "devDependencies": { "babel-eslint": "7.2.3", @@ -60,7 +59,8 @@ "jest": "20.0.4", "jest-fetch-mock": "1.2.1", "raw-loader": "^0.5.1", - "rimraf": "^2.6.1" + "rimraf": "^2.6.1", + "webpack": "^3.6.0" }, "jest": { "setupFiles": [ From 4dff32a482c10939b4a69a13bc1b2a61210e76ad Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Tue, 3 Oct 2017 06:08:38 +0530 Subject: [PATCH 10/11] Disable webpack cache --- packages/react-error-overlay/webpack.config.iframe.js | 9 +-------- packages/react-error-overlay/webpack.config.js | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/packages/react-error-overlay/webpack.config.iframe.js b/packages/react-error-overlay/webpack.config.iframe.js index 1df5a363f88..fc656a6447e 100644 --- a/packages/react-error-overlay/webpack.config.iframe.js +++ b/packages/react-error-overlay/webpack.config.iframe.js @@ -22,14 +22,7 @@ module.exports = { { test: /\.js$/, include: path.resolve(__dirname, './src'), - use: [ - { - loader: 'babel-loader', - options: { - cacheDirectory: true, - }, - }, - ], + use: 'babel-loader', }, ], }, diff --git a/packages/react-error-overlay/webpack.config.js b/packages/react-error-overlay/webpack.config.js index bfbd845fb06..ad11e8aa1ab 100644 --- a/packages/react-error-overlay/webpack.config.js +++ b/packages/react-error-overlay/webpack.config.js @@ -28,14 +28,7 @@ module.exports = { { test: /\.js$/, include: path.resolve(__dirname, './src'), - use: [ - { - loader: 'babel-loader', - options: { - cacheDirectory: true, - }, - }, - ], + use: 'babel-loader', }, ], }, From 57274a4954de2df7631d8220203802982f45ba49 Mon Sep 17 00:00:00 2001 From: Tharaka Wijebandara Date: Tue, 3 Oct 2017 06:27:17 +0530 Subject: [PATCH 11/11] Update license headers to MIT --- packages/react-error-overlay/build.js | 6 ++---- packages/react-error-overlay/src/iframeScript.js | 6 ++---- packages/react-error-overlay/src/utils/pollyfills.js | 7 +++---- packages/react-error-overlay/webpack.config.iframe.js | 6 ++---- packages/react-error-overlay/webpack.config.js | 6 ++---- 5 files changed, 11 insertions(+), 20 deletions(-) diff --git a/packages/react-error-overlay/build.js b/packages/react-error-overlay/build.js index fdb64a73210..592da141ffe 100644 --- a/packages/react-error-overlay/build.js +++ b/packages/react-error-overlay/build.js @@ -1,10 +1,8 @@ /** * 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. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ const webpack = require('webpack'); const chalk = require('chalk'); diff --git a/packages/react-error-overlay/src/iframeScript.js b/packages/react-error-overlay/src/iframeScript.js index 912ef86a07a..c95ea36b1a4 100644 --- a/packages/react-error-overlay/src/iframeScript.js +++ b/packages/react-error-overlay/src/iframeScript.js @@ -1,10 +1,8 @@ /** * 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. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ import './utils/pollyfills.js'; diff --git a/packages/react-error-overlay/src/utils/pollyfills.js b/packages/react-error-overlay/src/utils/pollyfills.js index cd59a252dcc..ddd5aeb9651 100644 --- a/packages/react-error-overlay/src/utils/pollyfills.js +++ b/packages/react-error-overlay/src/utils/pollyfills.js @@ -1,11 +1,10 @@ /** * 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. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ + if (typeof Promise === 'undefined') { // Rejection tracking prevents a common issue where React gets into an // inconsistent state due to an error, but it gets swallowed by a Promise, diff --git a/packages/react-error-overlay/webpack.config.iframe.js b/packages/react-error-overlay/webpack.config.iframe.js index fc656a6447e..9fa742b720b 100644 --- a/packages/react-error-overlay/webpack.config.iframe.js +++ b/packages/react-error-overlay/webpack.config.iframe.js @@ -1,10 +1,8 @@ /** * 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. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ 'use strict'; diff --git a/packages/react-error-overlay/webpack.config.js b/packages/react-error-overlay/webpack.config.js index ad11e8aa1ab..5d640e05ca3 100644 --- a/packages/react-error-overlay/webpack.config.js +++ b/packages/react-error-overlay/webpack.config.js @@ -1,10 +1,8 @@ /** * 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. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ 'use strict';