メインコンテンツにスキップ

Pub ワークスペース (モノレポサポート)

プロジェクトに取り組んでいる際、複数の Dart パッケージを同じバージョン管理リポジトリ (モノレポ) で開発することがあります。

例えば、以下のようなディレクトリレイアウトを持つ場合があります。

/
  packages/
    shared/
      pubspec.yaml
      pubspec.lock
      .dart_tool/package_config.json
    client_package/
      pubspec.yaml
      pubspec.lock
      .dart_tool/package_config.json
    server_package/
      pubspec.yaml
      pubspec.lock
      .dart_tool/package_config.json

このセットアップにはいくつかの欠点があります。

  • パッケージごとに dart pub get を一度実行する必要があります。
  • 各パッケージで依存関係のバージョンが異なる状態になるリスクがあり、パッケージ間でのコンテキスト切り替え時に混乱を招きます。
  • IDE でルートフォルダーを開くと、Dart アナライザーは各パッケージに対して個別の分析コンテキストを作成するため、メモリ使用量が増加します。

Pub は、単一の共有解決を利用してリポジトリを ワークスペース として整理することを可能にします。大規模なリポジトリでワークスペースを使用すると、分析に必要なメモリ量が減り、パフォーマンスが向上します。

ワークスペースを作成するには

  • リポジトリのルートディレクトリに pubspec.yaml を追加し、リポジトリのパッケージへのパス (ワークスペースパッケージ) を列挙する workspace エントリを追加します。

    yaml
    name: _
    publish_to: none
    environment:
      sdk: ^3.6.0
    workspace:
      - packages/helper
      - packages/client_package
      - packages/server_package
  • 既存の pubspec.yaml ファイルごとに、SDK 制約が少なくとも ^3.6.0 であることを確認し、resolution エントリを追加します。

    yaml
    environment:
      sdk: ^3.6.0
    resolution: workspace
  • リポジトリ内のどこかで dart pub get を実行します。これにより

    • ルート pubspec.yaml の隣に、すべてのワークスペースパッケージのすべての dependencies および dev_dependencies の解決を含む単一の pubspec.lock が作成されます。
    • パッケージ名をファイル場所マッピングする単一の共有 .dart_tool/package_config.json が作成されます。
    • ワークスペースパッケージの隣にある既存の pubspec.lock および .dart_tool/package_config.json ファイルを削除します。

これで、ファイル構造は次のようになります。

/
  packages/
    shared/
      pubspec.yaml
    client_package/
      pubspec.yaml
    server_package/
      pubspec.yaml
  pubspec.yaml
  pubspec.lock
  .dart_tool/package_config.json

孤立したファイル

#

既存のモノレポを Pub ワークスペースを使用するように移行すると、各 pubspec の隣に既存の「孤立した」pubspec.lock および .dart_tool/package_config.json ファイルが存在します。これらは、ルートの隣に配置された pubspec.lock および .dart_tool/package_config.json ファイルをシャドウします。

したがって、pub get は、ルートと (含む) 任意のワークスペースパッケージの間のディレクトリにある pubspec.lock および .dart_tool/package_config.json を削除します。

/
  pubspec.yaml                       # Root
  packages/
    pubspec.lock                     # Deleted by `pub get`
    .dart_tool/package_config.json   # Deleted by `pub get`
    foo/
      pubspec.yaml                   # Workspace member
      pubspec.lock                   # Deleted by `pub get`
      .dart_tool/package_config.json # Deleted by `pub get`

ワークスペースルートとワークスペースパッケージの間の任意のディレクトリに、ワークスペースのメンバーではない「孤立した」pubspec.yaml ファイルが含まれている場合、pub get はエラーを報告し、解決に失敗します。これは、そのような pubspec.yaml を解決すると、ルートにあるものをシャドウする .dart_tool/package_config.json ファイルが作成されるためです。

/
  pubspec.yaml                      # Root `workspace: ['foo/']`
  packages/
    pubspec.yaml                    # Not workspace member => error
    foo/
      pubspec.yaml                  # Workspace member

ワークスペースパッケージ間の相互依存関係

#

ワークスペースパッケージがお互いに依存している場合、ソースに関係なく、ワークスペース内のものに自動的に解決されます。

例: packages/client_package/pubspec.yamlshared に依存している可能性があります。

yaml
dependencies:
  shared: ^2.3.0

ワークスペース内で解決されると、shared の*ローカル*バージョンが使用されます。

ただし、shared のローカルバージョンは、制約 (^2.3.0) に一致する必要があります。

しかし、パッケージがワークスペースの一部ではなく、依存関係として消費される場合、元のソース (ここでは暗黙的に hosted) が使用されます。

したがって、client_package が pub.dev に公開され、誰かがそれに依存している場合、その人は推移的な依存関係として shared のホストバージョンを取得します。

ワークスペースでの依存関係の上書き

#

ワークスペースパッケージのすべての dependency_overrides セクションは尊重されます。また、ワークスペースの pubspec.yaml ファイルの隣に pubspec_overrides.yaml ファイルを配置することもできます。

ワークスペースでパッケージを一度だけ上書きできます。上書きを整理するために、dependency_overrides をルート pubspec.yaml に保持することをお勧めします。

特定のワークスペースパッケージでコマンドを実行する

#

dart pub adddart pub publish などの一部の pub コマンドは、「現在の」パッケージで操作されます。ディレクトリを変更するか、-C を使用して pub をディレクトリにポイントさせることができます。

dart pub -C packages/client_package publish
# Same as
cd packages/client_package ; dart pub publish ; cd -

ワークスペース外のパッケージを一時的に解決する

#

ワークスペースパッケージを単独で解決したい場合があります。たとえば、依存関係の制約を検証するためです。

これを行う 1 つの方法は、resolution 設定をリセットする pubspec_overrides.yaml ファイルを作成することです。たとえば次のようになります。

yaml
# packages/client_package/pubspec_overrides.yaml
resolution:

これで、packages/client_package 内で dart pub get を実行すると、独立した解決が作成されます。

すべてのワークスペースパッケージを一覧表示する

#

dart pub workspace list を実行して、ワークスペースのパッケージを一覧表示できます。

dart pub workspace list
Package         Path                      
_               ./                        
client_package  packages/client_package/  
server_package  packages/server_package/  
shared          packages/shared/