Angular Mono-Repo using Lerna and Yarn Workspaces(for reusability)

GREAT CODERS are those who believe in reusing rather than rewriting. So lets see, why and how to use reusable code by creating mono-repository (mono-repo) and specially creating it for Angular apps.
What is Mono-Repo?
Mono-Repos is the place or a way we keep many similar repositories of different applications together and manage it from a single source. With this we can achieve reusability, code sharing, code refactoring. It also gives a good level of collaboration across teams.
When to use Mono-Repo?
In large scale enterprises projects, where we have different applications where we have lots of commonalities in terms of components then we can use this approach. For example, there is a project with applications like customer portal and supplier portal, where UX is similar jst with some minor changes in components and major changes in access.
Who uses Mono-Repo?
A lot of companies and open source projects. The most interesting:
- babel [Community driven]
- create-react-app [Facebook]
- msal.js [Microsoft]
What is required to create Mono-Repo for Angular Apps?
- Yarn workspaces: It is used for better management of node-modules across apps.
- Lerna: For creating different application, library and managing them and sharing resources between each other
- Angular CLI: To create angular projects and applications

How to create this Mono-Repository for Angular Apps?
1. Enable yarn workspaces:
yarn config set workspaces-experimental true
2. Create angular project
ng new lerna-demo — create-application=false
3. Delete the package-lock file (which is created by angular cli) as we will be using yarn and not npm
4. Add lerna as dev dependency and initalize it
yarn add lerna — save-dev
lerna init — independent
5. Modify lerna.json for the project as below:

Here,
projects is the packages folder where we will add all our apps or libraries
version is kept independent as we can manage packages independently and publish it
6. Add package installer to the dev dependencies if you want to use library else you can skip this step
yarn install ng-packagr tsickle — save-dev
7. Update package.json and add following key in the file so that workspace is defined.

8. Add library in the repository and modify its package file along with adding packaging configuration
ng g lib shared

9. Now lets create application in the repository. Add package.json in the app folder and add scripts for serve, test, lint and build
ng g app app-one

10. Add following scripts in the root package json file. So that root file can control all other projects

11. Now you need to build the angular library so that you can add it as a dependency in your applications
yarn run build-lib
lerna add shared
12. You need to install all the dependencies required by apps and libraries using below statement:
lerna bootstrap
13. To use library in the app of the project. Open app.module.ts file from . app-one,
and add import statement
and declare the module

Now that final step is done. You can create and use the components, services, directives, pipes, interceptors or any other feature of library as any other module you import inside any of your application.

PROS:
- Similar packages required in multiple applications can be stored together in the root node_modules
- All the dependencies for all the applications can be installed or updated using single command
- It lets you run build or tests on all the applications using single command
- Common functionalities can be separated and shared using library
- Mature and plenty of tutorials around the web.
- Version all packages separately or in a single line.
- Link dependencies in the project with lerna bootstrap.
- Automation for task execution for all packages in the repo.
- Lerna publish publishes all updates to NPM.
CONS:
- You need to rebuild the library every time you make any change
- Heavy refactoring for the repository. A lot of initial overhead.
- Maintenance overhead grows with different package.json and environments for every package.
- Discoverability for packages relies on NPM/library’s docs.
- PRs can only be made in the repo, and it can be hard to onboard new developers into the repo, which in turn impairs adoption of packages
You can find the repository example for this Mono Repo at https://github.com/MayuriRathod/Angular-MonoRepo
For further reading about lerna or mono-repo you can refer to below links:
https://medium.com/naresh-bhatia/sharing-ui-components-with-lerna-and-yarn-workspaces-be1ebca06efe
https://medium.com/mitterio/multirepo-to-lerna-js-monorepo-80f6657cb443
