Reputation: 3560
My flutter project depends on several local flutter and dart packages to keep things separated and clean. My folder structure is like this:
main-flutter-project
│ lib
| test
│ pubspec.yaml
│
└── local-packages
│ └── dart-package-1
│ │ pubspec.yaml
│ │
│ └── flutter-package-1
│ │ pubspec.yaml
│ │
│ └── flutter-package-2
│ pubspec.yaml
...
Each local package is self contained and can be maintained without touching the main project.
This structure means that I have many pubspec.yaml
files where I have to keep the dependencies updated.
When I use e.g. the bloc
libaray bloc: ^7.2.1
in say 5 packages, I have to update the version in each pubspec
file separately when a new version is released.
Is there a possibility to specify those shared package dependency versions in only one place where the other pubspec.yaml
files refer to?
I've seen this e.g. with Maven where you can specify a property <junit.version>4.12</junit.version>
and access it from somewhere else <version>${junit.version}</version>
.
Upvotes: 10
Views: 2814
Reputation: 6343
We were solving a similar problem.
AFAIK, there's no built-in or recommended way to do this, so we were inventing some hacks.
In our case, we have core
package that has some shared functionality and common dependencies, if you don't have it, you can still create an artificial one, let's say, shared_dependencies
package, and specify all the shared dependencies there.
Now, let's say, package foo
depends on shared_dependencies
package, and there's dependency bar
defined in shared_dependecies
package that foo
needs to use. There are some ways to do that:
Import dependency directly. Since foo
depends transitively on bar
, you can just write import package:bar/bar.dart
and it will work. It's not the best way though:
Export package in shared_dependencies
package. I.e. shared_dependencies.dart
can contain the following lines:
export 'package:bar/bar.dart'
That means that in your foo
package you can just write import 'shared_dependencies/shared_dependencies.dart'
and get access to bar
content.
Pros:
Contras:
foo
package depends on one bar
package only, it could be weird to import all shared_dependencies.Export in separate libraries of shared_dependencies
package. You can group some related packages together in different files, e.g.:
bar.dart
:
export 'package:bar/bar.dart'
bloc.dart
:
export 'package:bloc_concurrency/bloc_concurrency.dart';
export 'package:flutter_bloc/flutter_bloc.dart';
In that case, if you need bar
package in foo
, you write import 'package:shared_dependencies/bar.dart'
; if you need bloc
, you write import 'package:shared_dependencies/bloc.dart'
. Auto-imports work as well.
Add direct dependency to foo
package, but don't specify version constraints:
bar:
This basically means that you need any bar
package, but since foo
also depends on shared_dependencies
, its constraints will be taken into account. This may be needed if you're using some executables from bar
package, as there's a limitation in Dart SDK that doesn't allow to run executables in transitive dependencies.
In our project, we ended up using 2
for the most commonly used packages, 3
for other packages, and 4
for packages with executables that we need to run.
Upvotes: 23