Bloom acts as a central repository for reuseable React components and common styles to promote consistency across various projects at Appear Here. It also acts as a style guide to demonstrate how components should be used on their own and in combination with each other.
It's been bootstrapped with create-react-app, and has a number of additional features to make development easier.
Include Bloom in your projects like any other npm/yarn module:
npm install @appearhere/bloom
or
yarn install @appearhere/bloom
You'll now be able to require components from bloom like any other module:
var bloom = require('@appearhere/bloom');
var Link = require('@appearhere/bloom/components/Link/Link');
// ES2016
import bloom from '@appearhere/bloom';
import Link from '@appearhere/bloom/components/Link/Link';
If the module import fails like so, You may need an appropriate loader to handle this file type
, you'll need to make sure you're transpiling Bloom along with the rest of your code:
// BEFORE
{
test: /\.(js|jsx)$/,
include: './src',
loader: 'babel',
query: require('./babel.dev')
},
// AFTER
{
test: /\.(js|jsx)$/,
include: ['./src', './node_modules/@appearhere/bloom'],
loader: 'babel',
query: require('./babel.dev')
}
Note: Check engines from package.json for node version.
Install:
yarn install
To build the style guide for deployment:
yarn run build
This will create a static version of the style guide in /build
.
To build the style guide for development:
yarn dev
This will run the style guide, automatically opening your browser window at the root page. We use hot module reloading, so the vast majority of changes you'll make to components or the style guide itself will auto update on the page.
NOTE: changes to variables current require you to restart the project, as they're consumed on the initial run π
Aside from running the style guide locally on your machine, we also have the option to use React Storybook.
React Storybook is a UI development environment for your React components. With it, you can visualize different states of your UI components and develop them interactively.
To use storybook, simply run:
yarn run storybook
All components inside Bloom should:
- Be reuseable
- Have tests
- Have stories (as per React Storybook)
Component styles, tests and stories should live along side their components. Tests and stories are automatically picked up by their respective modules via a strict naming convention:
// Component
Link.js
// Styles
Link.css
// Tests
Link.test.js
// Story
Link.story.js
Typically speaking, components should live in their own directory with the same name as the component, e.g., components/Link/Link.js
. In some cases, you may find it makes more sense to have multiple components live in the same directory, where there is a tight relationship between them.
When developing components, it's suggested your start by developing them in isolation, using React Storybook, before adding them to the style guide to demonstrate how they work together with other components. That's not to say you have to do this, how you actually go about it is down to your personal preference.
Currently, we're setup to use Jest for testing.
At minimum, all components should have a "does it render" test:
import React from 'react';
import ReactDOM from 'react-dom';
import Link from './Link';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<Link />, div);
});
You may also want to test class level functions:
it('tracks the number of clicks', () => {
const div = document.createElement('div');
const instance = ReactDOM.render(<Link />, div);
t.equals(instace.state.clicks, 0);
instance.trackClick();
t.equals(instace.state.clicks, 1);
});
Be careful when adding tests; we want to ensure that a simple change to a component's mark up, e.g., changing the className
value, don't result a ton of failing tests. We also need to be wary of when we're effectively testing the React internals as opposed to our own components.
Sometimes you might need to make changes to Bloom while you're working on your main project. Having to flip over to Bloom, PR the changes and get them published is slow and cumbersome. yarn install ../path/to/bloom
is one option, but every time you make a change, you'll have to redo the command and recompile.
Enter yarn link
yarn link
uses symlinks to reference your local copy of Bloom in your main project, meaning changes are reflected in every project that consumes your local copy of Bloom.
To get started, head to your copy of Bloom and run
yarn link
This will create a global symlink to your copy of Bloom. Head to your project and run to use this reference instead of the regularly installed package:
yarn link @appearhere/bloom
One flaw with this, is that a Webpack loader's include
property won't follow symlinks. Earlier in the README, we managed to get Bloom into your project like so:
{
test: /\.(js|jsx)$/,
include: ['./src', './node_modules/@appearhere/bloom'],
loader: 'babel',
query: require('./babel.dev')
}
To make this work, we instead need to ensure the include path to Bloom is absolute:
const pathToBloom = fs.realpathSync('./node_modules/@appearhere/bloom');
{
test: /\.(js|jsx)$/,
include: ['./src', pathToBloom],
loader: 'babel',
query: require('./babel.dev')
}
Additional bonus: if the loader you're using is setup to work with hot module reloading, changes to Bloom will also get hot reloaded in your main project π
Bloom, as required by NPM, follows Semvar. That said, given it has yet to reach a MVP state, only minor and patch versions will be incremented. This is because the whole project should be treated as unstable, i.e., we might change any component at a moments notice. Given that it will only be used internally for now, that's fine.
In this time, a Bloom release will be made, at most, once a day. When publishing Bloom to NPM, increment the minor or patch versions, publish then bump the version of Bloom used in our other projects. This should ensure we're always using the latest and greatest in our applications, and ensure that they never get too far out of sync.
When the frequency of work on Bloom decreases to significantly enough, then consider releasing a v1.0.0
. This should be when we're making very few changes to components already in the library and we're only adding new ones.
Once we've released v1.0.0
or open sourced the project, we'll adopt true Semvar. Ideally, we'll make releases based on a roadmap of some form, probably dictated by our internal sprints.
So as to not slow us down, we should continue to publish Bloom on a regular basis, but instead us pre-releases, e.g., v1.0.0-0.0.1
. The current thought is that the pre-release versions will follow a similar pattern to Semvar itself, i.e., major.minor.patch.
Bloom uses Lerna to publish new versions of the library.
To publish a new version, pull down latest master, then run:
yarn build
(see below for which one to use)lerna publish
When to use what:
major
: A change where a consumer of this library will have to change their code to work with this new versionminor
: Adding a new feature, or making a major internal change without outward-facing consequencespatch
: Fixing a small bug, typo, or other small change
Do not create tags as part of pull requests. Adding new features to master is different to publishing a version to yarn.
More info will be added here when we need to tackle the v1.0.0
release.
Once youβve pushed the new version to GitHub and published the release, head to Bloom's releases and add a change log.
You can auto generate one by running:
git --no-pager log [PREVIOUS_VERSION_TAG]..[NEW_VERSION_TAG] --pretty=format:'- %s %H ' --reverse --no-merges
As part of the release process, Bloom will automatically be published to Heroku.
It's the collective name for Jellyfish; they're pretty dumb, look cool
and have a form of immortality through regeneration which are all aspects of a good pattern library. bloom.appearhere.co.uk
also sounds decent!
The repo was bootstrapped with create-react-app, and you can find the readme that it ships with here. It's worth reading if you want to know more about the foundation of this project. Note that some of it might be out of date.