flopflip v0.1.0
Status
Installation
yarn add flopflip or npm i flopflip --save
Demo
A minimal demo exists and can adjusted to point to a custom LaunchDarkly account. You would have to create feature toggles according to the existing flags too.
Then simply run:
- From the repositories root:
yarn build:watch - From
/demo: firstyarnand thenyarn start
A browser window should open and the network tab should show feature flags being loaded from LaunchDarkly.
Documentation
Flopflip allows you to manage feature flags through LaunchDarkly within an application written using React and Redux.
API & exports
The modules/index.js exports:
createFlopFlipEnhancera redux store enhancer to configure LaunchDarkly and add feature toggle state to your redux storeConfigureFlopFlipa component to configure LaunchDarkly (alternative to the store enhancer)reducerandSTATE_SLICEa reducer and the state slice for the feature toggle statewithFeatureTogglea Higher-Order Component (HoC) to conditionally render components depending on feature toggle stateinjectFeatureTogglesa HoC to inject requested feature toggles from existing feature toggles onto thepropsof a componentFeatureToggleda component conditionally rendering itschildrenbased on the status of a passed feature flag
createFlopFlipEnhancer
Requires arguments of clientSideId:string, user:object.
- The
clientSideIdis your LaunchDarkly ID. - The
userobject needs at least akeyattribute. An anonymouskeywill be generated usinguuid4when nothing is specified. The user object can contain additional data.
reducer & STATE_SLICE
The flopflop reducer should be wired up with a combineReducers within your application in coordination with the STATE_SLICE which is used internally too to manage the location of the feature toggle states.
In context this configuration could look like:
import { createStore, compose, applyMiddleware } from 'redux';
import {
createFlopFlipEnhancer,
flopflipReducer,
// We refer to this state slice in the `injectFeatureToggles`
// HoC and currently do not support a custom state slice.
FLOPFLIP_STATE_SLICE
} from 'flopflip';
// Maintained somewhere within your application
import user from './user';
import appReducer from './reducer';
const store = createStore(
combineReducers({
appReducer,
[FLOPFLIP_STATE_SLICE]: featureToggleReducer,
}),
initialState,
compose(
applyMiddleware(...),
createFlopFlipEnhancer(
// NOTE:
// This clientId is not secret to you and can be found
// within your settings on LaunchDarkly.
window.application.env.LD_CLIENT_ID,
user
)
)
)Whenever setup is not preferred via the store enhance the same can be achieved using the ConfigureFlopFlip component.
It takes the props:
- The
clientSideIdis your LaunchDarkly ID. - The
userobject needs at least akeyattribute. An anonymouskeywill be generated usinguuid4when nothing is specified. The user object can contain additional data.
import { createStore, compose, applyMiddleware } from 'redux';
import {
ConfigureFlopFlip,
flopflipReducer,
FLOPFLIP_STATE_SLICE
} from 'flopflip';
// Maintained somewhere within your application
import user from './user';
import appReducer from './reducer';
const store = createStore(
combineReducers({
appReducer,
[FLOPFLIP_STATE_SLICE]: featureToggleReducer,
}),
initialState,
compose(
applyMiddleware(...),
)
)
// Somewhere where your <App /> is rendered
<ConfigureFlopFlip user={user} clientSideId={clientSideId}>
<App />
</ConfigureFlopFlip>FeatureToggled
The component renders its children depending on the state of a given feature flag. It also allows passing an optional untoggledComponent which will be rendered whenever the feature is disabled instead of null.
import React, { Component } from 'react';
import { FeatureToggled } from 'flopflip';
import flagsNames from './feature-flags';
export default (
<FeatureToggled
flag={flagsNames.THE_FEATURE_TOGGLE}
untoggledComponent={<h3>At least there is a fallback!</h3>}
>
<h3>I might be gone or there!</h3>
</FeatureToggled>
);withFeatureToggle
A HoC to conditionally render a component based on a feature toggle's state. It accepts the feature toggle name and an optional component to be rendered in case the feature is disabled.
Without a component rendered in place of the ComponentToBeToggled:
import { withFeatureToggle } from 'flopflip';
import flagsNames from './feature-flags';
const ComponentToBeToggled = () => <h3>I might be gone or there!</h3>;
export default withFeatureToggle(flagsNames.THE_FEATURE_TOGGLE)(
ComponentToBeToggled
);With a component rendered in place of the ComponentToBeToggled:
import { withFeatureToggle } from 'flopflip';
import flagsNames from './feature-flags';
const ComponentToBeToggled = () => <h3>I might be gone or there!</h3>;
const ComponentToBeRenderedInstead = () =>
<h3>At least there is a fallback!</h3>;
export default withFeatureToggle(flagsNames.THE_FEATURE_TOGGLE)(
ComponentToBeToggled,
ComponentToBeRenderedInstead
);injectFeatureToggles
This HoC matches feature toggles given against configured ones and injects the matching result. withFeatureToggle uses this to conditionally render a component.
import { injectFeatureToggles } from 'flopflip';
import flagsNames from './feature-flags';
const Component = props => {
if (props.featureToggles[flagsNames.TOGGLE_A])
return <h3>Something to render!</h3>;
else if (props.featureToggles[flagsNames.TOGGLE_B])
return <h3>Something else to render!</h3>;
return <h3>Something different to render!</h3>;
};
export default injectFeatureToggles([flagsNames.TOGGLE_A, flagsNames.TOGGLE_B])(
Component
);The feature flags will be available as props within the component allowing some custom decisions based on their value.
Module formats
Flopflip is built as a UMD module using rollup. The distribution version is not added to git but created as a preversion script.
- ...ESM just import the
dist/flopflip.es.jswithin your app.- ...it's a transpiled version accessible via the
pkg.module
- ...it's a transpiled version accessible via the
- ...CommonJS use the
dist/flopflip.umd.js - ...AMD use the
dist/flopflip.umd.js - ...
<script />link it todist/flopflip.umd.jsordist/flopflip.umd.min.js
All build files are part of the npm distribution using the files array to keep install time short.