Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy load babel on REPL #1318

Merged
merged 4 commits into from
Aug 22, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added js/repl/LoadingMessage.js
Empty file.
10 changes: 8 additions & 2 deletions js/repl/PresetLoadingAnimation.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { css } from "glamor";
import React from "react";

const PresetLoadingAnimation = () =>
<div className={styles.loadingAnimation}>
type PresetLoadingAnimationProps = {
className: ?string,
};

const PresetLoadingAnimation = ({
className = "",
}: PresetLoadingAnimationProps) =>
<div className={`${className || ""} ${styles.loadingAnimation}`}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: className || "" is redundant with the initializer above

<div className={`${styles.loadingTick} ${styles.loadingTick1}`} />
<div className={`${styles.loadingTick} ${styles.loadingTick2}`} />
<div className={`${styles.loadingTick} ${styles.loadingTick3}`} />
Expand Down
72 changes: 62 additions & 10 deletions js/repl/Repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,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 scopedEval from "./scopedEval";
import PresetLoadingAnimation from "./PresetLoadingAnimation";
import {
envPresetConfig,
pluginConfigs,
Expand All @@ -22,12 +23,15 @@ import {
loadPersistedState,
configArrayToStateMap,
configToState,
persistedStateToBabelState,
persistedStateToEnvConfig,
} from "./replUtils";
import { media } from "./styles";
import scopedEval from "./scopedEval";
import { colors, media } from "./styles";

import type {
BabelPresets,
BabelState,
EnvConfig,
PluginState,
PluginStateMap,
Expand All @@ -36,6 +40,7 @@ import type {

type Props = {};
type State = {
babel: BabelState,
builtIns: boolean,
code: string,
compiled: ?string,
Expand Down Expand Up @@ -86,7 +91,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,
Expand All @@ -110,18 +116,32 @@ export default class Repl extends React.Component {
sourceMap: null,
};

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) {
let message = "Loading Babel...";

if (!state.babel.isLoading && state.babel.didError) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: state.babel.didError should be sufficient?

message =
state.babel.errorMessage ||
"An error occurred while loading Babel :(";
}

return (
<div className={styles.loader}>
<div className={styles.loaderContent}>
{message}
{state.babel.isLoading &&
<PresetLoadingAnimation className={styles.loadingAnimation} />}
</div>
</div>
);
}

const options = {
lineWrapping: state.lineWrap,
};
Expand Down Expand Up @@ -167,6 +187,19 @@ export default class Repl extends React.Component {
);
}

_setupBabel() {
loadBabel(this.state.babel, babelState => {
this.setState(state => ({
...babelState,
...(babelState.isLoaded ? this._compile(state.code, state) : null),
}));

if (babelState.isLoaded) {
this._checkForUnloadedPlugins();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be done in the setState callback?

}
});
}

_checkForUnloadedPlugins() {
const {
envConfig,
Expand Down Expand Up @@ -370,7 +403,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,
Expand All @@ -379,6 +414,7 @@ export default class Repl extends React.Component {
prettier: plugins.prettier.isEnabled,
showSidebar: this.state.isSidebarExpanded,
targets: envConfigToTargetsString(envConfig),
version: this.state.babel.version,
};

StorageService.set("replState", state);
Expand Down Expand Up @@ -408,6 +444,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%",
}),
Expand Down
Loading