Lerna comes to our rescue when we are to manage multiple inter-dependent packages within a repository. Have a package that is a dependency of another and you don’t want to waste time building the dependency, publishing it to npm, and then installing it into your package? Then, Lerna can get behind the wheel for you and let you use your dependency package within your main package by completely eliminating the need to publish it. Lerna accomplishes this by creating a symlink of your dependency inside your main package’s node_modules
folder.
However, since Lerna creates a symlink of your dependency package, which we shall refer to as a module henceforth, the node_modules
directory of your module also gets referred to from your main package’s node_modules folder. This may not usually cause problems but certain libraries don’t take kindly to having multiple copies of it in the node_modules
directory.
Say, we use a library called A in both the module and our main package. The node_modules
directory of our main package will already have a copy of library A. In addition, the node_modules
directory of our module which is referenced to from within the node_modules
directory of our main package will also have library A. In effect, the node_modules
directory of our main package will have two copies of library A. This may not be a problem but libraries like React throw an error when there are duplicates.
To demonstrate this, I have created the following monorepo.
The monorepo contains two packages viz., sample_one
and sample_counter
. The sample_counter
is a module that implements the cliched React component that increments a counter on button click. The sample_one is the main package that imports this module and uses this in its React app. I have installed and configured Lerna so that the sample_counter
module is symlinked from the sample_one
app.
When I run this app, React throws an error called "Error: Invalid hook call"
as shown below.
The reason is the third mentioned reason: “You might have more than one copy of React in the same app”. This is because of the way Lerna manages the packages in our monorepo and there is nothing Lerna can do to resolve this. So, what’s the escape hatch?
Enter Yarn workspaces. Yarn workspaces use a completely different strategy to manage dependencies in a monorepo. While doing all that Lerna does in managing dependencies, Yarn workspaces, additionally, ensures only one copy of a library is found inside a package. This resolves the issue we get when we use React.
To get started with Yarn, you first need to install Yarn. Then, modify the lerna.json file by adding a new key called “useWorkspaces”
and set it to true.
{ "packages": [ "packages/*" ], "version": "0.0.0", "useWorkspaces":true }
Once that’s done, then declare the packages in the monorepo by passing the list of packages as an array into a key called “workspaces”
in the package.json
file. You can individually declare all the packages or, as in my case, if your packages all reside in a directory called packages, then you can simply use “packages/*”
to add all your packages. Finally, set the “private”
key to true because the repository should be private if yarn workspaces is to work.
{ "name": "lernaYarnWorkspaces", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "lerna run build", "prebuild": "yarn" }, "workspaces":["packages/*"], "keywords": [], "author": "Theviyanthan", "license": "ISC", "dependencies": { "lerna": "^3.18.5" }, "private": true }
Once you complete the above configurations, then run yarn
or yarn install
to install the dependencies. Now, when you run the app, you will see that the app runs fine.
You can obtain the sample repo here.
The previous article discussed transferring knowledge from one completed problem to a new problem. However,…
Memetic automatons leverage knowledge gained from solving previous problems to solve new optimization problems faster…
This article discusses how we can use data to automatically select the best meme from…
Memetic computation is an extension of evolutionary computation that combines the use of memes and…
Evolutionary algorithms are heuristic search and optimization algorithms that imitate the natural evolutionary process. This…
Mininet is a popular network emulator that allows us to create virtual networks using virtual…