This content originally appeared on Level Up Coding - Medium and was authored by Viduni Wickramarachchi
Monorepo Solutions in 2021
Easily manage your Monorepo with these tools
A Monorepo is a single repository where you store all the code that belongs to a project. For example, a Monorepo will include the website code and mobile app code in one place. However, it differs from a monolithic application as the modules are placed with clear boundaries within the repository.
And, for anyone starting with Monorepos, proper tooling is the key to avoid known pitfalls. So let’s take a look at some of these tools to find the best for your use case.
1. Bit
Bit is one of the best tools available for Monorepos out there. It attempts to avoid most of the challenges that appear with Monorepos by introducing some fundamental changes to the way you structure your code. One such change is;
Bit automatically isolates the components from the project, including their dependencies.
You might wonder, what’s so special about it, right? Just think for a moment, if you can arrange your Monorepo as a collection of components,
- Grouped by your choice into multiple collections.
- Shared across these groups (with fully-managed dependency versioning).
- Able to track the dependencies and test them automatically upon changes for the entire dependency tree.
- Teams can collaborate on these components in parallel for better productivity.
- Even able to share components beyond the Monorepo.
That’s the power of Bit. You can also use it to build modular apps, design systems, author and deliver micro-frontends, and even share components between applications.
However, if you are new to Bit, it might take some time to familiarize these concepts. So the best way to fast track is to try it out. You can start step by step using the following guide.
If you like to dig deeper into its full capabilities, refer to the following article.
Monorepos Made Simpler with Bit
2. Bazel
Google is one of the many large companies that adopted Monorepos at an early stage. Bazel is Google’s Monorepo-oriented build system. Most Monorepo tools only support JavaScript, however, Bazel goes beyond that.
Bazel showcases itself using the tagline “{Fast, Correct} — Choose two”, which I would say is pretty accurate. Bazel makes builds extremely fast and can handle very large builds spending a little amount of time. This is achieved by running distributed builds. This is a key feature in Bazel.
Some features of Bazel
- Fast and Correct — Just like their tagline says!
- High-level build language — Offers a human-readable definition language
- Supports multiple languages such as JavaScript, Java, Go, C+, etc. (which is not offered by most build tools)
- Can run on parallel machines
- Scalable — Capable of building and testing at scale and supports large codebases
- Deterministic incremental builds
- Builds are sandboxed — Offers hermeticity (If a build rule is not declared to depend on a particular file, it will not be able to open that file)
- Builds outputs for multiple platforms
Bazel leverages both local and distributed caching along with dependency analysis to rebuild only the parts of the build that were affected due to new changes. I find this more efficient than the mechanisms used by most other tools. Further, Bazel continues to strike for efficiency by determining out-of-date artifacts by using content digests instead of timestamps when it creates dependency graphs. What does this achieve?
It helps avoid unnecessary rebuilds of targets and enables predictable builds even when distributed across multiple hosts. Since Bazel uses content digests, it's able to cache intermediate build step outputs and reuse them when necessary.
The language used to define new rules in Bazel is called Starlark. It is inspired by the Python 3 syntax but does not include all Python features. Bazel is available for macOS, Ubuntu, Fedora/CentOS, and Windows.
How does Bazel work?
- Loads the build files relevant to the defined target
- Then it analyzes the inputs and their dependencies apply the specified build rules and produces an action graph
- Finally, the build output is produced by executing build actions on the inputs.
Who uses Bazel?
Major companies like Google, Dropbox, Huawei, Stripe, Braintree, etc. uses Bazel. Google scaled up its Monorepo as the company grew. By 2015 the Google Monorepo had 86 terabytes of data with 2 billion lines of code. Uber built their Go Monorepo with the use of Bazel. Detailed information as to how they did it can be found here.
3. Lerna
Lerna is a tool that optimizes the workflow between multiple packages in a JavaScript-based Monorepo with Git and NPM. Lerna integrated with popular frameworks and languages such as TypeScript, React, Angular, Babel, etc.
What can Lerna achieve?
- Helps to deal with semantic versioning — Let’s say you have a number of modules in your Monorepo that use the same package. Incrementing the version of this would require you to run the same command across all modules. With Lerna, this can be simplified as you can update the version of the same package across all modules at once.
- Helps setting up build workflows
- Enables to push packages easily
- Allows linking dependencies between projects — If project A is dependant on project B, it is possible to have shared dependencies and test both projects together. This will not affect other projects in the Monorepo which does not have a direct dependency
Using Lerna commands
- lerna init — Create a new Lerna repo or upgrade an existing repo to the current version of Lerna. This can either be done in fixed/locked mode or independent mode. To initiate Lerna in the independent mode, the flag --independent will have to be used
- lerna bootstrap — Ties together the packages in the current Lerna repo by installing their dependencies and linking cross-dependencies, if any.
- lerna publish — Creates a new release of the packages that were updated.
- lerna changed — Checks which packages that changed since the last release
- lerna run <script> — Runs the specified script in each package that has the script
- lerna ls — Lists all public packages in the current Lerna repo
You can define all your Lerna configurations in the lerna.json file. A sample file would look as follows.
{
"packages": ["packages/*"],
"npmClientArgs": ["--no-lockfile"],
"version": "independent",
"command": {
"version": {
"ignoreChanges": ["*.md"],
"npmClient": "npm",
"message": "chore(release): publish"
},
"publish": {
"npmClient": "npm"
}
}
}
Usually, we use a yarn build or yarn lint to build or run lint commands in our applications. Since a Monorepo has multiple applications, we can use Lerna instead of yarn . An example build script that will build every module in the Monorepo would be lerna run build --stream . The --stream flag will display the build output in the terminal.
Lerna also has a GUI which takes you through the steps required to set up a Lerna Monorepo and the related activities. This is called the lerna-wizard. According to synk.io trend statistics, Lerna is very popular among a lot of developers.
4. NX
NX provides a set of dev tools for Monorepos. It emphasizes modern full-stack web technologies. It is a TypeScript based Monorepo tool. It provides,
- A workspace
- Command-line interface
- Cloud-based computation caching
- Great language level IDE support
Nx helps set up the build pipeline of the Monorepo and provides other tools to aid the development process too. It provides a guide to share code between your modules to make it easier to share code.
Similar to Bazel, Nx also analyzes the repo to identify which modules were affected by a certain change and builds, runs, tests only the affected modules. This identification is done using the affected command. This is an efficient way to run builds, especially if you have a large number of shared libraries within your modules. Nx’s guide to share code is rather opinionated. However, this comes in handy if a large number of developers are involved in the development process. While some may not like an opinionated guide, in some cases, this might be efficient and useful.
Adding Nx to an existing Monorepo is quite easy. It can be done by just using one command, npx add-nx-to-monorepo . If you are interested in learning this process, refer to this article.
5. Yarn Workspaces
yarn as you all know is a JavaScript dependency management tool. It supports Monorepos through Workspaces. Workspace is also a package with a set of build rules and has its own package.json .
Yarn Workspaces have the following features.
- Shared node_modules for all your packages in the Monorepo.
- A single lock file (e.g.: yarn.lock ) for all packages
- Provides dependency symlinking to allow local development of packages
- If you need to update dependencies for only one package, you can achieve that by using the -focus flag. This is called focused dependency update.
- Can easily integrate with Lerna — In such a scenario, Yarn Workspaces will handle installation/symlinking while Lerna will handle publishing and version controlling.
Yarn Workspaces can install and update dependencies of all packages in your Monorepo with a single command.
For more information about how to use Yarn Workspaces, you can refer to their official documentation.
With yarn workspaces, it is very easy to create new packages. The code becomes more modular and elegant. We save a lot of disk space and also speeds up package installation processes.
TL;DR
In this article, we discussed different Monorepo solutions. The solutions we explored above helps you easily manage your Monorepo in various ways. Most of these solutions help mainly with dependency management across multiple modules without having to go through a lot of trouble.
- Bazel — Enables fast and correct distributed builds in Monorepos
- Lerna — Optimizes the workflow between multiple packages in a Monorepo
- Bit — Shareable component library across the Monorepo modules
- Nx — Provides dev tools for Monorepos
- Yarn workspaces — Enables installation and symlinking of packages across the Monorepo modules with a single command
Let’s have a look at a comparison of these tools.
Further, most of these tools have the capability to be integrated with each other too. For example, Bit + Yarn Workspaces, Lerna + Yarn Workspaces, etc.
Thanks for reading!
Different Monorepo Solutions in 2021 was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Viduni Wickramarachchi
Viduni Wickramarachchi | Sciencx (2021-09-07T17:25:14+00:00) Different Monorepo Solutions in 2021. Retrieved from https://www.scien.cx/2021/09/07/different-monorepo-solutions-in-2021/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.