概要
このブログポストではYarnのWorkspacesを使ってモノレポを構成する方法について紹介します。
ブログシリーズ
このブログはシリーズで作成されました。次のリンクを通じて他のブログポストも確認してください。
- [プロジェクト管理] リポジトリ戦略
- [JavaScript] モノレポ(Monorepo)のためのツール
- [Monorepo] NodeJS のモジュールの読み込み
- [Monorepo] Symlink
- [Monorepo] Yarn Workspaces
- [Monorepo] Yarn Workspaces の依存性の Hoisting
- [Monorepo] Yarn Workspaces のコマンド
- [Monorepo] pnpm を使ってモノレポを作る方法
Yarn Workspaces
前回のブログポストであるモノレポを使うためのツールで JavaScript パッケージマネージャであるYarnのWorkspacesを紹介しました。
今回のブログポストでは実際にYarnのWorkspaces機能を使ってモノレポを構成する方法について紹介します。
- 公式ドキュメント: Workspaces
YarnのWorkspacesは前回のブログポストで紹介したSymlinkを使って複数のプロジェクトを単一のコードベースで管理できるようにしてくれる機能です。この機能を使えば簡単にモノレポを構成できます。
例題
Yarnが提供するWorkspace機能を確認するための例題を作成してみましょう。まず、次のようにフォルダとファイル構造を作成します。
.
└── 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"
}
module-bのpackage.jsonは次のようです。
// src/module-b/package.json
{
"name": "module-b",
"version": "1.0.0",
"main": "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' ]
}
Yarn Workspaces の設定
次はYarnのWorkspacesを使ってmodule-aでmodule-bを使えるようにしてみます。まずルートフォルダ(/)で次のコマンドを使ってYarnのWorkspacesを使えるようにします。
yarn init -y
そうするとルートフォルダに次のような内容を含んだpackage.jsonが作成されることを確認できます。
{
"name": "monorepo",
"version": "1.0.0",
"main": "index.js",
"license": "MIT"
}
YarnのWorkspacesを使うためにはこのpackage.jsonファイルを次のように修正する必要があります。
{
"name": "monorepo",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"workspaces": {
"packages": ["src/module-a", "src/module-b"]
}
}
モノレポは複数のプロジェクトを持っている単一のコードベースであるため、npmレジストリなどにデプロイする必要はありません。そのためprivateをtrueに設定してモノレポがデプロイされないようにします。Yarn V1では必須ですが、Yarn V2からは設定する必要はありません。安全に管理するためにprivateをtrueに設定することをお勧めします。もちろん、モノレポ内の個々のプロジェクトはデプロイできるため、それぞれのプロジェクトはprivateを設定する必要はありません。
Workspacesは配列([])またはオブジェクト({})を設定できます。Yarnではオブジェクト形式で作成することを推奨しています。Workspacesの中にpackagesというキーで配列を作成し、それぞれのモジュールを追加しました。このようにそれぞれ指定してもよいですが、次のように*を使って簡単にすべてのモジュールを指定することもできます。
{
"name": "monorepo",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"workspaces": {
"packages": ["src/*"]
}
}
Yarn Workspaces 確認
これでYarnのWorkspacesを使う準備が整いました。次のコマンドを実行してパッケージをインストールします。
yarn install
するとnode_modulesフォルダがルートフォルダに作成され、Symlinkを使ってそれぞれのモジュールが接続されていることを確認できます。
.
├── node_modules
│ ├── module-a -> ../src/module-a
│ └── module-b -> ../src/module-b
├── package.json
├── src
│ ├── module-a
│ │ ├── index.js
│ │ └── package.json
│ └── module-b
│ ├── index.js
│ └── package.json
└── yarn.lock
これでmodule-aからmodule-bを使えるようになりました。次のコマンドを実行してmodule-aが正しく動作するか確認してみましょう。
node src/module-a/index.js
すると次のように問題なくmodule-aが実行されることを確認できます。
module-a
module-b
もちろんSymlinkで接続されているため、module-bのコードを修正するとmodule-aでも修正されたコードを使うことができます。src/module-b/index.jsファイルを開いて次のように修正します。
console.log('module-b!!!');
そして次のコマンドを実行して修正された内容が正しく表示されるか確認してみましょう。
node src/module-a/index.js
すると次のように修正された内容が正しく表示されることを確認できます。
module-a
module-b!!!
.gitignore
Gitでソースコードを管理している場合、.gitignoreファイルを作成して次のように修正してnode_modulesフォルダをGitから除外するようにします。
# .gitignore
node_modules
完了
これでモノレポを使うためYarnのWorkspacesを使う方法についてみてみました。YarnのWorkspacesは基本的にSymlinkで動作するため、Symlinkについて理解するとよいでしょう。Symlinkについて詳しく知りたい場合は前回のブログポストを参照してください。
皆さんもYarnのWorkspacesを使ってモノレポを構成してみてください。
私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!
アプリ広報
Dekuが開発したアプリを使ってみてください。Dekuが開発したアプリはFlutterで開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。






