ワークスペース

ワークスペースとは、 Yarn 1.0 から追加された、デフォルトで利用できるパッケージのアーキテクチャを設定する新しい方法です。ワークスペースにより複数のパッケージを設定する際に、 yarn install を一度実行するだけで、それらの全てが単一のパスにインストールされるようになります。

なぜこれがしたいのか?

  • 依存関係は共にリンクさせることができ、つまりワークスペース同士は常に利用可能なコードで最新のものを使用しながら、お互いに依存することができるのです。 これはワークスペースのツリーには影響しますが、システム全体には影響しないため、 yarn link より優れたメカニズムです。

  • プロジェクトの全ての依存関係が一緒にインストールされ、Yarn がそれらをより最適化できる自由を与えられるのです。

  • Yarn は各プロジェクトで異なったものではなく、単一の lock ファイルを使用するので、競合が少なく、レビューもしやすくなります。

使い方は?

以下の記述を package.json ファイルに追加して下さい。これからは、このディレクトリを「ワークスペースのルート」と呼ぶことにします:

package.json

{
  "private": true,
  "workspaces": ["workspace-a", "workspace-b"]
}

private: true が必要なことに注意してください!ワークスペースは公開されることを意図しておらず、誤ってそれらを公開してしまうものがないよう、安全措置を講じたのです。

このファイルが作成された後、workspace-aworkspace-b の2つの新しいサブフォルダを作成してください。 それら各々に、別の package.json ファイルを以下の内容で作成してください:

workspace-a/package.json:

{
  "name": "workspace-a",
  "version": "1.0.0",

  "dependencies": {
    "cross-env": "5.0.5"
  }
}

workspace-b/package.json:

{
  "name": "workspace-b",
  "version": "1.0.0",

  "dependencies": {
    "cross-env": "5.0.5",
    "workspace-a": "1.0.0"
  }
}

最後に、どこかで yarn install を実行してください。理想的には、ワークスペースルート直下です。全てが上手くいったら、以下と同様のファイルの階層構造となっているはずです:

/package.json
/yarn.lock

/node_modules
/node_modules/cross-env
/node_modules/workspace-a -> /workspace-a

/workspace-a/package.json
/workspace-b/package.json

完成です! workspace-aworkspace-b にあるファイルから要求すれば、 Github 上に公開されているものではなく、まさに現在プロジェクト内にあるコードが使用されます。そして重複する cross-env パッケージは正しく除去され、workspace-a および workspace-b の両方から使用できるようにプロジェクトのルートに配置されます。

Lerna と比較してどうなのか?

Yarn のワークスペースは、Lerna のようなツールが使用することもできる(そして 実際できます! )、低レベルでプリミティブなものです。 ワークスペースは、Lerna が提供するような高レベルの機能をサポートすることはありません。しかし、Yarn 自身の内部の依存関係の解決およびリンクを行う処理のコアロジックを実装することによって、新しい使用法とパフォーマンスの改善を実現できるようにしたいと、私たちは考えています。

Tips とコツ

  • workspaces フィールドは各ワークスペースへのパスを含む配列です。 それらの各々を追跡するのは面倒なことがあるので、このフィールドは glob パターンに対応しています! 例えば、Babel はそのパッケージを単一の packages/* の形で参照しています。

  • ワークスペースは、大規模なアプリケーションで使用できるほど十分に安定しており、標準のインストールでの動作を一切変更するべきではありません。しかし、ワークスペースが何らかの問題を起こしていると思われるなら、以下の行を Yarnrc ファイルに追加して、無効にすることができます:

      workspaces-experimental false
    

制限および注意事項

  • あなたのワークスペースとユーザーが取得するものとでは、パッケージのレイアウトは異なったものとなります(ワークスペースの依存関係はファイルシステムの上層に移動されています)。 その上層へ移動するプロセスは標準化されておらず、このレイアウトは既に有害であるとみなされており、理論的には目新しいものではありません。

  • 上記の例では、workspace-bworkspace-a の package.json で参照されているものと異なるバージョンに依存している場合、依存関係はローカルのファイルシステムからではなく、Github からインストールされます。 これは、一部のパッケージでは新しいものをビルドするのに、実際には以前のバージョンを使用する必要があるためです(Babel はそのうちの1つです)。

  • ワークスペース内のパッケージを公開するときには注意してください。 次のリリースの準備中に新しい依存関係を使うことに決めても、 package.json にそれを宣言するのを忘れたとしても、ローカルではテストが通ることがあります。他のパッケージがその依存関係をすでにワークスペースのルートにダウンロードしているとそうなります。 けれども、レジストリからそのパッケージをインストールして使おうとすると、依存関係リストが不完全で新しい依存関係をダウンロードできないために、壊れしまって使えません。 現時点では、このシナリオに対して警告を出せません。

  • それぞれのワークスペースは、フォルダの階層という観点ではワークスペースのルートの子階層である必要があります。このファイルシステムの階層の外にワークスペースへの参照を作ることはできませんし、作ってはいけません。

  • ネストされたワークスペースは現時点ではサポートされていません。