Deploying a Composable React App to Netlify

ni
nitsan7702 months ago

Introduction

In this blog post, we will learn how to build and deploy a composable React app to Netlify, using Bit.

In Bit, everything is a component. The app is also just a deployable component. This means we can easily compose it with another component - the Netlify Deployer component - to deploy it to Netlify. Just like playing with Lego blocks.

Lego blocks

This is the app we will build:

Bit
hello world!

Welcome to Bit

Edit this component and see it change in the UI or play with the commands below to learn more about how Bit works.

Bit CLI

Understanding Bit's Commands

Templates

$bit
Copiedcopy

Create

$bit
Copiedcopy

Import

$bit
Copiedcopy

Tag

$bit
Copiedcopy

Export

$bit
Copiedcopy

You can see the deployed app here.

If you're feeling a bit tired today, here's a TL;DR of the steps we will take:

  1. Create a new React app with Bit
    $bit
    Copiedcopy
  2. Install the Netlify deployer component and plug it into your app:
    $bit
    Copiedcopy

Add this snippet to your my-app.react-app.tsx file:

import type { ReactAppOptions } from '@teambit/react';
import {
  Netlify,
  NetlifyOptions,
} from '@teambit/cloud-providers.deployers.netlify';

const netlifyConfig: NetlifyOptions = {
  accessToken: process.env.NETLIFY_AUTH_TOKEN as string,
  productionSiteName: 'your-site-name',
  team: 'your-team-name',
};

const netlify = new Netlify(netlifyConfig);

export const MyApp: ReactAppOptions = {
  name: 'my-app',
  entry: [require.resolve('./my-app.app-root')],
  deploy: netlify.deploy.bind(netlify),
};

export default MyApp;
CopiedCopy

Don't forget to add your Netlify token to your environment variables.

  1. Tag the app component:
$bit
Copiedcopy

Great job! You've just deployed your React app to Netlify with Bit. Now every time you tag a new version of your app, Bit will automatically deploy it to Netlify.

If you change any of the app dependencies, Bit will also deploy the updated version of the app.

Let's take a closer look at how this works.

Getting the app up and running

Please make sure that the Bit binary is installed on your machine:

npx @teambit/bvm install
CopiedCopy

You can quickly get up and running with a composable React app by using a Starter. Run the following command:

$bit
Copiedcopy

This command creates a new workspace from the React-app starter. It includes a React App component in addition to some preconfigured React components.

To standardize your development workflow, you can create your own Starters and Component scaffolder.

Your workspace should look like this after running the command:

My-React-App
.bit
.vscode
react-app
types
.bitmap
.eslintrc.js
.gitignore
.prettierrc.js
README.md
tsconfig.json
workspace.jsonc

As you can see you have three components in your workspace. In this blog post, we will focus on the app component.

Here are some useful commands to get you started:

  • This command runs the local development server:
    $bit
    Copiedcopy
  • You can run the following command to view all components in your workspace and isolate them for development:
    $bit
    Copiedcopy

The latter command opens the workspace UI in a new browser window. It's useful for writing documentation, tests, etc., for the component.

Deploying a React app to Netlify

It's time to deploy the app! To accomplish this, we will use the Netlify Deployer component. It is designed to plug into the deploy task that is part of the tag pipeline and deploy the app to Netlify.

When you run the bit tag command, a series of tasks are executed.

To see all the tasks that are executed when you run the bit tag command, run the following command:

$bit
Copiedcopy

Here's the output:

Build Pipeline Tasks:
teambit.harmony/aspect:CoreExporter
teambit.compilation/compiler:BabelCompiler
teambit.compilation/compiler:TSCompiler
teambit.defender/tester:TestComponents
teambit.pkg/pkg:PreparePackages
teambit.harmony/application:build_application
teambit.preview/preview:GenerateEnvTemplate
teambit.preview/preview:GeneratePreview

Tag Pipeline Tasks:
teambit.pkg/pkg:PackComponents
teambit.pkg/pkg:PublishComponents
teambit.harmony/application:deploy_application

Snap Pipeline Tasks:
teambit.pkg/pkg:PackComponents
teambit.harmony/application:deploy_application
CopiedCopy

We won't dig into the details of each task, but we'll focus on the deploy_application one. The app will be deployed by this task. It doesn't matter if the app is a React app or a Node app.

In our case, we are deploying a React app to Netlify. Hence, we will use Netlify Deployer. Let's install it in our workspace:

$bit
Copiedcopy

Now we can add it to the deploy task slot. In the my-app.react-app.ts file add the following:

