Actually, if you use Lerna and you want to use it with YARN, Lerna will simply delegate the package linking to YARN. And in this case, we do specify what are the packages, but when we are doing the installation or we want to link between them, it will install the node modules as if they are normal packages, but under the hood, it will actually link to the folder in the repository where the package is stored.
It works beautifully when you have, when you're working with plain JavaScript. It is slightly less that great if you work with something that requires the build process like a TypeScript or modules, and so on, if you need the babel, then you would need to point to the dist folder and not to the build and make sure that everything is correctly built.
I would like to mention again, some less orthodox way is using the TypeScript path. Instead of specifying what are the packages, you can specify paths of your TypeScript to the different packages and just use them. But it could be a good way if you are using it for application and you're building multiple applications. So not purely mono-repo, but also a possible way.
And the last strategy is about installation. And here I refer to the external modules, to the NPM modules that you want to add in each one of the packages. So some strategies here. You can specify all the packages that you need at your Workspace root. And this is only useful if you're building an application that there is some sort of a bundling process. Otherwise obviously you won't be able to install the other like microservices or other packages because the dependencies will not exist there. But if you're working with the applications and using a bundling, this might be a good way. You will have less problems trying to upgrade, less mismatches between versions. And this could be useful.
But if you go to the more traditional way, meaning each package has its own package and has a set of dependencies, then the first option is to do a local install. Which means that you have the dependencies, and under each package you have a node modules and it is going to be installed there. And then you make sure that you can have different versions for different packages. It makes it very autonomous.
Another option, and again, the package manager support this, is doing a hoisting. Which means everything is still defined at the package level, but when it is being installed, it is actually installed under a single node model at the root, unless there are version mismatches. And the reason this works is because when node is searching for a package, it will just go up the tree and try and find the package somewhere higher in the hierarchy. The risk here is that you forgot to add some package in one of your packages and then when you and you won't get any problem during testing or during the local development because it is stored somewhere because of another package. But then when you go to deploy just this package on your production machine or standing machine, you might get some errors and there are linked rules. There's an ESLint rule that is verifying this. So we don't have to rely on our memory and brain power.
So to sum it up, if we want to go with the monorepo, first we need to understand what is the scope, what do we want to put in our monorepo? It doesn't have to be all of the code. Then we want to define what are the strategies that we are going to use for the release, the build, the development process, how we are going to link the different packages and what is our installation method.
Comments