4
10 Comments

Monorepo

I wonder if someone is using mono-repo in their projects. I used in Angular projects but, I haven't experience in Vue or React projects. If I have to give more details; What did you pay attention to the folder structure and file naming? Also, did you need any tools except the webpack like gulp or rollup? In short, I would appreciate it if you share your experiences.

on January 21, 2020
  1. 1

    I've used a monorepo which consisted of two React packages (one of frontend only, and the other included a simple node server for SSR purposes).

    The cool thing about this setup was being able to use a shared directory which included components/services/whatever that were used in both apps.

    It was written in Typescript and I've created a base tsconfig file, as well as project specific tsconfigs which extended the base one (https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#configuration-inheritance-with-extends). Proper path mapping was also crucial (especially for accessing the shared stuff easily - https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping).

    Each project had it's own webpack configuration.

    In my case there was one, common package.json file with all the dependencies and scripts - but in some cases it might be better to separate them and create one per package.

    App structure (pretty much simplified here) looked like:

    - package.json
    - tsconfig.base.json
    -packages
      - package_one
        - server
        - client
        - webpack
        - README.md
        - tsconfig.json
      - package_two
        - src
        - webpack
        - README.md
        - tsconfig.json
      - shared
  2. 1

    I worked on a React/Node.js app that had the web app and a bunch of our custom node modules all in the same git repo (the app depended on the node modules... and we weren't allowed to publish those node modules anywhere on the Internet). We used yarn workspaces so the app could resolve those dependencies while we were developing, and then had a build that combined everything into a single deployable node project that you could run "yarn install" and "yarn start" on.

    Originally we had each custom node module in a separate git repo and tried to manage it all with git submodules. It became a version-control nightmare until we switched to the monorepo.

  3. 1

    I have a monorepo for my Backend and I'm really happy so far. I put some days of effort into abstracting away my Gitlab CI jobs and my actual modules just extend the base jobs and overwrite their path, so that CI can find the artifacts required for deployment. The advantage is you can do build caching across all your services/modules as they are using the same repo as well as caching of your docker images by recycling some layers in common, much optimization possibilities.

    The biggest advantage for me is to have the core of my project as compact as possible to maintain control over everything all the time, plus the ability to have shared modules without going through an archive repository first.

    My goal is to do infrastructure provisioning within my pipeline (ex. Kubernetes setup, creating some AWS resources) before deploying my services so that I can replicate and reconstruct my whole application at any point in time and setup staging environments easily.

    I'm using Java with Quarkus/Gradle which lets you easily link modules through Gradle Multi Module Projects, with JS it's a different story. Others have recommended lerna, there is also https://bit.dev you can use for Web which lets you upload your components and share them between projects, but this doesn't require having a monorepo

    1. 1

      My goal is to do infrastructure provisioning within my pipeline (ex. Kubernetes setup, creating some AWS resources) before deploying my services so that I can replicate and reconstruct my whole application at any point in time and setup staging environments easily.

      👍 Agree %100

  4. 1

    Lerna (https://lerna.js.org/) works nice for non-Angular JS projects (also node), especially when using Yarn as your package manager.

    There are some cases, however, you may want to consider other approaches:

    • having a React config that is difficult to change – it was tricky to reconfigure WebPack when using the Create React App toolkit (maybe something has changed since then);
    • non-Node back ends – then you'll probably need have a Lerna monorepo within some generic monorepo, also some back-end stacks don't work well with monorepoed front ends;
    • not all CI/CD services work well with monorepoes – instead of building/publishing single packages, it may waste resources on rebuilding unchanged packages if not configured properly (and this configuration can be tedious, especially on CircleCI which I use daily).
    1. 1

      Yeah CI/CD definitely is more complicated when you have a monorepo setup. I've tended to prefer building more monolithic applications instead of starting with microservices which means there's fewer things to deploy on each merge.

      I really appreciate having certain things like dependency versions, lint rules, typescript config, prettier config, etc. all shared throughout the entire repo so to me the extra hassle is worth it, and I figure the extra CI minutes are cheaper than the time it would take for me to manage syncing that stuff manually.

      1. 1

        When it comes to microservices vs monolith, I would always advise starting with monolith until you your application grows. Then you'll know whether something is worth extracting into a separate service. Otherwise, you might find yourself having a set of intertwined and coupled monoliths instead of the microservices you wanted. However, monorepo doesn't always mean microservices – you may just extract commonly used helpers to a separate package.

        When it comes to sharing configs between different repos, you can make another one – the config repository just for the config files that may be imported into each repository, and maybe customized on-the-go. I've seen this pattern quite often in projects that needed to share linter configs between dozens of repositories.

  5. 1

    Take a look at https://lerna.js.org/ we use this in a React project. Its been a while since we set it up but never really had any issues with it.

    There is a list on that link of projects using Lerna to get an idea of folder structure.

    1. 1

      Web applications are structurally different from Node Modules. As far as I know, Lerna is very popular in the use of Node Modules. I also like the folder structure provided by Nx in Angular and React projects. But both of them remain heavy with their cumbersome structures. Nx's never-ending peer dependency issue is complete trouble. I take of care 'nohoist in Workspaces' now.

      Actually, what I want to learn are personal experiences.

  6. 1

    This comment was deleted 3 years ago

    1. 2

      I think it would be. Actually, this is the answer I'm looking for.

      1. 1

        This comment was deleted 3 years ago