How to open source your React components
Learning how to use productivity tools will save you a great amount of time
Preface
Have you ever thought about open source your awesome React components? Follow this tutorial and you will learn how to use some of the best productivity tools to help you scaffold a project, write a React component and publish it to NPM so that it can be used by developers around the world.
Things Required
First, let’s think about what we need before writing any code, below is a list of the basic requirement for open-sourcing a React component:
- Babel and Webpack
Although they are not necessary, they will make your life much easier. Babel allows you to use modules, JSX with ES6 syntax. Webpack allows you to hot reload the component during the development using HMR(Hot Module Replacement), you can plug in Sass loader to make writing CSS with better experience, and use the Uglify plugin to minify your JavaScript codes. Also Webpack helps you bundle the final assets for distribution.
- Unit Test
Function test and code coverage are important for open source project, who wants to use a buggy component that doesn’t work as expected?
- ES Module and UMD
Eventually our React component should be independent and reusable, and it needs to be self-contained. There are several ways to achieve the encapsulation, the most common ones are ES Module and UMD. With ES Module, we can require or import the component, whereas UMD allows us to use the component by loading it with <script> tag.
- Deployment
Once we finish our development, how do we publish it to NPM? Github is the best place to host our repo, and how to make the whole release cycle easier so that whenever a new version published to NPM, our Github release page also shows the new release information including the relative changes.
As a JavaScript developer, I used to tackle all the above requirements by spending hours or even days of time to grab the necessary tools and made them work as desired, that helped me a lot in understanding how things work together and I enjoyed it. I even built my own tools like React Webpack Boilerplate and Slush Webpack HTML to help me scaffold the websites quicker. But I haven’t tried to open source a React component, and whenever I am passionate to start doing it, I remember the following picture:
Yes, scaffolding a project takes time and I don’t want to repeat my work!
Scaffold in 3 Steps
Luckily, I found some tools which are super awesome to help me solve the above requirements.
Before we go too far, make sure the component name is still available on NPM, andnpm search
should help. Let’s say we are going to create a fancy React button, not sure see if react-fancy-button
is already been taken:
> npm search react-fancy-buttonNAME | DESCRIPTION | VERSION | DATE | ...
react-fancy-button | React Button | 1.0.5 | 2017-11-01 | ...
Unfortunately, we have to pick another name react-cool-button
.
Sometimes I use Create React App to play with some React components, but it’s not designed for making a single React component, it’s for building a React website.
nwb is a toolkit for developing React apps, Preact apps, Vanilla JavaScript apps, React components and libraries and npm modules for the web! The most important thing is hides all the complexity of setting up Webpack, Babel, unit test etc.
This is how I use nwb to scaffold a React component:
Step 1. Install nwb and create the project folder
> npm install -g nwb
> nwb new react-component react-cool-buttonCreating a react-component project...
? Do you want to create an ES modules build for use by compatible bundlers? Yes
? Do you want to create a UMD build for global usage via <script> tag? No
create .gitignore
create .travis.yml
create CONTRIBUTING.md
create README.md
create demo/src/index.js
create nwb.config.js
create package.json
create src/index.js
create tests/.eslintrc
create tests/index-test.js
✔ Installing react and react-dom
✔ Initing Git repo
nwb created a folder named react-cool-button
and installed the necessary npm packages. Run npm start
and open a browser tab, go to http://localhost:3000
, you will see a demo page for the React component:
The coolest thing is if you modify the React Component in src/index.js
or the demo page indemo/src/index.js
, the demo page will be refreshed automatically!
Step 2. Setup Github repository
Go to Github and create a new repository called react-cool-button
, do not initialize the repository with a README, we just need an empty repository and soon will set up with the new react-cool-button
folder just created.
Now if you type git remote -v
in react-cool-button
folder, it will show you empty result. Let’s fix it so we can push local changes to remote server.
> git remote add origin git@github.com:YOUR-GITHUB-USERNAME/react-cool-button.git
> git config user.name YOUR-GITHUB-USERNAME
> git config user.email YOUR-GITHUB-EMAIL
> git remote -v
origin git@github.com:YOUR-GITHUB-USERNAME/react-cool-button.git (fetch)
origin git@github.com:YOUR-GITHUB-USERNAME/react-cool-button.git (push)
> git push -u origin master...Branch 'master' set up to track remote branch 'master' from 'origin'.
Step 3. Setup deployment with Travis CI
Travis is one of the best CI services that allows us to execute tasks whenever there is a new push to the remote repository. We would like to use it to help us publish our React component to NPM when a commit is pushed to master branch or a new pull request is merged to master branch as well. First we need to let Travis be aware of our new repository, go to Travis and let it monitor the react-cool-button
repository.
Publishing to npm is simple, we can use npm publish
, but we don’t want to do it manually, also we want to update the Github release page to include the new release information. semantic-release is the perfect tool to achieve this, and it’s super easy to set it up.
First, install semantic-release-cli
.
> npm i -g semantic-release-cli
Then use it to set up all the necessary connections and authentication with NPM, Github and Travis:
> cd react-cool-button
> semantic-release-cli setup? What is your npm registry? https://registry.npmjs.org/
? What is your npm username? YOUR-NPM-USERNAME
? What is your npm password? [hidden]
? What is your GitHub username? YOUR-GITHUB-USERNAME
? What is your GitHub password? [hidden]
? What is your GitHub two-factor authentication code? [hidden]
? What CI are you using? Travis CI
? Do you want a `.travis.yml` file with semantic-release setup? Yes
? Do you want to overwrite the existing `.travis.yml`? No
The package.json file is now updated:
{
"name": "react-cool-button",
"version": "0.0.0-development",
"description": "react-cool-button React component",
"main": "lib/index.js",
"module": "es/index.js",
"files": [
"css",
"es",
"lib",
"umd"
],
"scripts": {
"build": "nwb build-react-component",
"clean": "nwb clean-module && nwb clean-demo",
"prepublishOnly": "npm run build",
"start": "nwb serve-react-demo",
"test": "nwb test-react",
"test:coverage": "nwb test-react --coverage",
"test:watch": "nwb test-react --server",
"travis-deploy-once": "travis-deploy-once",
"semantic-release": "semantic-release"
},
"dependencies": {},
"peerDependencies": {
"react": "16.x"
},
"devDependencies": {
"nwb": "0.23.x",
"react": "^16.5.1",
"react-dom": "^16.5.1",
"travis-deploy-once": "^5.0.7",
"semantic-release": "^15.9.15"
},
"author": "",
"homepage": "",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/jeantimex/react-cool-button.git"
},
"keywords": [
"react-component"
]
}
As you can see, running semantic-release-cli setup
modified the package.json
file with the highlighted sections.
- 0.0.0-development
semantic-release calculates a new version for you based on the commit message! The commit message needs to follow Angular Commit Message Conventions. If you are not sure what it is, read Introduction to Semantic Release. Basically your commit message should look like this:
semantic-release will bump up the new version based on the commit message like so:
- travis-deploy-once
travis-deploy-once
ensures that the release happens only once, when all the builds have finished, instead of releasing for every tested Node version.
Now let’s modify the .travis.yml
file:
sudo: falselanguage: node_jscache:
directories:
- ~/.npmnotifications:
email: falsenode_js:
- 8before_install:
- npm install codecov.io coverallsafter_success:
- cat ./coverage/lcov.info | ./node_modules/codecov.io/bin/codecov.io.js
- cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
- npm run build
- npm run travis-deploy-once "npm run semantic-release"branches:
only:
- master
npm run build
makes sure the distribution folder dist
is generated for publishing to NPM. Once the dist
folder is generated, run semantic-release
.
Since package.json
is updated with new packages, let’s make sure the package-lock.json
is also updated, run npm install
.
> npm install
Let’s save our changes and create a new commit:
> git add -A
> git commit -m "fix: Finish scaffolding"
> git push
Because we push directly to the master branch, Travis will trigger a job to perform unit test, build and publish to NPM. The react-cool-button
package is now listed in NPM:
🎉 Congratulations! We just published our React component! And the Github release page is also updated automatically:
Writing React Components
At this point, all the heavy lifting tasks are completed, now it’s time to enjoy the development of our fancy React button!
Use your favorite code editor and open the react-cool-button
project.
- The
src
folder will contain all the source code for our React component. - The
tests
folder will contain all the unit tests. - The
demo
folder is used to showcase the React component. - The
dist
folder will be generated by runningnpm run build
and it will contain all the JavaScript codes for npm distribution.
Step 1. Create CoolButton
folder inside src
and have the following files in it:
src
├── CoolButton
│ ├── CoolButton.js
│ ├── index.js
│ └── styles.css
└── index.js
src/CoolButton/CoolButton.js:
import React, { Component } from 'react';
import './styles.css';class CoolButton extends Component {
render() {
return (
<button className="cool-button">
{this.props.children}
</button>
);
}
}export default CoolButton;
src/CoolButton/styles.css:
.cool-button {
background-color: #fff;
border-radius: 28%;
box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.1);
display: inline-block;
height: 90px;
line-height: 90px;
overflow: hidden;
position: relative;
text-align: center;
width: 90px;
}
src/CoolButton/index.js:
export { default as CoolButton } from './CoolButton';
src/index.js:
export { CoolButton } from './CoolButton';
Now modify the demo/src/index.js to use the CoolButton
:
import React, {Component} from 'react'
import {render} from 'react-dom'import { CoolButton } from '../../src'class Demo extends Component {
render() {
return <div>
<h1>react-cool-button Demo</h1>
<CoolButton>Cool</CoolButton>
</div>
}
}render(<Demo/>, document.querySelector('#demo'))
If you run npm start
, you will see the newly created CoolButton on the demo page:
We have to modify the unit test, rename the index-test.js
to CoolButton-test.js
and edit the content like so:
import expect from 'expect'
import React from 'react'
import {render, unmountComponentAtNode} from 'react-dom'import { CoolButton } from 'src/'describe('CoolButton', () => {
let nodebeforeEach(() => {
node = document.createElement('div')
})afterEach(() => {
unmountComponentAtNode(node)
})it('should render the CoolButton', () => {
render(<CoolButton>Cool</CoolButton>, node, () => {
expect(node.innerHTML).toContain('Cool')
})
})
})
Run npm run test
and make sure it passes.
Finally let’s publish the new updates to NPM! All we need to do is commit the changes to master branch, make sure follow the Angular Commit Message Conventions:
> git add -A
> git commit -m "feat: Introduce CoolButton React component"
Once Travis completes the build, the react-cool-button
package will be updated to v1.1.0
and you can ask your friends to try out this cool React button:
> npm install react-cool-button
Conclusion
Managing an open source project is not easy, using the correct tools can help you save a lot of time. I hope you enjoy this tutorial and it’s helpful to you.
The source code of this tutorial can be found on my Github page.
About me
At Box, I have been using React for three years, I contribute to Box React UI which is a collection of React components designed elegantly for Box projects. Also I maintain several other open source projects like React Webpack Boilerplate, JavaScript Problems and Solutions, iOS Collapsible Table Section, Klotski etc.