ワークスペース

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

なぜこれがしたいのか?

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

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

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

使い方は?

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

package.json

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

Note that the private: true is required! Workspaces are not meant to be published, so we’ve added this safety measure to make sure that nothing can accidentally expose them.

このファイルが作成された後、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つです)。

  • Be careful when publishing packages in a workspace. If you are preparing your next release and you decided to use a new dependency but forgot to declare it in the package.json file, your tests might still pass locally if another package already downloaded that dependency into the workspace root. However, it will be broken for consumers that pull it from a registry, since the dependency list is now incomplete so they have no way to download the new dependency. Currently there is no way to throw a warning in this scenario.

  • Workspaces must be children of the workspace root in term of folder hierarchy. You cannot and must not reference a workspace that is located outside of this filesystem hierarchy.

  • Nested workspaces are not supported at this time.