This content originally appeared on Bits and Pieces - Medium and was authored by Fernando Doglio
3 Lerna Alternatives for Building a Component Library
Lerna is changing hands and who knows what’ll happen to it, here are 3 alternatives you might want to consider instead
A component library is a collection of UI components that you’d want to use for a project. They would all make sense to be used together, either because of the design philosophy behind them, or even because of their common design rules. And when developed, while their internal logic might be independent of each other (i.e the Input component doesn’t need the DateSelector or the DropDownList to work), it makes a lot of sense to have them inside the same repository. After all, while their business logic isn’t meant to be coupled, their styles and internal coding styles might benefit from all of them being inside the same monorepo.
But alas, when you have a group of independent components, all bundled up inside the same project if you’re not careful, things can go really wrong.
So what you’d usually use, is an external tool that would handle things like publishing and versioning your independent components. And for that, you’d usually go with Lerna, a very known and familiar (to many devs) tool that helps in organizing the workflow for developing and publishing a project that contains multiple mini-packages inside.
But what if you don’t want to use Lerna? Which, its creator and main maintainer for years recently passed down the torch to someone else. So what are the alternatives to Lerna that you can try instead of going with a project that could potentially change directions anytime soon?
Let’s take a look!
#1 Bit
The first alternative I want to cover is Bit, an open-source tool (with native integration to Bit.dev’s remote hosting platform) that helps you create and share atomic components. What does this mean? That you can build independent components from scratch or extract sections of your code and share them as independent components on a Bit server (e.g. Bit.dev). This last bit is crucial, because it allows you to extract code from an already ongoing project and extend it and version it as if it was a completely independent 3rd party dependency.
Some of the highlights of Bit are:
- You don’t have to extract the code to share it. You can export a component directly from inside your repository. Bit allows you to identify a section of your code as a component and treat it independently from the rest of your project. This, in turn, helps you simplify the sharing process since you don’t have to set up a separate repo and rework the way you import those files into your project (Bit is most often used as a tool for authoring components from scratch. In that case, the entire project would be a collection of independent components). This is amazing if you already have a monorepo with multiple components and now you want to incorporate Bit into it. You can simply start telling Bit which folders hold which component and it’ll do the rest for you!
- People importing your components (as opposed to just installing them) can also collaborate on them, modify them, and export them back to the registry. This is incredibly powerful if you’re working as a group of teams inside the same organization. That way you’re able to collaborate on the same tool across teams without having to work on a separate project to do it. Importing a Bit component brings down the code and copies it into your working directory (instead of a pesky npm_modules folder where you can’t do anything with it).
Bit is a lot more than a tool for versioning and publishing a component library out of a monorepo. Instead, Bit allows you to centralize everything you’ll do as part of your development workflow, outside of coding, of course.
Let me explain: for a typical workflow you’d code your components, you’d version them in Git, you’d use a bundler to put everything together before testing them, and you’d use some sort of testing library (like Jest, for instance). You’d also use a dependency manager like npm, yarn, pnpm, etc… and probably a few more extra tools.
Bit has commands like “build”, “run”, “test” and so on that wrap all these common actions and allow you to configure and abstract the needs for these tools. Are you building a React component library? Fantastic! Simply set up a default React workspace! Bit will, by default, be configured with a set of these tools for you. But the best part? You don’t need to care until you have to customize them for specific reasons. Otherwise you can simply go through these commands, version your components and share them with the world without even caring about whether you’re using Yarn, NPM or PNPM.
Here is a more detailed article about this particular use case if you’re interested.
#2 Turborepo
Turborepo is a build system for JavaScript-based monorepos. That means this is exactly what you want if you want to avoid going the Lerna route. This tool was built specifically to handle having to deal with multiple projects inside the same code repository.
You can use it to create a brand new multi-project from scratch or add it to an existing monorepo that requires some internal order. Clearly, it’ll always be easier to start from scratch using the create-turbo package (with npx create-turbo@latest ) but we all know that’s not always possible.
Regardless of how you start, you’ll soon get down to configuring build pipelines, which is kind of the core of Turborepo. Your pipelines will determine the build dependency of each environment (like “testing” where you’ll want to make sure there is no real output other than the test results, or “building” where you want to configure the output directory that will be used in production, and so on).
Some of the key aspects of Turborepo that you’ll want to think about when making the decision:
- It’s using incremental builds. This means that you won’t have to build every file in your project if you haven’t modified them since the last time you built them. This is a fantastic time-saver for bigger projects that otherwise would take forever to build every time you make a small change.
- It’s also taking advantage of all your CPU cores. This might seem like a silly thing to highlight, but not every system does take advantage of every core in your CPU, thus missing the performance gained by parallelizing tasks.
- Convention-based config. This one might not be your cup of tea, but I love it. This essentially means that by default, it’ll know pretty well what to do and how to do it. And if you stick to the pre-set conventions, you won’t have to overly configure anything, simply throw some JSON files with a few lines of code, and the tool will do the rest.
There is of course, more to Turborepo, but if this quick description caught your eye, make sure to check it out.
If you liked what you’ve read so far, consider subscribing to my FREE newsletter “The rambling of an old developer” and get regular advice about the IT industry directly in your inbox
#3 Yarn workspace
If you’re not having a very complex multi-package project that requires a lot of orchestration, you might benefit from going with something more “basic”.
Since version 1.0.0, Yarn implemented what they called “workspaces”. This is a mechanism that allows developers to define a single project with multiple sub-packages, some of them even depending on each other.
The two main benefits that workspaces bring to the table are:
- Simplified dependency management. While all sub-projects will have an individual package.json file, they will all be orchestrated at the same time by Yarn (a single yarn install will do for all projects). This in turn simplifies the entire installation process and reduces any potential chance of having conflicting dependency versions.
- Inter package dependencies are easily solved by creating symlinks internally between them. This reduces the duplicated files considerably
You can think about Yarn workspaces as the building blocks for tools like Lerna, in fact, the latter actually merged a PR that updated its internal logic to use Yarn workspaces.
To make workspaces work, simply define them in the root folder’s package.json file inside the workspaces key, like this:
And now, you’ll have to create 3 different folders inside your project’s root, named exactly like that (“one”, “two”, “three”). Each of these folders will contain, in turn, its own package.json file with its dependencies. It’ll be up to Yarn to figure everything out later.
This is definitely a great alternative if you want to keep the tooling at a minimum, because you’ll likely be using Yarn already.
The main difference between Turborepo, Yarn workspaces and Bit is that the latter works as an integral solution. Instead of aiming to be just one more tool inside your already convoluted development workflow, Bit is trying to become the single tool you’ll need to worry about. It’s quite the goal, but based on my tests, it’s doing a very nice job!
Building a component library inside large companies can be really challenging, especially if you’re using a monorepo for it. Don’t get me wrong, it’s definitely not the wrong approach, monorepos have many advantages for this use case, but then again, the tooling is key to success in this situation.
What tools are you using to simplify the building and versioning tasks in your company? Are you going to stick to Lerna for the time being? Or are you trying out new alternatives?
Learn more
- How to reuse React components across your projects
- Building a Composable UI Component Library
- Sharing Components at The Enterprise
3 Lerna Alternatives for Building a JS Component Library was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Fernando Doglio
Fernando Doglio | Sciencx (2022-06-21T08:55:49+00:00) 3 Lerna Alternatives for Building a JS Component Library. Retrieved from https://www.scien.cx/2022/06/21/3-lerna-alternatives-for-building-a-js-component-library/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.