Exported is a code generator that automates the creation and maintenance of barrel files using the Dart build system.
Barrel files are a common pattern in Dart packages to centralize a public API by re-exporting multiple library files through a single public file. Maintaining barrel files manually can be tedious and error-prone as codebases grow and public APIs change.
Exported simplifies this process by automatically generating barrel files based
on annotations and configuration. Simply annotate top-level elements with
@Exported
, and build_runner
will generate the appropriate
barrel files, ensuring your public API stays up-to-date with minimal effort.
- Annotation-Based Exports: Use the
@Exported
annotation on library directives, classes, functions, or other top-level elements to include them in barrel files. - Option-Based Exports: Include additional exports (e.g., symbols from
other packages) via the
build.yaml
configuration. - Multiple Barrel Files: Generate multiple barrel files for different parts of your package.
- Export Tagging: Easily organize exports using tags for grouping and mapping them to specific barrel files.
- Installation
- Running the Generator
- Quick Start
- Configuration of Builder Options
- Adding Exports from the Builder Options
- Customizing Barrel Files
Install build_runner
, exported
and
exported_annotation
by adding them to your
pubspec.yaml
file:
dart pub add dev:build_runner
dart pub add dev:exported
dart pub add exported_annotation
To run the code generator, execute a one-time build in your project directory:
dart run build_runner build -d
Alternatively, run a persistent build server that watches your package files for changes and rebuilds as necessary:
dart run build_runner watch -d
See the build_runner
documentation for more information
on running builds.
To get started, simply annotate top-level elements with @exported
to include
them in the generated barrel file. By default, this will generate a file
lib/$package.dart
that includes all annotated symbols.
Use @exported
on individual classes (or any other public top-level element):
import 'package:exported_annotation/exported_annotation.dart';
@exported
class User {}
@exported
class Order {}
class Payment {}
The generated barrel file (e.g., lib/ecommerce.dart
) will export User
and
Order
:
export 'package:ecommerce/src/models.dart' show User, Order;
Use @exported
on an entire library to include all contained public symbols:
@exported
library;
import 'package:exported_annotation/exported_annotation.dart';
class User {}
class Order {}
class Payment {}
This will generate an export directive of the entire library:
export 'package:ecommerce/src/models.dart';
You can control which symbols to include by using the show
and hide
arguments of the annotation:
// Exports User and Order, while excluding Payment.
@Exported(show: {'User', 'Order'})
library;
import 'package:exported_annotation/exported_annotation.dart';
class User {}
class Order {}
class Payment {}
Which generates:
export 'package:ecommerce/src/models.dart' show User, Order;
Similarly, use hide
:
@Exported(hide: {'Payment'})
library;
import 'package:exported_annotation/exported_annotation.dart';
class User {}
class Order {}
class Payment {}
Generating:
export 'package:ecommerce/src/models.dart' hide Payment;
Exported uses the build.yaml
configuration file to customize
how barrel files are generated, including:
- Adding additional exports of external packages or libraries within your package.
- Configuring multiple barrel files and using tags to control which exports go into each file.
The build.yaml
file should be placed at the root of your package, alongside
pubspec.yaml
:
my_package/
lib/
build.yaml
pubspec.yaml
Configure the exported
builder options by following the standard structure
used by Dart's build system:
targets:
$default:
builders:
exported:
options:
# Configuration options
In addition to annotating elements with @exported
, you can specify additional
exports in the exports
section of the builder options. This is primarily
useful for exporting symbols from external packages, but can also include
libraries from within your package.
External libraries can be either dart:
or package:
libraries. You can
specify full URIs or simply use a package name:
options:
exports:
- 'dart:async'
- 'package:uuid/uuid.dart'
- 'ecommerce_helpers' # Resolves to 'package:ecommerce_helpers/ecommerce_helpers.dart'
Use the show
and hide
filters to selectively export only specific symbols
from the package:
options:
exports:
- 'dart:async'
- uri: 'package:uuid/uuid.dart'
show: ['Uuid']
- uri: 'ecommerce_helpers'
hide: ['LegacyUserHelper', 'LegacyOrderHelper']
This example will generate:
export 'dart:async';
export 'package:uuid/uuid.dart' show Uuid;
export 'package:ecommerce_helpers/ecommerce_helpers.dart' hide LegacyUserHelper, LegacyOrderHelper;
To include symbols from libraries within your own package, use the uri
argument with a relative path starting with lib/
:
options:
exports:
- 'lib/src/api.dart'
- uri: 'lib/src/models/user.dart'
show: ['User']
Which generates:
export 'package:ecommerce/src/api.dart';
export 'package:ecommerce/src/models/user.dart' show User;
Warning
When duplicate export URIs are configured (via annotations and/or builder options), Exported will silently merge the show/hide filters per barrel file:
- If a library is exported in full (without filters), it will override any
show
orhide
filters. - A
hide
filter takes precedence over ashow
filter (i.e., anything excluded implicitly byshow
will be included throughhide
). - If an element is both shown and hidden, it will be shown.
By default, Exported generates a single barrel file lib/$package.dart
. This
can be customized from the barrel_files
section of the builder options.
To change the path of the generated barrel file, specify a different file path relative to the package root:
options:
barrel_files:
- 'lib/core.dart'
Exported allows you to generate multiple barrel files for a package. The
generator uses a tagging system to group exports and map them to specific
barrel files. To use multiple barrel files, configure them in the build.yaml
:
options:
barrel_files:
- 'lib/ecommerce.dart'
- path: 'lib/core.dart'
tags: ['core']
- path: 'lib/models.dart'
tags: ['models']
In this example, three barrel files will be generated:
lib/ecommerce.dart
will contain all exports.lib/core.dart
will contain exports tagged withcore
.lib/models.dart
will contain exports tagged withmodels
.
Note
If the path
is omitted, the default barrel-file path lib/$package.dart
will be used for that file.
To assign tags to exports, use the tags
parameter of @Exported
:
import 'package:exported_annotation/exported_annotation.dart';
@Exported(tags: {'core'})
class User {}
@Exported(tags: {'models'})
class Order {}
@exported
class Payment {}
In this example:
lib/ecommerce.dart
will export all three symbols.User
andOrder
will be exported tolib/core.dart
andlib/models.dart
, respectively.Payment
is untagged and will be exported to all barrel files.
Tags can be reused across multiple barrel files and each export can be assigned multiple tags, allowing for flexible grouping of exports.
Important
- Exports without tags will be included in all barrel files.
- Barrel files without tags will include all exports, regardless of their tags.
For exports that are added via the builder options, use the tags
key:
options:
exports:
- uri: 'package:uuid/uuid.dart'
tags: ['core']
- uri: 'lib/src/models/user.dart'
show: ['User']
tags: ['models']