Contents
Outline
In this blog post, I will introduce how to create a monorepo using PnpM
.
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
PnpM
PnpM
is one of the NodeJS package managers, and it is similar to NPM
and Yarn
. PnpM
emphasizes fast installation speed and space saving. It is used in various projects.
install PnpM
You can install PnpM
using the following command.
pnpm -v
If PnpM
is not installed, run the following command to install PnpM
.
npm install -g pnpm
Example
After installing PnpM
, let’s use PnpM
to create a monorepo. To create a monorepo, create the following folder and file structure.
.
├── package.json
└── src
├── module-a
│ ├── index.js
│ └── package.json
└── module-b
├── index.js
└── package.json
The package.json
file of the module-a
is as follows.
// src/module-a/package.json
{
"name": "module-a",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
The package.json
file of the module-b
is as follows.
// src/module-b/package.json
{
"name": "module-b",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
And, the index.js
of the module-b
is as follows.
// src/module-b/index.js
console.log('module-b');
Finally, the index.js
of the module-a
is as follows.
// src/module-a/index.js
console.log('module-a');
require('module-b');
After configuring the files like this, run the following command to check if the module is loaded correctly.
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' ]
}
pnpm-workspace.yaml
To create a monorepo using PnpM
, you need a pnpm-workspace.yaml
file. Create a pnpm-workspace.yaml
file in the root folder and modify it as follows.
packages:
- 'src/*'
Install dependencies
module-a
uses module-b
, so you need to add module-b
as a dependency in the package.json
file of module-a
. To add a dependency, open the src/module-a/package.json
file and modify it as follows.
{
"name": "module-a",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"module-b": "workspace:*"
}
}
After modifying the package.json
file, install the dependencies by running the following command in the root folder.
pnpm install
After then, when you check the folder structure, you can see that a Symlink
to module-b
is created in the node_modules
of module-a
.
.
├── node_modules
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
└── src
├── module-a
│ ├── index.js
│ ├── node_modules
│ │ └── module-b -> ../../module-b
│ └── package.json
└── module-b
├── index.js
└── package.json
For more information about Symlink
, please refer to the following link.
Check
Now that you are ready to use PnpM
for the monorepo. Run the following command to check if the modules are loaded correctly.
pnpm module-a start
Then, you can see the following output.
module-a
module-b
You can use the following command because a Symlink
to module-b
is created in the node_modules
of module-a
.
node ./src/module-a
module-b
has no dependencies, so you can run the following command without any problems.
pnpm module-b start
# module-b
node ./src/module-b
# module-b
Completed
Done! We’ve seen how to create a monorepo using PnpM
. If you are using PnpM
instead of Yarn
, please refer to this blog post to create a monorepo using PnpM
.
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.