From 5b0b58fabfc4c1224e112809dfe0d974d2e01297 Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Fri, 18 Aug 2017 11:07:51 -0500 Subject: [PATCH] Lazy load Babel on REPL --- js/repl/LoadingMessage.js | 0 js/repl/PresetLoadingAnimation.js | 4 +- js/repl/Repl.js | 75 +++++++- js/repl/ReplOptions.js | 298 +++++++++++++++++------------- js/repl/UriUtils.js | 5 +- js/repl/loadBabel.js | 50 +++++ js/repl/loadBuildArtifacts.js | 39 ++++ js/repl/replUtils.js | 17 +- js/repl/types.js | 20 +- repl2.html | 1 - 10 files changed, 357 insertions(+), 152 deletions(-) create mode 100644 js/repl/LoadingMessage.js create mode 100644 js/repl/loadBabel.js create mode 100644 js/repl/loadBuildArtifacts.js diff --git a/js/repl/LoadingMessage.js b/js/repl/LoadingMessage.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/repl/PresetLoadingAnimation.js b/js/repl/PresetLoadingAnimation.js index 96bbcd11a6..23cb7d3feb 100644 --- a/js/repl/PresetLoadingAnimation.js +++ b/js/repl/PresetLoadingAnimation.js @@ -1,8 +1,8 @@ import { css } from 'glamor'; import React from 'react'; -const PresetLoadingAnimation = () => -
+const PresetLoadingAnimation = ({ className }) => +
diff --git a/js/repl/Repl.js b/js/repl/Repl.js index 9a285ef673..22d1aa267e 100644 --- a/js/repl/Repl.js +++ b/js/repl/Repl.js @@ -7,7 +7,9 @@ import ReplOptions from './ReplOptions'; import StorageService from './StorageService'; import UriUtils from './UriUtils'; import compile from './compile'; +import loadBabel from './loadBabel'; import loadPlugin from './loadPlugin'; +import PresetLoadingAnimation from './PresetLoadingAnimation'; import scopedEval from './scopedEval'; import { envPresetConfig, @@ -21,12 +23,14 @@ import { loadPersistedState, configArrayToStateMap, configToState, + persistedStateToBabelState, persistedStateToEnvConfig } from './replUtils'; -import { media } from './styles'; +import { colors, media } from './styles'; import type { BabelPresets, + BabelState, EnvConfig, PluginState, PluginStateMap, @@ -35,6 +39,7 @@ import type { type Props = {}; type State = { + babel: BabelState, builtIns: boolean, code: string, compiled: ?string, @@ -82,7 +87,8 @@ export default class Repl extends React.Component { // A partial State is defined first b'c this._compile needs it. // The compile helper will then populate the missing State values. - const state = { + this.state = { + babel: persistedStateToBabelState(persistedState), builtIns: persistedState.builtIns, code: persistedState.code, compiled: null, @@ -105,18 +111,27 @@ export default class Repl extends React.Component { ) }; - this.state = { - ...state, - ...this._compile(persistedState.code, state) - }; - - // Load any plug-ins enabled by query params - this._checkForUnloadedPlugins(); + this._setupBabel(); } render() { const state = this.state; + if (!state.babel.isLoaded) { + const message = state.babel.isLoading + ? 'Loading Babel...' + : 'An error occurred while loading Babel :('; + + return ( +
+
+ {message} + {state.babel.isLoading && } +
+
+ ); + } + const options = { lineWrapping: state.lineWrap }; @@ -161,6 +176,27 @@ export default class Repl extends React.Component { ); } + _setupBabel() { + loadBabel(this.state.babel, success => { + this.setState(state => { + const babelState = state.babel; + + if (success) { + babelState.isLoaded = true; + babelState.isLoading = false; + } else { + babelState.didError = true; + babelState.isLoading = false; + } + + return { + babel: babelState, + ...this._compile(state.code, state), + }; + }, () => this._checkForUnloadedPlugins()); + }); + } + _checkForUnloadedPlugins() { const { envConfig, @@ -353,7 +389,9 @@ export default class Repl extends React.Component { const state = { babili: plugins['babili-standalone'].isEnabled, browsers: envConfig.browsers, + build: this.state.babel.build, builtIns: this.state.builtIns, + circleciRepo: this.state.babel.circleciRepo, code: this.state.code, debug: this.state.debugEnvPreset, evaluate: this.state.runtimePolyfillState.isEnabled, @@ -361,7 +399,8 @@ export default class Repl extends React.Component { presets: presetsArray.join(','), prettier: plugins.prettier.isEnabled, showSidebar: this.state.isSidebarExpanded, - targets: envConfigToTargetsString(envConfig) + targets: envConfigToTargetsString(envConfig), + version: this.state.babel.version, }; StorageService.set('replState', state); @@ -387,6 +426,22 @@ export default class Repl extends React.Component { } const styles = { + loader: css({ + alignItems: 'center', + background: colors.inverseBackgroundDark, + color: colors.inverseForegroundLight, + display: 'flex', + height: '100vh', + justifyContent: 'center', + }), + loadingAnimation: css({ + justifyContent: 'center', + margin: '2rem 0 0 0', + }), + loaderContent: css({ + margin: 'auto', + textAlign: 'center', + }), codeMirrorPanel: css({ flex: '0 0 50%' }), diff --git a/js/repl/ReplOptions.js b/js/repl/ReplOptions.js index 7e23fc606d..95e9a19685 100644 --- a/js/repl/ReplOptions.js +++ b/js/repl/ReplOptions.js @@ -12,6 +12,7 @@ import Svg from './Svg'; import { colors, media } from './styles'; import type { + BabelState, EnvConfig, PluginConfig, PluginState, @@ -23,6 +24,7 @@ type ToggleExpanded = (isExpanded: boolean) => void; type ToggleSetting = (name: string, isEnabled: boolean) => void; type Props = { + babel: BabelState, builtIns: boolean, className: string, debugEnvPreset: boolean, @@ -78,144 +80,146 @@ class ExpandedContainer extends Component { return (
-
-
Settings
- - - {pluginConfigs.map(config => - - )} -
-
-
Presets
- {presetPluginConfigs.map(config => +
+
+
Settings
- )} -
-
- -
+ + {pluginConfigs.map(config => + + )} +
+
+
Presets
+ {presetPluginConfigs.map(config => + + )} +
+
+
+ +