diff --git a/firebase.json b/firebase.json index 1b682dc5a7..b65b0161fe 100644 --- a/firebase.json +++ b/firebase.json @@ -181,7 +181,7 @@ { "source": "/go/ffi", "destination": "/interop/c-interop", "type": 301 }, { "source": "/go/flutter-upper-bound-deprecation", "destination": "https://github.com/flutter/flutter/issues/68143", "type": 301 }, { "source": "/go/macros", "destination": "/language/macros", "type": 301 }, - { "source": "/go/pub-workspaces", "destination": "https://flutter.dev/go/pub-workspace", "type": 301 }, + { "source": "/go/pub-workspaces", "destination": "/guides/packages#workspaces", "type": 301 }, { "source": "/go/non-promo-conflicting-getter", "destination": "/tools/non-promotion-reasons#getter-name", "type": 301 }, { "source": "/go/non-promo-conflicting-non-promotable-field", "destination": "/tools/non-promotion-reasons#field-name", "type": 301 }, { "source": "/go/non-promo-conflicting-noSuchMethod-forwarder", "destination": "/tools/non-promotion-reasons#nosuchmethod", "type": 301 }, diff --git a/src/content/guides/packages.md b/src/content/guides/packages.md index 55481448cd..c297e633f4 100644 --- a/src/content/guides/packages.md +++ b/src/content/guides/packages.md @@ -261,6 +261,184 @@ To update `pubspec.lock` run `dart pub get` without `--enforce-lockfile`. [content hash]: /tools/pub/glossary#content-hashes + +## Pub Workspaces (Mono-repo Support) + +When working on a project, you might develop multiple Dart packages in the same +version control repository (a mono-repo). + +For example you might have a directory layout like: + +```console +/ + 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 +``` + +There are some downsides to this setup: + +* You need to run `dart pub get` once for each package. +* You risk ending up with different versions of dependencies for each package. + Leading to confusion when context switching between the packages. +* If you open the root folder in your IDE, the dart analyzer will have to have a + separate analysis contexts for each package (increasing memory usage). + +Pub allows you to organize your repository as a "workspace" using a single +shared resolution for all your packages. + +:::note +Using a single shared dependency resolution for all your packages increases +the risks of dependency conflicts. Because Dart does not allow multiple versions +of the same package. + +If the packages are going to be used together (as is commonly the case), +this is often a feature, as it forces you to resolve incompatibilities between your +packages when they arise, rather then when you start using the packages. +::: + +To create a workspace: + +* Add a `pubspec.yaml` at the repository root directory with a `workspace` entry + enummerating the paths to the packages of the respository (the workspace + packages): + +```yaml +name: _ +publish_to: none +environment: + sdk: ^3.6.0 +workspace: + - packages/helper + - packages/client_package + - packages/server_package +``` + +* For each of the existing `pubspec.yaml`s, make sure their SDK constraint is at + least `^3.6.0` and add a `resolution` entry: + + ```yaml + environment: + sdk: ^3.6.0 + resolution: workspace + ``` + +* Run `dart pub get` anywhere in the repository, and this will: + * Create a single `pubspec.lock` next to the root `pubspec.yaml` that contains + the a resolution of all the `dependencies` and `dev_dependencies` of all the + workspace packages. + * Create a single shared `.dart_tool/package_config.json` that maps package + names to file locations. + * Delete any other existing `pubspec.lock` and + `.dart_tool/package_config.json` files next to workspace packages. + +Now the file structure looks like this: + +```console +/ + packages/ + shared/ + pubspec.yaml + client_package/ + pubspec.yaml + server_package/ + pubspec.yaml + pubspec.yaml + pubspec.lock + .dart_tool/package_config.json +``` + +:::version-note +Pub workspaces was introduced in Dart 3.6.0. + +To use pub workspaces, all your workspace packages (but not your dependencies) +must have a SDK version constraint of `^3.6.0` or higher. +::: + +### Interdependencies between workspace packages + +If any of the workspace packages depend on each other, they will automatically +resolve to the one in the workspace, regardless of the source. + +Eg. `packages/client_package/pubspec.yaml` might depend on `shared`: + +```yaml +dependencies: + shared: ^2.3.0 +``` + +When resolved inside the workspace, the _local_ version of `shared` will be +used. + +The local version of `shared` would still have to match the constraint +(`^2.3.0`) though. + +But when the package is consumed as a dependency without being part of the +workspace, the original source (here implicitly `hosted`) is used. + +So if `client_package` is published to pub.dev and someone depends on it, they +will get the hosted version of `shared` as a transitive dependency. + +### Dependency overrides in a workspace + +All `dependency_overrides:` sections in the workspace packages are respected, +and you can also place a `pubspec_overrides.yaml` file next to any of the +workspace `pubspec.yaml` files. + +You can only override a package once in the workspace. To keep overrides organized +it can be preferable to keep `dependency_overrides` in the root `pubspec.yaml`. + +### Running a command in a specific workspace package + +Some pub commands, such as `dart pub add`, and `dart pub publish` operate on a +"current" package. You can either change directory, or use `-C` to point pub at +a directory: + +```console +$ dart pub -C packages/client_package publish +# Same as +$ cd packages/client_package ; dart pub publish ; cd - +``` + +### Temporarily resolving a package outside its workspace: + +Sometimes you might want to resolve a workspace package on its own, eg. to +validate its dependency constraints. + +One way to do this is to create a `pubspec_overides.yaml` file that resets the +`resolution:` setting. Like: + +```yaml +# packages/client_package/pubspec_overrides.yaml +resolution: +``` + +Now running `dart pub get` inside `packages/client_package` will create an +independent resolution. + +### Listing all workspace packages + +You can run `dart pub workspace list` to list the packages of a workspace. + +```console +$ dart pub workspace list +Package Path +_ ./ +client_package packages/client_package/ +server_package packages/server_package/ +shared packages/shared/ +``` + ## More information The following pages have more information about packages and diff --git a/src/content/tools/pub/cmd/pub-add.md b/src/content/tools/pub/cmd/pub-add.md index fee7385d4a..2616c93925 100644 --- a/src/content/tools/pub/cmd/pub-add.md +++ b/src/content/tools/pub/cmd/pub-add.md @@ -188,6 +188,11 @@ _Previously the `--sdk=` option_: $ dart pub add foo --sdk=flutter ``` +## In a workspace + +In a [Pub Workspace](/guides/packages#workspaces) `dart pub add` will add +dependencies only to the package in the current directory. + ## Options For options that apply to all pub commands, see diff --git a/src/content/tools/pub/cmd/pub-deps.md b/src/content/tools/pub/cmd/pub-deps.md index a55f2a1e83..590371087f 100644 --- a/src/content/tools/pub/cmd/pub-deps.md +++ b/src/content/tools/pub/cmd/pub-deps.md @@ -79,3 +79,8 @@ Generates output in JSON format. {% render 'pub-problems.md' %} + +## In a workspace + +In a [Pub Workspace](/guides/packages#workspaces) `dart pub deps` will list +dependencies for all packages in the workspace, one workspace package at a time. \ No newline at end of file diff --git a/src/content/tools/pub/cmd/pub-downgrade.md b/src/content/tools/pub/cmd/pub-downgrade.md index 7bfcfd1abf..fb77a31063 100644 --- a/src/content/tools/pub/cmd/pub-downgrade.md +++ b/src/content/tools/pub/cmd/pub-downgrade.md @@ -122,3 +122,8 @@ resolved versions, and returns a list of the changed constraints. Can be applied to [specific dependencies](#downgrading-specific-dependencies). {% render 'pub-problems.md' %} + +## In a workspace + +In a [Pub Workspace](/guides/packages#workspaces) `dart pub downgrade` will +downgrade all dependencies across the workspace. \ No newline at end of file diff --git a/src/content/tools/pub/cmd/pub-lish.md b/src/content/tools/pub/cmd/pub-lish.md index 1d1c9c338b..87b28642b0 100644 --- a/src/content/tools/pub/cmd/pub-lish.md +++ b/src/content/tools/pub/cmd/pub-lish.md @@ -47,3 +47,8 @@ You can either wait a few minutes in between publishing the first and the second to publish the second package immediately, by side-stepping client-side valiation. {% render 'pub-problems.md' %} + +## In a workspace + +In a [Pub Workspace](/guides/packages#workspaces) `dart pub publish` publishes +the package in the current directory. \ No newline at end of file diff --git a/src/content/tools/pub/cmd/pub-outdated.md b/src/content/tools/pub/cmd/pub-outdated.md index 03616a5d75..3c0f95f06e 100644 --- a/src/content/tools/pub/cmd/pub-outdated.md +++ b/src/content/tools/pub/cmd/pub-outdated.md @@ -193,6 +193,10 @@ When you edit the `pubspec.yaml` file, you generally update the **dependencies** and **dev_dependencies** sections so that each package uses the versions in the **Resolvable** column. +## In a workspace + +In a [Pub Workspace](/guides/packages#workspaces) `dart pub outdated` lists +all dependencies ## Options diff --git a/src/content/tools/pub/cmd/pub-remove.md b/src/content/tools/pub/cmd/pub-remove.md index 7a78fb064a..092ffa7107 100644 --- a/src/content/tools/pub/cmd/pub-remove.md +++ b/src/content/tools/pub/cmd/pub-remove.md @@ -19,6 +19,11 @@ and then calling `dart pub get`: $ dart pub remove http ``` +## In a workspace + +In a [Pub Workspace](/guides/packages#workspaces) `dart pub remove` removes +dependencies from the package in the current directory. + ## Options For options that apply to all pub commands, see diff --git a/src/content/tools/pub/cmd/pub-upgrade.md b/src/content/tools/pub/cmd/pub-upgrade.md index ccbb5b420b..7e3761919d 100644 --- a/src/content/tools/pub/cmd/pub-upgrade.md +++ b/src/content/tools/pub/cmd/pub-upgrade.md @@ -99,6 +99,14 @@ offline `dart pub upgrade` locks your app to that old version. The next time you are online, you will likely want to run `dart pub upgrade` again to upgrade to a later version. +## In a workspace + +In a [Pub Workspace](/guides/packages#workspaces) `dart pub upgrade` will +upgrade all dependencies in the shared resolution from across all workspace +packages. + +`dart pub upgrade --major-versions` and `dart pub upgrade --tighten` will update +constraints in all workspace `pubspec.yaml`s. ## Options diff --git a/src/content/tools/pub/glossary.md b/src/content/tools/pub/glossary.md index e284476f4d..22436db8fb 100644 --- a/src/content/tools/pub/glossary.md +++ b/src/content/tools/pub/glossary.md @@ -307,3 +307,15 @@ since they use the [lockfile](#lockfile) to manage their dependency versions. For more information, see [Pub Versioning Philosophy](/tools/pub/versioning). + +## Workspace + +A collection of packages that are developed together with a shared resolution of +their dependency constrains. Useful for developing in a mono-repo. + +The packages will have a shared `pubspec.lock` and a shared +`.dart_tool/package_config.json`. + +For more information, see +[Pub Workspaces](/guides/packages#workspaces). +