概要
このブログポストではYarn
のWorkspaces
を使ってモノレポを構成する方法について紹介します。
ブログシリーズ
このブログはシリーズで作成されました。次のリンクを通じて他のブログポストも確認してください。
- [プロジェクト管理] リポジトリ戦略
- [JavaScript] モノレポ(Monorepo)のためのツール
- [Monorepo] NodeJS のモジュールの読み込み
- [Monorepo] Symlink
- [Monoepo] Yarn Workspaces
- [Monoepo] Yarn Workspaces の依存性の Hoisting
- [Monoepo] Yarn Workspaces のコマンド
- [Monoepo] 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で開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。