Pub workspaces (monorepo support)
When working on a project, you might develop multiple Dart packages in the same version control repository (a monorepo).
For example you might have a directory layout like:
/
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 create 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. Using workspaces for large repositories reduces the amount of memory required for analysis, hence improving performance.
To create a workspace:
Add a
pubspec.yaml
at the repository root directory with aworkspace
entry enumerating the paths to the packages of the repository (the workspace packages):yamlname: _ publish_to: none environment: sdk: ^3.6.0 workspace: - packages/helper - packages/client_package - packages/server_package
For each of the existing
pubspec.yaml
files, make sure their SDK constraint is at least^3.6.0
and add aresolution
entry:yamlenvironment: sdk: ^3.6.0 resolution: workspace
Run
dart pub get
anywhere in the repository. This will:- Create a single
pubspec.lock
next to the rootpubspec.yaml
that contains the resolution of all thedependencies
anddev_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.
- Create a single
Now the file structure looks like this:
/
packages/
shared/
pubspec.yaml
client_package/
pubspec.yaml
server_package/
pubspec.yaml
pubspec.yaml
pubspec.lock
.dart_tool/package_config.json
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
:
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. 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's 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 the directory, or use -C
to point pub at a directory:
$ 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, for example to validate its dependency constraints.
One way to do this is to create a pubspec_overides.yaml
file that resets the resolution
setting, like so:
# 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.
$ dart pub workspace list
Package Path
_ ./
client_package packages/client_package/
server_package packages/server_package/
shared packages/shared/
Unless stated otherwise, the documentation on this site reflects Dart 3.6.0. Page last updated on 2024-12-10. View source or report an issue.