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
- [Monorepo] Yarn Workspaces
- [Monorepo] Dependency Hoisting of Yarn Workspaces
- [Monorepo] Command of Yarn Workspaces
- [Monorepo] 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.



