How to Easily Share and Consume React Components Using Bit

Learn how to easily create, share and consume react components with the awesome power of Bit

--

In this “age of components”, we often see ourselves re-writing the same logic for a similar component in a previous project every time we start a new project. Ohhh man! it becomes boring and monotonous.

I love NPM, but it can be hard to pack, publish and maintain many components. Another problem is, that once you publish a package, you can’t easily make changes to its code from a different project using it.

In comes Bit, which is a tool built to help teams easily share and manage code components across projects. Teams that scale code-sharing and code reuse enjoy faster development cycles and simpler maintenance.

In this post, we will demonstrate the power of Bit. We will create a component’s library and share the components using Bit. We will demo the consumption of the components usingnpm i @bit/... and development of the components from a different project usingbit import ...

The component’s library will contain:

  • Button
  • Table

Using Bit, we will quickly export these components from the library and use NPM to install them in a new project. Then, we’ll want to make some styling changes- so we will use Bit to make changes to the Button component right from the consuming project itself and then sync the changes between the projects. Sounds very useful? it is. Let’s see how.

Project Setup

First, we install the create-react-app CLI globally in our machine:

npm i create-react-app -g

Install the Bit CLI tool:

npm i bit-bin -g

Next, we scaffold our React project:

create-react-app react-components

Move into the directory:

cd react-components

Our components will be contained in the components folder, so we create it:

mkdir src/components

Creating the Button component

We create the Button component:

mkdir src/components/Button
touch src/components/Button/Button.css
touch src/components/Button/Button.react.js
touch src/components/Button/index.js

Open Button.css and paste the following code:

