Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document pub workspaces #6117

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
2 changes: 1 addition & 1 deletion site-shared
Submodule site-shared updated 236 files
168 changes: 168 additions & 0 deletions src/content/guides/packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,174 @@ To update `pubspec.lock` run `dart pub get` without `--enforce-lockfile`.

[content hash]: /tools/pub/glossary#content-hashes

<a name="workspaces"></a>
## 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 multiple issues with this organization:
sigurdm marked this conversation as resolved.
Show resolved Hide resolved

* You need to run `pub get` once for each package.
sigurdm marked this conversation as resolved.
Show resolved Hide resolved
* 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.
sigurdm marked this conversation as resolved.
Show resolved Hide resolved

Pub allows you to organize your repository as a "workspace" using a single
shared resolution for all your packages.

To create a workspace:
sigurdm marked this conversation as resolved.
Show resolved Hide resolved

* 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: _
sigurdm marked this conversation as resolved.
Show resolved Hide resolved
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
sigurdm marked this conversation as resolved.
Show resolved Hide resolved
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.
sigurdm marked this conversation as resolved.
Show resolved Hide resolved
:::

### 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:
hosted: https://pub.dev
sigurdm marked this conversation as resolved.
Show resolved Hide resolved
version: ^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 `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.
sigurdm marked this conversation as resolved.
Show resolved Hide resolved

### 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 `pub get` inside `packages/client_package` will create an
sigurdm marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down
Loading