Rethinking the “One Ring To Rule Them all” Monorepo manager
Tags: webdev, tutorial, opensource, architecture
Published: 2022-05-06 07:59:53


In this post I stop and rethink whether a single solution to manage _all_ my monorepo needs is the right choice to make or should I go by "the right tool for the job" approach. 

In my recent article (“[Lerna is no longer maintained. Now what? - Part 1](Rethinking the “One Ring To Rule Them all” Monorepo manager)”) I started migrating from Lerna to NX according to the requirements Lerna has in my [Pedalboard](https://github.com/mbarzeev/pedalboard) monorepo.

One comment I got stated this by @guitarino:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpq8aa4yjick6rqv92hh.png) 

Which made me :thinking: … 

My workspaces, though could be managed by Lerna, are managed by Yarn Workspaces which makes a lot more sense and practically works far better. That and the fact I like the idea of the “right tool for the right job” made me go back to the drawing board.

If I go by this idea, why should Lerna or NX take care of running scripts across the entire project where it is clearly the responsibility of the solution managing my workspaces - **Yarn**.

Let’s see if yarn can handle this. A quick Googling and I find this:

https://classic.yarnpkg.com/en/docs/cli/workspaces#toc-yarn-workspaces-run

I’m replacing the NX call with the `yarn workspace run` command and checkiung how it goes.
What I had before is this:

```json
"scripts": {
       "test": "nx run-many --target=test --all",
       "coverage": "yarn test --coverage",
       "lint": "nx run-many --target=lint --all",
       "build": "nx run-many --target=build --all",
       "publish:lerna": "lerna publish --yes --no-verify-access",
       "coverage:combined": "pedalboard-scripts aggregatePackagesCoverage && nyc report --reporter lcov"
   },
```

And I will change it to this:

```json
"scripts": {
       "test": "yarn workspaces run test",
       "coverage": "yarn test --coverage",
       "lint": "yarn workspaces run lint",
       "build": "yarn workspaces run build",
       "publish:lerna": "lerna publish --yes --no-verify-access",
       "coverage:combined": "pedalboard-scripts aggregatePackagesCoverage && nyc report --reporter lcov"
   },
```

Everything works well except the “build” command. It fails because the “components” package does not have a “build” script. That’s a shame, since NX simply overlooked such cases and let them pass.
Let’s see what Yarn has to offer in that case…

Hmmm, it appears that the Yarn `[foreach](https://next.yarnpkg.com/cli/workspaces/foreach)` command knows how to deal with missing scripts.
But this plugin requires Yarn v.2 or above, so let’s do that upgrade real quick, following the instructions [here](https://yarnpkg.com/getting-started/migration):

After we have our Yarn set with the new version we can import the plugin which allows us to use the “foreach” command like so:

`yarn plugin import workspace-tools`

Now I can modify my root project’s `package.json` to be:

```json
"scripts": {
       "test": "yarn workspaces foreach -p run test",
       "coverage": "yarn test --coverage",
       "lint": "yarn workspaces foreach -p run lint",
       "build": "yarn workspaces foreach -ptv run build",
       "publish:lerna": "lerna publish --yes --no-verify-access",
       "coverage:combined": "pedalboard-scripts aggregatePackagesCoverage && nyc report --reporter lcov"
   },
```

The params I’m using for the `build` command are for running in parallel, which still takes the topological order into consideration and resolves dependencies first. The “v” is for verbose. 

I’m checking all of my scripts and everything seems to be working as it did before, minus the need for NX to complete these tasks. Awesome!

This still does not mean I won’t need NX in the future but it makes a lot more sense to keep the concerns of the tools I use separated.

In general I’m not a big fan of “all-in-one” solutions ever since the days of “printer, scanner, copier” in the same hardware device. It really depends on the requirements one might have, but for my slim monorepo I feel that the big role Lerna plays (and plays well, may I add) which actually requires an alternative is bumping and publishing the packages versions.
This is something which NX are currently working on, as my tweet thread elaborates about:

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Fresh from the <a href="https://twitter.com/NxDevTools?ref_src=twsrc%5Etfw">@NxDevTools</a> conf - <br>I&#39;ve asked if they&#39;re going to attend the whole &quot;publish&quot; workflow Lerna has and the answer was that they are currently working on it. They have a few concerns there:<br>👇🏻</p>&mdash; Matti Bar-Zeev (@mattibarzeev) <a href="https://twitter.com/mattibarzeev/status/1520082189093851139?ref_src=twsrc%5Etfw">April 29, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

There are still aspects of NX which excite me, like custom generators, dependencies graph visualization etc. but the choice of the tooling will be done from now on with “the right tool for the job” in mind.

As always, if you know of other means of achieving what's written above, please make sure to share them with the rest of us :)

*Hey! If you liked what you've just read check out <a href="https://twitter.com/mattibarzeev?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">@mattibarzeev</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> on Twitter* :beers:

<small><small><small>Photo by <a href="https://unsplash.com/@pjswinburn?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Philip Swinburn</a> on <a href="https://unsplash.com/s/photos/the-right-tool?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></small></small></small>