One of the reasons we love React is the truly reusable nature of its components, even compared to other frameworks. Reusing components means you can save time writing the same code, prevent bugs and mistakes, and keep your UI consistent for users across your different applications.
But, reusing React between apps components can be harder than it sounds. In the past, this process involved splitting repositories, boiler-plating packages, configuring builds, refactoring our apps and more.
In this post, I'll show how to use Bit (GitHub) in order make this process much easier, saving around 90% of the work. Also, it will allow you to gradually collect existing components from your apps into a reusable collection for your team to share - like these ones.
In this short tutorial, we'll learn how to:
Quickly setup a Bit workspace
Track and isolate components in your app
Define a zero-config React compiler
Version and export components from your app
Use the components in a new app
- Bonus: Leveraging Bit to modify the component from the consuming app (yes), and syncing the changes between the two apps.
Quick Setup
So for this tutorial, we've prepared an example React App on GitHub you can clone.
$ git clone https://github.com/teambit/bit-react-tutorial
$ cd bit-react-tutorial
$ yarn
Now, go ahead and install Bit.
$ npm install bit-bin -g
Next, we'll need a remote collection to host the shared components. You can set up on your own server, but let's use Bit's free component hub instead. This way our collection can be visualized and shared with our team, which is very useful.
quickly head over to bit.dev and create a free collection. It should take less than a minute.
Now return to your terminal and run bit login
to connect your local workspace with the remote collection, where we'll export our components.
$ bit login
Cool. Now return to the project you've cloned and init a Bit workspace:
$ bit init --package-manager yarn
successfully initialized a bit workspace.
That's it. Next, let's track and isolate a reusable component from the app.
Track and isolate reusable components
Bit lets you track components in your app, and isolates them for reuse, including automatically defining all dependencies. You can track multiple components using a glob pattern (src/components/*
) or specify a path for a specific component. In this example, we'll use the later.
Let's use the bit add
command to track the "product list" component in the app. We'll track it with the ID 'product-list'. Here's an example of how it will look like as a shared component in bit.dev.
$ bit add src/components/product-list
tracking component product-list:
added src/components/product-list/index.js
added src/components/product-list/product-list.css
added src/components/product-list/products.js
Let's run a quick bit status
to learn that Bit successfully tracked all the files of the component. You can use this command at any stage to learn more, it's quite useful!
$ bit status
new components
(use "bit tag --all [version]" to lock a version with all your changes)
> product-list ... ok
Define a zero-config reusable React compiler
To make sure the component can run outside of the project, we'll tell Bit to define a reusable React compiler for it. This is part of how Bit isolates components for reuse, while saving you the work of having to define a build step for every component.
Let's import the React compiler into your project's workspace. You can find more compiler here in this collection, including react-typescript.
$ bit import bit.envs/compilers/react --compiler
the following component environments were installed
- bit.envs/react@0.1.3
Right now the component might consume dependencies from your project. Bit's build is taking place in an isolated environment to make sure the process will also succeed on the cloud or in any other project. To build your component, run this command inside your react project:
$ bit build
Version and export reusable components
Now let's export the component to your collection. As you see, you don't need to split your repos or refactor your app.
First, let's tag a version for the component. Bit lets you version and export individual components, and as it nows about each component's dependants, you can later bump versions for single component and all its dependants at once.
$ bit tag --all 0.0.1
1 component(s) tagged
(use "bit export [collection]" to push these components to a remote")
(use "bit untag" to unstage versions)
new components
(first version for components)
> product-list@0.0.1
You can run a quick 'bit status' to verify if you like, and then export it to your collection:
$ bit export <username>.<collection-name>
exported 1 components to <username>.<collection-name>
Now head over to your bit.dev collection and see how it looks!
You can save a visual example for your component, so you and your team can easily discover, try and use this component later on.
Install components in a new app
Create a new React app using create-create-app (or your own).
$ npx create-react-app my-new-app
Move over to the new app you created.
Install the component from bit.dev:
$ yarn add @bit/<username>.<collection-name>.product-list --save
That's it! you can now use the component in your new app!
- If you want to use npm, run
npm install
once after the project is created so a package-lock.json will be created and npm will organize dependencies correctly.
Modify components from the consuming app
Now let's use Bit to import the component's source-code from bit.dev and make some changes, right from the new app.
First, init a Bit workspace for the new project:
$ bit init
And import the component
$ bit import <username>.<collection-name>/product-list
successfully imported one component
Here is what happened:
A new top-level components folder is created that includes the code of the component, with its compiled code and node_modules (in this case the node_modules are empty, as all of your node_modules are peer dependencies and are taken from the root project.
The .bitmap
file was modified to include the reference to the component
The package.json file is modified to point to the files rather than the remote package. Your package.json now displays:
"@bit/<username>.<collection-name>.product-list": "file:./components/product-list"
Start your application to make sure it still works. As you'll see, no changes are required: Bit takes care of everything.
Then, just go ahead and make changes to the code anyway you like!
Here's an example.
Now run a quick bit status
to see that the code is changed. Since Bit tracks the source-code itself (via a Git extension), it "knows" that the component is modified.
$ bit status
modified components
(use "bit tag --all [version]" to lock a version with all your changes)
(use "bit diff" to compare changes)
> product-list ... ok
Now tag a version and export the component back to bit.dev:
$ bit tag product-list
1 component(s) tagged
(use "bit export [collection]" to push these components to a remote")
(use "bit untag" to unstage versions)
changed components
(components that got a version bump)
> <username>.<collection-name>/product-list@0.0.2
and...
$ bit export <username>.<collection-name>
exported 1 components to <username>.<collection-name>
You can now see the updated version with the changes in bit.dev!
Update changes in the first app (checkout)
Switch back to the react-tutorial
app you cloned and exported the component from, and check for updates:
$ bit import
successfully imported one component
- updated <username>.<collection-name>/product-list new versions: 0.0.2
Run bit status
to see that an update is availabe for product-list
:
$ bit status
pending updates
(use "bit checkout [version] [component_id]" to merge changes)
(use "bit diff [component_id] [new_version]" to compare changes)
(use "bit log [component_id]" to list all available versions)
> <username>.react-tutorial/product-list current: 0.0.1 latest: 0.0.2
Merge the changes done to the component to your project. The structure of the command is bit checkout <version> <component>
. So you run:
$ bit checkout 0.0.2 product-list
successfully switched <username>.react-tutorial/product-list to version 0.0.2
updated src/app/product-list/product-list.component.css
updated src/app/product-list/product-list.component.html
updated src/app/product-list/product-list.component.ts
updated src/app/product-list/product-list.module.ts
updated src/app/product-list/products.ts
Bit performs a git merge. The code from the updated component is now merged into your code.
Run the application again to see it is working properly with the updated component:
$ yarn start
That's it. A change was moved between the two projects. Your application is running with an updated component.
Happy coding!
Conclusion
By being able to more easily reuse React components between applications you can speed your development velocity with React, keep a consistent UI, prevent bugs and mistakes and better collaborate as a team over a collection of shared components. It's also a useful way to create a reusable UI component library for your team in a gradual way without having to stop everything or lose focus.
Feel free to try it out yourself, explore the project in GitHub. Happy coding!
Top comments (1)
This is an awesome post, thanks for sharing!