Outline
When connecting the dependencies of various modules in Monorepo, Symlink
is used. In this blog post, I will explain Symlink (Symbolic Link)
, which is the basic knowledge for understanding Monorepo.
Blog Series
This blog is a series. Please check other blog posts through the following links.
- [Project Management] Repository Strategy
- [JavaScript] Tools for Monorepo
- [Monorepo] Node JS module resolution
- [Monorepo] Symlink
- [Monoepo] Yarn Workspaces
- [Monoepo] Dependency Hoisting of Yarn Workspaces
- [Monoepo] Command of Yarn Workspaces
- [Monoepo] Creating a Monorepo with PnpM
Symlink
Symlink
is an abbreviation for Symbolic Link
, and you can think of it as a shortcut (System shortcut)
for a file
or directory
.
Symlink
is a basic feature supported by major OS (macOS, Windows, Linux). In addition, it is also supported by npm
and yarn
, which are package managers for JavaScript.
Example
Let’s create an example to check the Symlink
feature provided by npm
and yarn
. First, create the following folder and file structure.
.
└── src/
├── module-a/
│ ├── index.js
│ └── package.json
└── module-b/
├── index.js
└── package.json
The package.json
of module-a
is as follows.
// src/module-a/package.json
{
"name": "module-a",
"version": "1.0.0",
"main": "index.js"
}
The package.json
of module-b
is as follows.
// src/module-b/package.json
{
"name": "module-b",
"version": "1.0.0",
"main": "index.js"
}
And the index.js
of module-b
is as follows.
// src/module-b/index.js
console.log('module-b');
Finally, the index.js
of module-a
is as follows.
// src/module-a/index.js
console.log('module-a');
require('module-b');
After creating the file structure like this, run the following command to check if the module is imported well.
node src/module-a/index.js
Then, you can see the following error.
module-a
node:internal/modules/cjs/loader:1073
throw err;
^
Error: Cannot find module 'module-b'
Require stack:
- /Users/deku/temp/temp/src/module-a/index.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1070:15)
at Module._load (node:internal/modules/cjs/loader:923:27)
at Module.require (node:internal/modules/cjs/loader:1137:19)
at require (node:internal/modules/helpers:121:18)
at Object.<anonymous> (/Users/deku/temp/temp/src/module-a/index.js:3:1)
at Module._compile (node:internal/modules/cjs/loader:1255:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1309:10)
at Module.load (node:internal/modules/cjs/loader:1113:32)
at Module._load (node:internal/modules/cjs/loader:960:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/Users/deku/temp/temp/src/module-a/index.js' ]
}
Create Symlink
Now, let’s create a Symlink
to check the Symlink
feature. First, go to the module-b
folder.
cd src/module-b
After then, run the following command to prepare to use Symlink
.
npm link
# yarn link
Then, go to the module-a
folder that uses module-b
.
cd ..
cd module-a
After then, run the following command to create a Symlink
for module-b
.
npm link module-b
Then, you can see that the node_modules
folder of the module-a
folder is created as follows, and the Symlink
of module-b
is created in it.
.
├── index.js
├── node_modules
│ └── module-b -> ../../module-b
└── package.json
This Symlink
folder is not a copy of module-b
, but is linked to module-b
itself. Therefore, if you modify the src/module-b/index.js
file, the src/module-a/node_modules/module-b/index.js
file will also be modified. Of course, if you modify the src/module-a/node_modules/module-b/index.js
file, the src/module-b/index.js
file will also be modified.
Check Symlink
Now, go to the root folder (/
) of the project and run the following command to check if the module is imported well.
# cd ../..
node src/module-a/index.js
Then, you can see the following output without any problems.
module-a
module-b
Next, let’s modify the src/module-b/index.js
file as follows.
console.log('module-b!!!!');
Then, when you open the src/module-a/node_modules/module-b/index.js
file, you can see that the modified content is reflected. Of course, if you run the following command, you can see that the modified content is shown well.
node src/module-a/index.js
module-a
module-b!!!!
Completed
Done! We’ve seem what Symlink
is, which is the basic knowledge for using Monorepo. When connecting the dependencies of various modules in Monorepo, Symlink
is used. Therefore, if you understand Symlink
in here, it will be helpful to use Monorepo.
Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!
App promotion
Deku
.Deku
created the applications with Flutter.If you have interested, please try to download them for free.