Components at Scale: Build a Library That Scales


So you want to build a component library — nice! The fact that you have even checked out this piece indicates that you’re working on a platform that's scaling. Or perhaps you’ve just hired some new devs and realized your codebase is diverging at a rate faster than quality checks can keep up with, while developers are introducing too many multiple ways of solving the same problem, increasing your technical debt.

A component library can help your developers and designers work in a much more consistent way, making efficient use of time when executed correctly.

There are always multiple ways of solving a problem, though, and you may find yourself in a situation where you may use different tools to what we use here. The architecture and tools we discuss here are to suit the particular challenges facing our team. Your situation and requirements may well be different. Thankfully, we have a wealth of options to pick from, and I would urge you to do your own research as well.

Without further ado, let's have a look at the key tech we want to incorporate.

What Tools to Use?

Personally, I always find it difficult to code by merely following steps from reading content. Instead, I like to have a repository to look at and, in tandem, play with. Here’s an example that’s available and free to use: https://github.com/gavmac/component-playground-template.

TypeScript

JavaScript developers go wild for TypeScript, and with good reason. If we want to scale our platform, we also need JavaScript that scales. TypeScript is a superset of JavaScript that primarily provides optional static typing, classes, and interfaces. TypeScript can help us to avoid painful bugs that developers commonly run into when writing JavaScript by type-checking the code.

As our React app grows with more developers pushing code, we need something to guard us against these errors and aid us to produce robust software. One of TypeScript’s biggest benefits is that it enables IDEs to provide a richer environment for spotting common errors as you type the code.

Material UI

Our repositories rely heavily on Material UI. It allows us to build common components in a nimble fashion and offers advantages when considering productivity. Therefore it makes sense for us to include it— particularly when creating our prototypes. We use its grid, inputs, buttons, etc. In addition to its well-thought-out style system, it’s also got fabulous documentation.

The trade-off is that it’s quite easy to get too heavily reliant on Material UI so that a breakaway in the future can become painful. But for the size of our team at the minute, it’s a worthwhile trade-off. New components in the future can be created without relying on it, which brings us to our next point.

Styled-components

Styled-components is a styling framework that uses tagged template literals in JavaScript and the power of CSS to provide a platform that allows you to write actual CSS to style React components. For more information about style systems, take a look at “Components at Scale: Deciding on a Style System,” where I discuss in further detail my reasoning behind styled-components.

rollup.js

Rollup is a module bundler for JavaScript that compiles small pieces of code into something larger and more complex, such as a library or application.

create-react-app

Our favorite way of starting a React project for a while now is create-react-app. It’s a quick build, offering a modern build setup, and if you don't predict any very specific webpack or Babel config changes, I would highly recommend it.

Let's Get Started

We are going to create a simple React application, using create-react-app. Jump into our terminal, where we’ll name our application component-factory, while ensuring we build it using TypeScript.

npx create-react-app component-factory — template typescript

Back to our terminal, let’s now install Material UI by running

yarn add @material-ui/core

We can install styled-components by running

yarn add @types/styled-components

Alright, now we want to do a bit of tidying up. We want to create a directory structure that looks like this. This means we can remove any of the files created by create-react-app that we don't want.

As you can see by our directory structure, we want to create a new folder under /src called components and add a new file there called styled-button.tsx. This will be the shiny new custom button that we want to use along with Material UI. Let's be really original and call it MyNewButton.

 

In the index.ts folder that you’ve created, import and export the component here. It’s this index.ts that’s going to be the entry point for our library, so any other components you create can all be imported into here.

import MyNewButtonButton from './components/buttons/styled-button';

export { MyNewButtonButton };

Now that we have a component created with TypeScript, we need to build and transpile it. Add a ./dist directory where our code can be read from once it’s published. To help with that, we’re going to use the neat little library I mentioned called rollup.js.

It comes with some dependencies, so enter your terminal again, then add them in.

yarn add -D rollup rollup-plugin-delete rollup-plugin-typescript2

Great… Wait, so what are we going to ask rollup to do? Well, allow me to show you.

Create a file name rollup.config.js and add the following:

 

Here we add our input, which is our index.ts file. We can then select where we want to output our transpiled files to. Two files are then generated in the ./dist folder, while at the same time anything that was previously there is deleted.

Now this is an important bit. Don't be like me and spend several hours wondering why you can’t import from your component-factory later on down the line. Instead, ensure that you add the main and module keys required to your package.json , and then update your scripts to include the following:

{
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
}
"scripts": {
"build": "rollup -c"
}

Give it a whirl. Hit up your terminal and run npm run build. Check the ./dist folder you’ve created. You should see your transpiled files, ready to be published.

Ink the Press! It’s Time to Publish!

Let’s put it out into the big, bad world. You can do this via a GitHub repository, but for the purpose of this piece, we’re going to publish it via npm.

First, you need to have an npm account. Create one if you don’t have one yet.

Second, you need to login to your npm account through the command line. Jump back into your terminal for one last Hurrah! Enter npm login and put in the credentials you’ve used while signing up for an account.

There are a few tools here you can try. For example, change your package name and try npm search to search if the name has been used anywhere. That’s useful when you’re trying to come up with quick and memorable names for your package.

Once you’re happy with the name, tell npm to publish your package with npm publish. Then your package will be available to install on import via npm.

You’ve just created a component library that’s ready to share and distribute across your applications.

High five! Pat yourself on the back. Turn on the kettle or grab a beer from the fridge.

You’ve done good, kid!


Leave a comment


Please note, comments must be approved before they are published