最終更新: a few seconds ago Remove Netlify-related code from main (grafted, HEAD)
NPM Workspaces を使った Monorepo 化について
Lerna 版の記事はこちらに残してあります
概要
Lerna を使った monorepo はいろいろと問題があり NPM 7 との相性も悪そうなので NPM Workspaces に切り替える。
2021 年 2 月に Workspaces 機能の入った NPM 7.0 がリリースされた。2021 年 5 月リリースの NPM 7.14 辺りから個別パッケージのインストールや削除についてもサポートされており、Lerna の機能のうち大部分は代替できるようになっている。
ただしこの機能が使えるのが NPM 7 以降なので、Node 12 ~ 14 を使っている場合でも NPM だけは 7.14 アップデートする必要がある。
基本的には lerna コマンドを使ってやっていた作業が一通り npm でできるようになる。--scope=... オプションは --workspace=... オプションに変わる(-w でも同じ)。
Hoisting について
モノレポにおける hoist(巻き上げ)とは、複数のパッケージで共通に利用されている dependencies を、個別パッケージごとではなくルートの node_modules に 1 回だけインストールされるようにする操作のことであり、CIRCUS の開発においては必須。これがないと、import React from 'react' した時に実際にインポートされる React が、別の場所にインストールされた別の React になってしまい、それによりフックが動かないなどの酷い不具合に遭遇する。
Lerna では --hoist オプションを明示的に渡す必要があったが、NPM Workspaces では自動で hoist されるので --hoist のようなオプションは不要。ただし NPM 操作は monorepo のリポジトリルートで行うこと。
新しいワークフロー
グローバルに NPM 7.14 以降をインストールする(Node 12, 14 などを使っている場合にのみ必要)
npm install -g npm@latest
# version 7.14 以降であることを確認
npm --version
以下、すべての NPM 操作は monorepo のリポジトリルートで行う。個別ディレクトリ(packages/circus-api 配下など)に cd してから作業をしないこと。
全体の依存物のインストール
npm ci
個別パッケージで何かをインストール
npm install パッケージ名 --workspace=@utrad-ical/circus-api
# または短く
npm i パッケージ名 -w @utrad-ical/circus-api
cd packages/circus-api → npm install パッケージ名 とすると不具合の原因になるので monorepo のルートで行うこと。以下同様。
全パッケージで何かを最新版にアップデート
npm update パッケージ名 --workspaces
複数のリポジトリで使われている依存物をバージョンを同期しながらアップデートしたい場合などに。
あるパッケージから依存を削除する
npm remove パッケージ名 --workspace=@utrad-ical/circus-api
ちなみに Lerna にはこの機能がなかった。
全サブパッケージから依存を削除する
npm remove パッケージ名 --workspaces
個々のパッケージでスクリプトを走らせる
個別にやる場合(単に個別パッケージに cd してから普通に走らせるのでも多分同じ)
npm run スクリプト名 --workspace=@utrad-ical/circus-api
全パッケージで行う場合
npm run スクリプト名 --if-present --workspaces