目录

Pub 工作区(monorepo 支持)

在处理项目时,你可能会在同一个版本控制存储库(monorepo)中开发多个 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 旁边创建一个包含所有工作区包的 dependenciesdev_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

工作区包之间的相互依赖关系

#

如果任何工作区包彼此依赖,它们将自动解析到工作区中的那个,而不管来源如何。

例如。packages/client_package/pubspec.yaml 可能依赖于 shared

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 中。

在特定的工作区包中运行命令

#

一些 pub 命令,例如 dart pub adddart pub publish 在“当前”包上运行。你可以更改目录,也可以使用 -C 将 pub 指向一个目录

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

临时解析工作区外部的包

#

有时你可能希望单独解析一个工作区包,例如验证其依赖关系约束。

一种方法是创建一个 pubspec_overides.yaml 文件,该文件重置 resolution 设置,如下所示

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/