概要
今回のブログポストではPnpM
を使ってモノレポを作る方法について説明します。
ブログシリーズ
このブログはシリーズで作成されました。次のリンクを通じて他のブログポストも確認してください。
- [プロジェクト管理] リポジトリ戦略
- [JavaScript] モノレポ(Monorepo)のためのツール
- [Monorepo] NodeJS のモジュールの読み込み
- [Monorepo] Symlink
- [Monoepo] Yarn Workspaces
- [Monoepo] Yarn Workspaces の依存性の Hoisting
- [Monoepo] Yarn Workspaces のコマンド
- [Monoepo] PnpM を使ってモノレポを作る方法
PnpM
PnpM は NodeJS のパッケージマネージャの 1 つで、NPM
、Yarn
と同じ役割をします。PnpM
は高速なインストールとスペースの節約を強調し、さまざまなプロジェクトで使用されています。
PnpM のインストール
次のコマンドを使ってPnpM
がインストールされたか確認します。
pnpm -v
インストールされていない場合は、次のコマンドを実行してPnpM
をインストールします。
npm install -g pnpm
例題
PnpM
をインストールしたら、PnpM
を使ってモノレポを構成してみましょう。モノレポを構成するために、次のようなフォルダとファイル構造を作ります。
.
├── package.json
└── src
├── module-a
│ ├── index.js
│ └── package.json
└── module-b
├── index.js
└── package.json
module-a
のpackage.json
は次のようになります。
// src/module-a/package.json
{
"name": "module-a",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
module-b
のpackage.json
は次のようになります。
// src/module-b/package.json
{
"name": "module-b",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
}
}
そしてmodule-b
のindex.js
は次のようになります。
// src/module-b/index.js
console.log('module-b');
最後にmodule-a
のindex.js
は次のようになります。
// src/module-a/index.js
console.log('module-a');
require('module-b');
このようにファイルを構成した後、次のコマンドを実行してモジュールを正しく読み込むか確認します。
node src/module-a/index.js
すると、次のようにエラーが発生することが確認できます。
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
PnpM
を使ってモノレポを構成するためには、pnpm-workspace.yaml
ファイルが必要です。ルートフォルダにpnpm-workspace.yaml
ファイルを作成し、次のように修正します。
packages:
- 'src/*'
依存性のインストール
module-a
がmodule-b
を使ってるので、module-a
のpackage.json
ファイルにmodule-b
を依存性として追加する必要があります。依存性を追加するためにsrc/module-a/package.json
ファイルを開き、次のように修正します。
{
"name": "module-a",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"module-b": "workspace:*"
}
}
ファイルを修正したら、ルートフォルダで次のコマンドを実行して依存性をインストールします。
pnpm install
その後、フォルダ構造を確認すると、次のようにmodule-a
フォルダ内のnode_modules
にmodule-b
のSymlink
が作成されていることが確認できます。
.
├── 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
Symlink
に関する詳細は次のリンクを参照してください。
確認
これでPnpM
を使ってモノレポを使う準備が整いました。次のコマンドを実行してモジュールを正しく読み込むか確認します。
pnpm module-a start
すると、次のように正常に実行されることが確認できます。
module-a
module-b
module-a
のnode_modules
にmodule-b
のSymlink
が作成されたため、次のコマンドを使用することができます。
node ./src/module-a
module-b
は依存性がないため、次のコマンドを実行すると問題なく実行されることが確認できます。
pnpm module-b start
# module-b
node ./src/module-b
# module-b
完了
これでPnpM
を使ってモノレポを構成する方法について説明しました。Yarn
を使わずにPnpM
を使っている場合は、このブログポストを参考にしてPnpM
でモノレポを構成してみてください。
私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!
アプリ広報
Deku
が開発したアプリを使ってみてください。Deku
が開発したアプリはFlutterで開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。