You will have to add your Netlify access token to the `NETLIFY_AUTH_TOKEN` environment variable. Learn more about it here.
import type { ReactAppOptions } from '@teambit/react';
import {
  Netlify,
  NetlifyOptions,
} from '@teambit/cloud-providers.deployers.netlify';

const netlifyConfig: NetlifyOptions = {
  accessToken: process.env.NETLIFY_AUTH_TOKEN as string,
  productionSiteName: 'your-site-name',
  stagingSiteName: 'your-site-name-staging',
  team: 'your-team-name',
};

const netlify = new Netlify(netlifyConfig);

export const MyApp: ReactAppOptions = {
  name: 'my-app',
  entry: [require.resolve('./my-app.app-root')],
  deploy: netlify.deploy.bind(netlify),
};

export default MyApp;
CopiedCopy
As you can see in the above code snippet, we are defining two site names. A production one and a staging one. When you lock your component to a release version (e.g. 1.0.0), the production site name will be used, whereas the staging site name will be used for snaps with no release version (hashes).

Now all we have to do is to run the bit tag command to deploy the app to Netlify:

$bit
Copiedcopy

Since all components in the workspace are new, Bit will tag them all and deploy the app to Netlify. Here is the terminal output:

new components
(first version for components)
     > apps/my-app@0.0.1
     > pages/home@0.0.1
     > themes/theme@0.0.1
CopiedCopy

If you look closely at the output, you will see that the deploy_application task was executed. This is the task that deploys the app to Netlify:

✔ env "teambit.harmony/aspect", task "teambit.harmony/application:deploy_application" has completed successfully in 8s
CopiedCopy

Now that we have deployed the app, let's export them to the remote scope:

$bit
Copiedcopy

Because we built our app based on component-based software engineering (CBSE) principles, each part of the app functions independently and can be exported to a remote scope, imported into a different workspace, and used in another app as a dependency

Incremental updates and deployment

Let's say we want to modify the home page. we'll make a simple change in the home.tsx file:

- <Paragraph className={styles.texts}>Understanding Bit's Commands</Paragraph>
+ <Paragraph className={styles.texts}>Understanding Bits' Commands</Paragraph>
CopiedCopy

It would be expected that only the pages/home component would be versioned if we tagged again. However, this is not the case. All home page dependents (in this case only the app) will be tagged in the workspace, and the app will be deployed again. The reason is that Bit tracks the dependency graph, and knows which components are impacted.

$bit
Copiedcopy

Here's the output:

changed components
(components that got a version bump)
     > pages/home@0.0.2
       auto-tagged dependents:
            apps/my-app@0.0.2
CopiedCopy

The app was automatically tagged, which is exactly what we wanted. When we make changes, only the affected components will be tagged and deployed. As a result, we can save a lot of time and resources.

Don't forget to export the second version of the apps/my-app and pages/home components to the remote scope:

$bit
Copiedcopy

A glimpse into the (near) future

Here's a sneak peek at a new product released on bit.cloud later this year called Ripple CI - the first component-driven continuous integration tool.

With Ripple, you only build components, not projects. When you update a component, Ripple will run for that component and every dependent component impacted by the change, across your entire system and apps.

As a result, your builds run much faster. They propagate to every impacted product and simulate the change. In addition, they will save tons of time by isolating failures and errors, so you don't have to run everything again. It's still in beta for now :)

In the picture above from Ripple-CI, you can see changes were made to the use-change-request hook. Consequently, only dependent components are rebuilt and versioned until the app component is deployed (if all tests and builds pass).

Conclusion

We learned how to deploy a React app to Netlify using Bit in this blog post. Additionally, we learned how to keep the app up-to-date by only tagging the affected components.

Everything becomes easier when you build apps in a distributed (component-driven) manner. Components can be built, tested, and deployed independently. After that, you compose them together to build more apps and features, just like you would with Lego blocks.

Changing the deployer component would allow us to change the service provider anytime. The deployment pipeline could also be expanded with more deployers. It's as simple as adding a new component to the pipeline, for example, the Cloudflare Deployer.

There is still a lot to learn about component-based software engineering. Please visit the Documentation for more information. Feel free to join the community Slack channel if you have any questions.

This blog post component has been updated to reflect the latest changes I made to the Netlify deployer component. Before I wrote this blog post, we had only one site name.

I have now implemented the option to have two site names, one for production and one for staging. When you lock your component to a release version (e.g. 1.0.0), the production site name will be used, whereas the staging site name will be used for snaps with no release version (hashes).

As a result, every app with the Netlify deployer component as a dependency (such as The Bit Blog you are currently reading) will have the same, updated, deployment pipeline. An excellent example of how Bit can help you build a component-based software engineering system.