feat(ui): lazy load monaco in runtime (#15978)

pull/16018/head
Alex Boatwright 2019-11-21 15:28:02 -08:00 committed by GitHub
parent 2c5fbe8ae1
commit 0dbaf4af43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 123 additions and 38 deletions

1
ui/global.d.ts vendored
View File

@ -2,4 +2,3 @@
// got some globals here that only exist during compilation // got some globals here that only exist during compilation
// //
declare var ENABLE_MONACO: string

View File

@ -5,6 +5,7 @@ const OSS_FLAGS = {
alerting: false, alerting: false,
eventMarkers: false, eventMarkers: false,
deleteWithPredicate: false, deleteWithPredicate: false,
monacoEditor: false,
downloadCellCSV: false, downloadCellCSV: false,
} }
@ -12,12 +13,14 @@ const CLOUD_FLAGS = {
alerting: true, alerting: true,
eventMarkers: false, eventMarkers: false,
deleteWithPredicate: false, deleteWithPredicate: false,
monacoEditor: false,
cloudBilling: CLOUD_BILLING_VISIBLE, // should be visible in dev and acceptance, but not in cloud cloudBilling: CLOUD_BILLING_VISIBLE, // should be visible in dev and acceptance, but not in cloud
downloadCellCSV: false, downloadCellCSV: false,
} }
export const isFlagEnabled = (flagName: string) => { export const isFlagEnabled = (flagName: string, equals?: string | boolean) => {
let localStorageFlags let localStorageFlags
let _equals = equals
try { try {
localStorageFlags = JSON.parse(window.localStorage.featureFlags) localStorageFlags = JSON.parse(window.localStorage.featureFlags)
@ -25,25 +28,86 @@ export const isFlagEnabled = (flagName: string) => {
localStorageFlags = {} localStorageFlags = {}
} }
return ( if (_equals === undefined) {
localStorageFlags[flagName] === true || _equals = true
(CLOUD && CLOUD_FLAGS[flagName]) || }
(!CLOUD && OSS_FLAGS[flagName])
) if (localStorageFlags.hasOwnProperty(flagName)) {
return localStorageFlags[flagName] === _equals
}
if (CLOUD) {
if (CLOUD_FLAGS.hasOwnProperty(flagName)) {
return CLOUD_FLAGS[flagName] === _equals
}
return false
}
if (OSS_FLAGS.hasOwnProperty(flagName)) {
return OSS_FLAGS[flagName] === _equals
}
return false
} }
// type influx.toggleFeature('myFlag') to disable / enable any feature flag // type influx.toggleFeature('myFlag') to disable / enable any feature flag
export const FeatureFlag: FunctionComponent<{name: string}> = ({ export const FeatureFlag: FunctionComponent<{
name, name: string
children, equals?: string | boolean
}) => { }> = ({name, equals, children}) => {
if (!isFlagEnabled(name)) { if (!isFlagEnabled(name, equals)) {
return null return null
} }
return children as any return children as any
} }
/* eslint-disable no-console */
const list = () => {
console.log('Currently Available Feature Flags')
if (CLOUD) {
console.table(CLOUD_FLAGS)
} else {
console.table(OSS_FLAGS)
}
}
/* eslint-enable no-console */
const reset = () => {
const featureFlags = JSON.parse(window.localStorage.featureFlags || '{}')
if (CLOUD) {
Object.keys(featureFlags).forEach(k => {
if (!CLOUD_FLAGS.hasOwnProperty(k)) {
delete featureFlags[k]
} else {
featureFlags[k] = CLOUD_FLAGS[k]
}
})
} else {
Object.keys(featureFlags).forEach(k => {
if (!CLOUD_FLAGS.hasOwnProperty(k)) {
delete featureFlags[k]
} else {
featureFlags[k] = CLOUD_FLAGS[k]
}
})
}
window.localStorage.featureFlags = JSON.stringify(featureFlags)
}
export const set = (flagName: string, value: string | boolean) => {
const featureFlags = JSON.parse(window.localStorage.featureFlags || '{}')
featureFlags[flagName] = value
window.localStorage.featureFlags = JSON.stringify(featureFlags)
return featureFlags[flagName]
}
export const toggleLocalStorageFlag = (flagName: string) => { export const toggleLocalStorageFlag = (flagName: string) => {
const featureFlags = JSON.parse(window.localStorage.featureFlags || '{}') const featureFlags = JSON.parse(window.localStorage.featureFlags || '{}')
@ -57,4 +121,4 @@ export const toggleLocalStorageFlag = (flagName: string) => {
// Expose utility in dev tools console for convenience // Expose utility in dev tools console for convenience
const w: any = window const w: any = window
w.influx = {toggleFeature: toggleLocalStorageFlag} w.influx = {toggleFeature: toggleLocalStorageFlag, list, reset}

View File

@ -25,3 +25,20 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.time-machine-editor--loading {
width: 100%;
height: 100%;
position: relative;
background: #292933;
&:after {
content: '';
position: absolute;
background: #202028;
top: 8px;
bottom: 8px;
left: 24px;
right: 8px;
}
}

View File

@ -1,14 +1,18 @@
// Libraries // Libraries
import React, {PureComponent} from 'react' import React, {PureComponent, Suspense} from 'react'
import {connect} from 'react-redux' import {connect} from 'react-redux'
import {Position} from 'codemirror' import {Position} from 'codemirror'
// Components // Components
import FluxEditor from 'src/shared/components/FluxEditor' const FluxEditor = React.lazy(() => import('src/shared/components/FluxEditor'))
const FluxMonacoEditor = React.lazy(() =>
import('src/shared/components/FluxMonacoEditor')
)
import Threesizer from 'src/shared/components/threesizer/Threesizer' import Threesizer from 'src/shared/components/threesizer/Threesizer'
import FluxFunctionsToolbar from 'src/timeMachine/components/fluxFunctionsToolbar/FluxFunctionsToolbar' import FluxFunctionsToolbar from 'src/timeMachine/components/fluxFunctionsToolbar/FluxFunctionsToolbar'
import VariableToolbar from 'src/timeMachine/components/variableToolbar/VariableToolbar' import VariableToolbar from 'src/timeMachine/components/variableToolbar/VariableToolbar'
import ToolbarTab from 'src/timeMachine/components/ToolbarTab' import ToolbarTab from 'src/timeMachine/components/ToolbarTab'
import {FeatureFlag} from 'src/shared/utils/featureFlag'
// Actions // Actions
import {setActiveQueryText} from 'src/timeMachine/actions' import {setActiveQueryText} from 'src/timeMachine/actions'
@ -40,6 +44,8 @@ interface State {
type Props = StateProps & DispatchProps type Props = StateProps & DispatchProps
const spinner = <div className="time-machine-editor--loading" />
class TimeMachineFluxEditor extends PureComponent<Props, State> { class TimeMachineFluxEditor extends PureComponent<Props, State> {
private cursorPosition: Position = {line: 0, ch: 0} private cursorPosition: Position = {line: 0, ch: 0}
@ -55,27 +61,29 @@ class TimeMachineFluxEditor extends PureComponent<Props, State> {
size: 0.75, size: 0.75,
handleDisplay: HANDLE_NONE, handleDisplay: HANDLE_NONE,
render: () => { render: () => {
if (ENABLE_MONACO) {
const FluxMonacoEditor = require('src/shared/components/FluxMonacoEditor')
.default
return (
<FluxMonacoEditor
script={activeQueryText}
onChangeScript={onSetActiveQueryText}
onSubmitScript={onSubmitQueries}
onCursorChange={this.handleCursorPosition}
/>
)
}
return ( return (
<FluxEditor <>
script={activeQueryText} <Suspense fallback={spinner}>
status={{type: '', text: ''}} <FeatureFlag name="monacoEditor">
onChangeScript={onSetActiveQueryText} <FluxMonacoEditor
onSubmitScript={onSubmitQueries} script={activeQueryText}
suggestions={[]} onChangeScript={onSetActiveQueryText}
onCursorChange={this.handleCursorPosition} onSubmitScript={onSubmitQueries}
/> onCursorChange={this.handleCursorPosition}
/>
</FeatureFlag>
<FeatureFlag name="monacoEditor" equals={false}>
<FluxEditor
script={activeQueryText}
status={{type: '', text: ''}}
onChangeScript={onSetActiveQueryText}
onSubmitScript={onSubmitQueries}
suggestions={[]}
onCursorChange={this.handleCursorPosition}
/>
</FeatureFlag>
</Suspense>
</>
) )
}, },
}, },

View File

@ -109,9 +109,6 @@ module.exports = {
}), }),
new ForkTsCheckerWebpackPlugin(), new ForkTsCheckerWebpackPlugin(),
new webpack.ProgressPlugin(), new webpack.ProgressPlugin(),
new webpack.DefinePlugin({
ENABLE_MONACO: JSON.stringify(false)
}),
new webpack.EnvironmentPlugin({...process.env, GIT_SHA, API_PREFIX: API_BASE_PATH, STATIC_PREFIX: BASE_PATH}), new webpack.EnvironmentPlugin({...process.env, GIT_SHA, API_PREFIX: API_BASE_PATH, STATIC_PREFIX: BASE_PATH}),
], ],
stats: { stats: {