Modern Frontend CI in 2023: A Complete Guide

Using Bit’s Ripple CI to to enhance CI workflows in 2023

Lakindu Hewawasam
Bits and Pieces

--

Modern app development no longer relies on monolith apps to build great software. Developers have started moving away from a monolithic setup and adopting a pattern called composable architecture.

In a nutshell, a composable architecture is where you think and design your application as tiny pieces, called components, that combine to create one whole app you serve to your users. It’s similar to a MACH architecture, and has several advantages like:

  1. Better flexibility: You can independently design, develop, and version your components. Therefore, they can be modified, added, and removed without dramatically impacting other parts.
  2. Better reusability: You no longer build components bound to a particular app. Instead, you decouple your components and plug these components in any place without an issue.

This is where tools like Bit come into the picture. Bit allows developers to build composable applications without effort by letting teams design, develop, test, and version components in an independent/isolated environment.

This means that you no longer have to work on one large project but can only work on the components you need to work on. Thus, you don’t need access to an entire codebase. Not only that, but this also implies that you can now efficiently distribute your component library and even build distributed design systems.

What is the need for a better CI pipeline in 2023?

When building composable apps, assuming that your app is distributed is always safe because your components will lie in different repos. Therefore, traditional CI measures will no longer be effective. For instance, consider the component tree depicted below:

Figure: A Component Tree in Bit Cloud

Here’s a sample component tree that I built. It contains two design elements — icon and button that are combined to create the widget - button-icon. Now, traditionally, if you were building this, you'd have a single React app that you'd use to build these React components. But, in distributed component development, you will maintain each separately (as shown in the difference in version numbers).

Therefore, you can’t run a traditional CI pipeline as these components are not in one place. Instead, you’d need to create some Ripple effect on your component tree where your components traverse from the child to the parent and test its usage and ensure that everything is working as expected.

Well, this is where Ripple CI comes into the picture.

Using Bit’s Ripple CI to build a CI pipeline

The Ripple CI is a cloud-based CI pipeline developed by Bit. It lets developers build their Bit scopes upon making changes to different components to ensure that the rest aren’t impacted and continue working as expected.

Sounds interesting. Well, let’s build a CI pipeline on our own.

Step 01 — Installing Bit

First, you must install Bit on your local development environment before doing anything. So, run the command depicted below to install Bit:

npx @teambit/bvm install

If you’ve managed to install Bit successfully, you should see the output shown below:

Figure: Installing Bit

Step 02 — Creating a Bit scope

Next, we’ll need to set up a Bit scope on Bit Cloud. This will let us host our components on a remote server that can later be used to trigger the Ripple CI. To do so:

Figure: Creating the scope

Step 03 — Creating a Bit Workspace

Next, you’ll need to create a Bit workspace that points to the remote scope. This will let you work on your local computer and build the necessary components.

To do so, run the following command:

bit new react ripple-ci-workspace --env teambit.react/react-env --default-scope my-org.my-scope

Replace my-org.my-scope with YOUR-BIT-USERNAME.ripple-ci. In my case, it'll be lakindu.ripple-ci.

Once you’ve created the scope, you should see the output shown below:

Figure: Creating the Bit Workspace

Next, open the workspace and run bit start to view your local development server:

Figure: Starting the Bit server

Step 04 — Building the component tree for CI

Next, we can start building the sample components:

  1. Button
  2. Icon
  3. Button-Icon

The Button-Icon will comprise a composition of the Icon and Button components.

To create these components with Bit, run the command:

bit create react design/button design/icon widgets/button-icon

This command will create the three components where button and icon will be located in the design namespace while the button-icon will be stored in the widgets namespace. Upon doing so, you'll see the output:

Figure: Creating the Bit components

Next, let’s update the button-icon.tsx file with the following code:

import type { ReactNode } from 'react';
import React from 'react';
import { Button } from '@lakinduhewa/ripple-ci.design.button';
import { Icon } from '@lakinduhewa/ripple-ci.design.icon';

export type ButtonIconProps = {
children?: ReactNode;
};

export function ButtonIcon({ children }: ButtonIconProps) {
return (
<div>
{children}
<Button />
<Icon />
</div>
);
}

What we’ve done is we’ve made the ButtonIcon component uses the Button and Icon component as its children. Next, run bit tag && bit export to export these components onto Bit Cloud. Upon doing so, visit your Bit Scope on Bit Cloud, and you'll see the screenshot below:

Figure: Viewing exported components

Step 06 — Triggering the Ripple CI

Okay, now’s the fun part. Playing around with Ripple CI.

Let’s assume we changed the Button or Icon component that ButtonIcon is using. In a nutshell, we want to propagate that change to its parent up the tree to ensure that the ButtonIcon uses the newest version of its children and that your distributed component architecture is consistent.

But how do we do this?

Well, you can do this by using lanes. Think of Bit Lanes like Git Branches. A lane consists of components that you’ve changed. And it can be reviewed and merged by peers in your team.

So, during this merge process, Bit will trigger its Ripple CI and propagate the changes up the component tree. To create a lane, run the following command:

bit lane create adding-button-impl --scope lakinduhewa.ripple-ci

Ensure that you replace lakinduhewa.ripple-ci with your username and scope name. After you've done this, you'll get the output:

You’re on a new Lane and can start working on the component. Next, open up button.tsx and include the following code:

import type { ReactNode } from 'react';
import React from 'react';

export type ButtonProps = {
children?: ReactNode;
onClick?: () => void;
};

export function Button({ children, onClick }: ButtonProps) {
return (
<div>
{children}
<button
type='button'
onClick={onClick}
>
Sample Button
</button>
</div>
);
}

Next, run the command:

bit snap --message "adding support for button onclick"

This is similar to a Git Commit. Next, run bit export to ship your Lane to your remote scope. Once you've done this, you'll see the output below:

Next, head to your Bit Scope and go to “Change Requests”. You’ll see the Draft Lane that you created as shown below:

Click on “Create Change Request” and select the name of the lane:

Next, you’ll see the Change Request as shown below:

Hereafter, click on Merge & Tag:

This will automatically merge your changes onto the Main lane, trigger a Ripple CI build, and release all of your components through the CI, including a complete traversal through the parent tree.

Next, head over to Ripple CI, and you’ll see the job:

As shown, it’s updating the Button component, and as a result ButtonIcon was impacted. Therefore, the Ripple CI released both of the components as new versions.

Wrapping up

Ripple CI brings immense power to your development workflow, especially when moving towards distributed composable app development in 2023.

Using only the components you need to work on and still ensuring that the release will be propagated across your component tree is robust and highly encouraged when building modern apps in 2023.

If you’re interested, consider checking out the Bit Scope we created in this article here.

Thank you for reading.

--

--