31

Monorepo Architecture Simplified With Bit and NPM

 4 years ago
source link: https://www.tuicool.com/articles/hit/6rQnMrI
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Monorepo Architecture Simplified With Bit and NPM

How to leverage Bit + NPM to simplify monorepo architecture, with and without Lerna and friends.

Rzeqiay.png!web

A “Monorepo” is a term used to describe various phenomenons.

A Monolith Application, as utilized by Facebook and Google , means keeping all logically separated projects in a single repository to unify and consolidate all development workflows.

The more common use of “Monorepo” refers to creating a multi-package repository which hosts multiple packages in different directories, each published individually. A common example would be Babel , which leverages Lerna to publish the project’s core ingredients separately as packages.

Do I even need a monorepo?

Most teams would choose to avoid a monorepo when possible, as the advantages of a multi-repo approach often overcome the shortcomings.

In some cases, the overhead of managing shared code and parallel development workflows becomes too much to handle, and questions about monorepos start to rise in the weekly dev team meetings.

In this post we’ll see how using new tooling likeBit you can change the equation, by making it easy to manage shared code across multiple repos or by making it easier to turn any repo into a multi-package monorepo.

Monorepos without overhead

Bit is a growingly popular tool that makes it easier to share, collaborate and sync code between projects. Even though it’s built for a multi-repo architecture, its abstraction and unique features make it a very powerful tool for handling large multi-package Monorepos with NPM .

You can learn more about Bit in a multi-repo architecturehere.

For this post’s sake, let’s see how Bit can be leveraged to turn any repository into a multi-package monorepo without most of the overhead we know today:

  • You don’t have to change a single file or code-line in the repository
  • All internal dependencies are automatically managed by Bit
  • You don’t need to configure every package’s build/test environment
  • Increase the discoverability for the code your share from the repo
  • Enable 2-way sharing and collaboartion between monorepos

Some teams choose to utilize tools like Lerna to handle the core packages within the monorepo. Bit can subtitute Lerna to reduce overhead, or play together with Lerna and/or Yarn workspaces. Here’s a short rundown.

yMRfm2v.png!web

Let’s dive in and review the key features that makes Bit useful for turning any repository into a multi-package repository, with very little overhead.

1. Zero refactoring: any repository is a monorepo

Bit can be used to publish any set of files from any repository as a package, without having to refactor the repository’s source code or file structure. At all.

Instead, Bit can be pointed to the relevant packages (components, modules etc) from the repository, which it will then seamlessly isolate, tag with a version, and wrap with a unique environment.

The isolated components and modules can then be installed with NPM/Yarn in other projects, or imported using Bit itself for further development.

Here’s an example React App on GitHub.

You might have missed it, but Bit was added to this project and was used to make all the UI components in the repo available as NPM packages .

The repository now effectively became a multi-package monorepo, even though not a single file or code-line was changed. You can do the same for your own repository, to save a lot of refactoring time and effort. This is also useful for shared libraries containing multiple shared components/modules.

Original repository:

Shared components:

2. Any set of files is a package (abstraction)

Another useful aspect of Bit is abstraction. Using Bit, you can define the code found in any path in the repository as a reusbale component.

So, you are not bound to “packages” in a specific directory or structure and can easily turn any module, from a core ingredient to thesmallest function, into a package. The repository’s structure will remain intact.

This ability is useful when sharing many components from a single repo, and makes Bit flexible enough to play well with other tools in the ecosystem.

For example, you can combine Bit and Lerna to handle the core packages in the repo and also easily publish and manage hundreds of smaller components.

3. Automatic dependency management

A basic Lerna monorepo structure looks like this:

my-lerna-repo/
  package.json
  packages/
    package-1/
      package.json
    package-2/
      package.json

As you can see, every package requires its own package.json file in which the dependancies for the package are defined and managed.

Bit uses an automatic dependency definition mechanism, which saves a lot of time and effort. Here’s how it works:

bit add
bit.json
package.json

You can learn more about ithere.

When working inside the project and a new component/package version is available, Bit will prompt about it in the bit status command and you can decide what to do about it. In the near future, you will be able to define a pro-active event-driven update strategy. Either way, time and work are saved.

With Bit you don’t have to constantly define and configure the dependency chain for the packages in the repo. Bit does that for you to save overhead.

4. No package-specific build/test configurations

One of the major overhead-generators around a multi-package repo is the environment (build, tests etc.) configurations needed for every packages.

Bit eliminates this overhead by letting you import pre-made environments into the project’s workspace before publishing the components. You can choose environment from thispre-made collection, orcreate/extend your own build and test environments.

Bit uses these environments to build and test every component/module individually in isolation from the project, and the results are presented in the component’s screen in Bit’s web UI.

Based on this process, it can even add more cool features like live rendering for React UI components (interactive example).

uInyAbr.gif

5. Code discoverability

One of the most painful problems when increasing the amount of code you share (packages published) is discoverability. Google spends a good fortune developing internal tools for this purpose alone.

Bit organizes the components and modules you share in a web UI which makes it easier to find components, collaborate, and quickly get key data to make an informed decision when choosing the right components.

These features include build/test results, visualized playground, auto-parsed docs (JSDocs or from the component’s .md file) and usage examples.

When publishing many components from the repository, these features workflow make it easier to quickly learn and utilize the different components in the repository, and also to use them in other projects when needed.

Combined with bit’s versioning and permission control, it can also help standardize the packages published and keep in control.

jy6jQnB.png!web

Bit + Lerna + Yarn workspaces

BzmUzem.png!web

Bit can also be combined with Yarn workspaces and/or Lerna .

Workspaces: Bit + Yarn workspaces is a powerful combination. While Bit will automatically manage dependencies between the packages in the repository, Workspaces will help consolidate and optimize the installation of external packages in the repository. When using Bit in a monorepo, it is actually recommended to combine workspaces to create an optimized workflow.

Lerna: Some teams and projects choose Lerna to manage their monorepo. Since Bit is abstract enough to work in any architecture, it can work hand-in-hand with a Lerna in a monorepo to provide the above advantages on top.

For example, Lerna can be used to manage the core packages while Bit can be used to share all smaller components. Bit also provides discoverability on top of Lerna, and reduces the amount of refactoring and maintenance needed.

Code-sharing between Monorepos

biyAVzZ.png!web

A common use case is when an organizations keeps 2 or more monorepos . Even companies like Twitter and Facebook actually keep more than 1 repo. Some keep 5, and some 40 in the popular repo-per-team approach.

Examples:

  • BackEnd -> FrontEnd
  • MobileApp -> WebApp
  • MonorepoA->SharedLib<-MonorepoB
  • Monorepo per team; multiple repos for multiple teams

In this architecture,Bit is particularly handy as it was designed for a multi-repo architecture. Using Bit, you can make components from one repo available to use in another one.

Components can be installed with NPM or Yarn from Bit’s Node.js registry .

However, they can also beimported with Bit itself. Once imported, the component can actually be developed right from the consuming project!

Changes can be managed and synced usingsimple updates and Bit’s advancedintegration to Git’s merge utility.

As a result, code can be shared, developed and synced from different repositories without being bound by the overhead and limitations of maintaining traditional NPM packages, and control remains in your hands.

Conclusion

Monorepo vs multiepo is a long lived discussion, as each architecture has its pros and cons. By introducing Bit (which is open source) to any of these architectures, you can reduce overhead and scale code sharing. You are welcome to ask questions, share from your experiences or simply give it a try.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK