yarn workspacesでmonorepoを構成しているときに特定のpackageだけhoistの対象外にしたいというときがある。
そういうときにどうすればよいかというと、noHoistオプションを単に使えばいいのだけどなぜかちゃんと書いてあるつもりなのにnoHoistが効かなくて困り果ててしまうケースがある。
このnoHoist設定は実はめちゃくちゃややこしく罠しかないので覚書として書いておく。
nohoist in Workspaces | Yarn Blog
結論から
noHoistにはディレクトリパスではなくパッケージ名のglobを書かねばならない
です。
それでは順を追って見ていきましょう。
packageの名は
こういうmonorepo構成だったとする。このうちfun-utilsだけはhoistの対象にしたくないのでnoHoistしたいとする。
. ├─package.json └─packages ├─fun-domain ├─fun-interfaces └─fun-utils // hoistしてほしくない
そしてpackages/fun-utilsのpackage.jsonはどうなっているかというとこう。
{ "name": "smile-utils", "version": "1.0.0", "dependencies": { "cross-env": "5.0.5" } }
おや?ディレクトリはpackages/fun-utilsなのにpackgae.jsonのnameフィールドは「smile-utils」ですね。
でもまあpackagesのフィールドはディレクトリなわけだし、普通こう書いてしまいますね。
"workspaces": { "packages": ["packages/*"], "nohoist": ["**/fun-utils", "**/fun-utils/**"] }
noHoistにディレクトリ名ベースのglobを書いた
ただこれではnoHoistの対象になりません
どうすればよいか。
"workspaces": { "packages": ["packages/*"], "nohoist": ["**/smile-utils", "**/smile-utils/**"] }
nameフィールドのglobに変えた
noHoistは実はpackage.jsonのnameのglobにしないといけなかったのです……。
ちなみに
1度rootで yarn install してあり、すでに各パッケージにlockファイルとnode_modules存在する状態からnoHoistの指定する場合は、noHoist対象node_modulesとyarn.lockを削除しておかないといけないことを確認しています(v1.22.4)
yarn install --force でもダメなので注意しましょう……。
😇