Monorepos anyone...?

I have a fairly complex app that actually consists of three separate Meteor apps and a bunch of Meteor packages shared by all those three apps. It gets painful when you have to…

  • Make a hotfix to the master branch
  • Switch between feature branches
  • Do any kind of non-linear work with the codebase

…because it typically means checking out the corresponding feature branch on each and every app and package, possibly updating any changed npm-dependencies that have changed etc… and when I make a release, I end up tagging and fiddling with branches more than is healthy. It becomes quite tiresome pretty fast.

:point_right:t2: I think I’m going to switch to some kind of a monorepo.
:point_right:t2: What else can I do to alleviate the pain?

Any experiences, help or helpful tips for this transformation, anyone?

1 Like

Have you tried git submodules? We had the same problem but with submodules they’re gone. Submodules are annoying at times themselves, but less so than the alternative

I have in the past, but I remember making a mental note to myself saying “STAY AWAY” . What is your Git flow with submodules when…lets say, you are working on a new feature in a separate feature branch, but suddenly you get alerted to a bug and need to create and deploy a hotfix?

I use a monorepo that has a set of base packages that are symlinked into the package directories of a couple of different apps. I’m fairly happy with with how easy it is to make changes and deploy quickly.

Couldn’t you just add the directory containing the packages into the METEOR_PACKAGE_DIRS environment variable, instead of symlinking?

That would work too.

  1. Stash / commit in the submodules, stash / commit in base
  2. Switch to trunk, git submodule update
  3. Create new branch(es) and do work
  4. Deploy
1 Like

We use submodules extensively for our local packages and they are a huge pain
If there’s anything better, I would love to hear it.

Is it possible to manage versions with METEOR_PACKAGE_DIRS?
We often have to maintain older apps with much older, or specific forks of packages that would break if they built with the latest versions

I’m working with 4 Meteor apps inside a mono repo and with more than 8 packages inside this mono repo too using METEOR_PACKAGE_DIRS to resolve them and a vendor package to declare versions for NPM dependencies only in one single place.

Also you can migrate to mono repo easily, keeping current branches and without losing any history from git (if you need help with this, I can help). When I join my current company they were not using mono repo and I did the migration in the first day and now everybody loves it. For me there is no sense to have a single product (can be composed by multiple apps) in multiple repositories. Mono repo is the way to go.

If you need help or more details let me know! I’m procrastinating to write a blog post about it but I can write it asap if it can help others now :slight_smile:

I have done this process of split repos and unify repos many times.

4 Likes

This would be very much appreciated! If there’s any gotchas or shortcuts, I’d rather read about them beforehand than discover them by myself.

1 Like

I agree, monorepo and shared packages with METEOR_PACKAGE_DIRS is absolutely the way to go. Everything else we tried was incredibly annoying.

I’ll write a blog post about that and I’ll post here :slight_smile:

Here we go

How to migrate to Mono Repository without losing any Git history

Please provide feedback :slight_smile: If you have any question ask me on Twitter FilipeNevola

6 Likes

Love how simple Git makes this. Thanks!

What’s the advantage/difference between METEOR_PACKAGE_DIRS and symlinks?

We run tests with non-meteor test-runners who would probably not be able to pick up on those packages if we don’t symlink them in the right place

Symlinks prepared in a small bash script sounds at least as reasonable no?

Main advantage for us is that you don’t have to have a bunch of symlinks, you just set an env variable pointing towards a single folder. We have dozens of shared packages, so managing all those symlinks would quickly get tedious.

Another thing to consider:

How much code do you really need to share by using packages / libraries? Sometimes redundancy is not a bad thing, especially when microservices are involved.

Sharing a library means hard coupling code / deps. I am not saying you should avoid libraries, this is just a minor comment to think about.

We have a big mono repo, however only one Meteor app. Basically we have tons of “plugins” that provide functionality, and these are all NPM packages (although currently we don’t publish them to NPM, API still too unstable). We have tried a bunch of approaches, currently we use yarn workspaces, which works great, and symlink them into the Meteor app to have Meteor do the babel etc (we did this externally before). You can check out our setup here: https://github.com/chili-epfl/FROG.

The only pain point is that Meteor doesn’t fully support yarn workspaces, because it refuses to look one directory up for a node_modules directory, so we do some automatic symlinking to get around this.

The only pain point is that Meteor doesn’t fully support yarn workspaces, because it refuses to look one directory up for a node_modules directory, so we do some automatic symlinking to get around this.

Hi houshuang,

I’m curious how you’re deploying this project with the symlinked packages. I’ve had issues in the past where some packages are symlinked but the meteor build package did not include those symlinked paths. The application is then broken upon deploy.

1 Like