.button_wrapper {}button {
display: inline-block;
font-family: "raleway-bold", sans-serif;
font-size: 1.6rem;
height: 5rem;
line-height: 5rem;
padding: 0 3rem;
margin: 0 .3rem 1rem 0;
background: #d8d8d8;
color: #252525;
text-decoration: none;
cursor: pointer;
text-align: center;
white-space: nowrap;
border: none;
border-radius: 1000px;
-moz-transition: all 0.3s ease-in-out;
-o-transition: all 0.3s ease-in-out;
-webkit-transition: all 0.3s ease-in-out;
-ms-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
button:hover {
background: #bebebe;
color: #FFFFFF;
outline: 0;
}

Paste the following code to Button.react.js:

import React from 'react';import './Button.css';class Button extends React.Component {
constructor(props) {
super(props);
}
render() {
let {children} = this.props
return (
<div className='button_wrapper'>
<button className="button">{children}</button>
</div>
);
}
}
export default Button;

Paste in index.js:

export { default }
from './Button.react.js';

Creating the Table component

We create the Table component:

mkdir src/components/Table
touch src/components/Table/Table.css
touch src/components/Table/Table.react.js
touch src/components/Table/index.js

Paste the following in Table.css:

.table_wrapper {}/**
* tables
* -
*/
table {
border-width: 0;
width: 100%;
max-width: 100%;
font-family: "raleway-regular", sans-serif;
}
th,
td {
padding: 1.5rem 3rem;
text-align: left;
border-bottom: 1px solid #E8E8E8;
}
th {
color: #252525;
font-family: "raleway-bold", sans-serif;
}
td {
line-height: 1.5;
}
th:first-child,
td:first-child {
padding-left: 0;
}
th:last-child,
td:last-child {
padding-right: 0;
}
.table-responsive {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.table {
border-collapse: collapse !important;
}
.table td,
.table th {
background-color: #fff !important;
}
.table-bordered th,
.table-bordered td {
border: 1px solid #ddd !important;
}

Paste the following in the Table.react.js:

import React from 'react';import './Table.css';class Table extends React.Component {
constructor(props) {
super(props);
}
render() {
let { data } = this.props;
let { head, body, style } = data;
style = 'table ' + style;
return (
<div className='table_wrapper'>
<table className={style}>
<tr>
{head.map(item=><th>{item}</th>)}
</tr>
{body.map(item => <tr>{item.map(_i => <td>{_i}</td>)}</tr>)}
</table>
</div>
);
}
}
export default Table;

Paste the following in index.js:

export { default }
from './Table.react.js';

Exporting the components

Now, our react-components folder will look like this:

react-components/
- node_modules/
- src/
- components/
- Button/
- Button.react.js
- Button.css
- index.js
- Table/
- Table.css
- Table.react.js
- index.js
- App.js
- App.css
- index.css
- index.js
- package.json

We need to export the components Button and Table to Bit but we need to initialize Bit in our directory.

bit init$ bit init
successfully initialized a bit workspace.

Next, we have to import React compiler. This compiler will be used to create a dist for the components, for other projects to consume (and therefore should be used in pretty much all components which are not pure ES5). It’s also used to render our components on the bit.dev remote playground.

bit import bit.envs/compilers/react --compiler$ bit import bit.envs/compilers/react --compiler
username: chidume
password:
Fatal: There is a mismatch between the remote server version - "14.1.0" and your bit version - "14.0.4", please update
username: chidume
password:
the following component environments were installed
- bit.envs/compilers/react@1.0.2

We track our components. This tells Bit the components it has to create registries for. We use the bit add command to achieve that.

bit add src/components/*$ bit add src/components/*
tracking 2 new components

The asterisk tells Bit to track all files in the components folder.

Now we need to isolate and tag the tracked components with a version. This locks each component dependency graph in an immutable state embrace.

bit tag --all 0.0.1$ bit tag --all 0.0.1
- building components(node:3192) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Bu
ffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
2 components tagged | 2 added, 0 changed, 0 auto-tagged
added components: button@0.0.1, table@0.0.1

Now, we need to create a collection on Bit. Collection on Bit is a workspace where we organize and group related components together.

So head over to bit.dev and create a collection.

When you are done creating the collection, we will use the bit export command to push the components to Bit

bit export <YOUR_ACCOUNT_NAME_HERE>.<YOUR_COLLECTION_NAME>$ bit export chidume.my_components
username: chidume
password:
exported 2 components to scope chidume.my_components

Go to your collection page to see your components there. You can play around with them there.

Consuming the Table and Button components

With our components published to Bit, we can use the components at will in our React projects.

You see the power of Bit, it singled out the components from our react-components library so we can install a specific component, out of a bunch, without the need to pull the whole react-components library.

Now, in the collection page of our components, Bit will present all options on how to pull in our components from Bit. You will see NPM, Yarn and Bit.

NPM and Yarn is used for consumption while Bit is used for development (consuming + modifying). When we want to use the components in our React project without adding to the project we simply use either NPM or Yarn. When wanting to consume and contribute to certain components Bit option should be used.

As we are only consuming we use NPM or Yarn to install the component we need from the Bit registry.

First, we scaffold a React project:

create-react-app react-prj
cd react-prj

Now, we want to render data in a tabular form in our React project so we install the Table component

npm i @bit/chidume.my_components.table // OR (with Yarn)yarn add @bit/chidume.my_components.table

This installs the Table component in /@bit/chidume.my_components_92.table folder in /node_modules/ folder.

Then, we can use the Table component in our app. Open the App.js file and paste the following code:

import Table from '@bit/chidume.my_components.table'const tableData = {
head: [
'#',
'Head',
'Tail',
'Trunk',
'%'
],
body: [
[
0,
'Yes',
'No',
'No',
100
]
],
style: 'table-bordered'
}
class App extends Component {
render() {
return (
<Table data = { tableData } />
)
}
}

Run npm start and see our Table rendered on your browser localhost:3000.

Developing the Table and Button components

Create another React project:

create-react-app react-bit

The folder looks like this:

- react-bit
- src/
- App.js
- App.css
- index.css
- index.js
- package.json

This project is different from the react-prj and react-components projects we created. Now, we need the Table component in this project. We first initialize a bit workspace via bit init and simply import it (the Table component) from Bit like this:

bit init
bit import <YOUR_ACCOUNT_NAME_HERE>.<YOUR_COLLECTION_NAME>/table --path src/components/table
bit import chidume.my_components_92/table --path src/components/table

This command will install the table from the Bit registry into src/components/table folder of react-bit

- react-bit
- src/
- components
- table/
- dist/
- Table.css
- Table.react.js
- index.js
- package.json
- App.js
- App.css
- index.css
- index.js
- package.json

We can modify the Table component and update the component. Le’s say we want to modify the Table component to have a search box, where we can search through our data table.

modify the Button component

Let’s say we want to consume Button component and also modify it, we will use the bit import command:

bit import chidume.my_components/button

This will install the Button component in components in our root project. We can specify where we want to install the component using the --path flag. I want to install it in src/cmps folder so I run this command:

bit import chidume.my_components/button --path src/cmps$ bit import chidume.my_components/button --path src/cmps
username: chidume
password:
successfully ran npm install at \src\cmpssuccessfully imported one component
- added chidume.my_components/button new versions: 0.0.1, currently used version 0.0.1

After installation, our project will look like this:

- react-bit
- src/
- components
- table/
- dist/
- Table.css
- Table.react.js
- index.js
- package.json
- cmps/
- dist/
- node_modules/
- Button.css
- Button.react.js
- index.js
- package.json
- package-lock.json
- bit.json
- .bitmap
- App.js
- App.css
- index.css
- index.js
- package.json

Now, in our modification of the Button component we want to remove the div.button_wrapper element because it extends beyond the button element:

class Button extends React.Component {
constructor(props) {
super(props);
}
render() {
let {children} = this.props
return (
<div className='button_wrapper'>
<button className="button">{children}</button>
</div>
);
}
}
|
v
class Button extends React.Component {
constructor(props) {
super(props);
}
render() {
let {children} = this.props
return (
<button className="button">{children}</button>
);
}
}

we can run bit status and see that the component is modified.

bit status$ bit status
modified components
(use "bit tag --all [version]" to lock a version with all your changes)
(use "bit diff" to compare changes)
> button ... ok

See it recorded the button component as modified.

Now we have to push the changes to the Bit registry. We tag the button component:

bit tag button$ bit tag button
username: chidume
password:
successfully installed the bit.envs/compilers/react@1.0.2 compiler1 components tagged | 0 added, 1 changed, 0 auto-tagged
changed components: chidume.my_components/button@0.0.2

Here, we tag using the component’s name, Bit increments the version number for us. The previous version number for the button component is 0.0.1 now it is 0.0.2

To push the changes we use the bit export command

$ bit export chidume.my_components
username: chidume
password:
exported 1 components to scope chidume.my_components

To consume the Button we don’t have to install via NPM or Yarn, we can still consume the component via Bit. Bit adds the component as a dependency in our package.json

"dependencies": {
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-scripts": "2.1.2",
"@bit/chidume.my_components.button": "file:./src/cmps"
},

See it refers to the components folder src/cmps/. We can import the Button component via:

import Button from '@bit/chidume.my_components.button'function App() {
return (
<Button>Click Me</Button>
)
}

Conclusion

This is huge!!! We practically demonstrated how to consume and develop a component on Bit. We began by developing components Button and Table on a React project, next we initialized Bit and pushed them to Bit. We consumed them by using NPM or Yarn, further down we both consumed and modified the component Button.

It’s better you practice the example I gave above, it goes a long way to make you thoroughly understand a concept. There are so many things you can modify in the Button component.

  1. Add styling via props
  2. Add default text
  3. Add click listener via props

Import the Button component in your project and try adding the above features. you will try and fail but keep on trying, its the path to great success. I’ll be waiting for your PR :)

If you have any questions regarding this or anything I should add, correct or remove, feel free to comment, email or DM me. Thanks!!!

--

--

JS | Blockchain dev | Author of “Understanding JavaScript” and “Array Methods in JavaScript” - https://app.gumroad.com/chidumennamdi 📕