-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make error overlay to run in the context of the iframe (#3142)
* Make error overlay to run in the context of the iframe * Configure webpack to build the entire package * Remove inline raw-loader config * Configure watch mode for error-overlay webpack build * Add polyfills to the error-overlay iframe script * Add header comment * Configure to fail CI on error or warning * Suppress flow-type error on importing iframe-bundle * Change webpack to a dev dependency and pin some versions * Disable webpack cache * Update license headers to MIT
- Loading branch information
Showing
7 changed files
with
284 additions
and
56 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 |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* | ||
* 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'); | ||
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'; | ||
|
||
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) => { | ||
if (error) { | ||
console.log(chalk.red('Failed to compile.')); | ||
console.log(error.message || error); | ||
console.log(); | ||
} | ||
|
||
if (stats.compilation.errors.length) { | ||
console.log(chalk.red('Failed to compile.')); | ||
console.log(stats.toString({ all: false, errors: true })); | ||
} | ||
|
||
if (stats.compilation.warnings.length) { | ||
console.log(chalk.yellow('Compiled with warnings.')); | ||
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 }) | ||
); | ||
console.log(); | ||
|
||
callback(stats); | ||
}); | ||
} | ||
|
||
function runBuildSteps() { | ||
build(iframeWebpackConfig, 'iframeScript.js', () => { | ||
build(webpackConfig, 'index.js', () => { | ||
console.log(chalk.bold.green('Compiled successfully!\n\n')); | ||
}); | ||
}); | ||
} | ||
|
||
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.\n'); | ||
watchMode ? setupWatch() : runBuildSteps(); | ||
}); |
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
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,57 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* | ||
* 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'; | ||
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 <CompileErrorContainer error={currentBuildError} />; | ||
} | ||
if (currentRuntimeErrorRecords.length > 0) { | ||
return ( | ||
<RuntimeErrorContainer | ||
errorRecords={currentRuntimeErrorRecords} | ||
close={dismissRuntimeErrors} | ||
launchEditorEndpoint={launchEditorEndpoint} | ||
/> | ||
); | ||
} | ||
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(); |
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
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,18 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* | ||
* 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, | ||
// 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'); |
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,27 @@ | ||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
|
||
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: 'babel-loader', | ||
}, | ||
], | ||
}, | ||
}; |
Oops, something went wrong.