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
@Exportedannotation 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.yamlconfiguration. - 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_annotationTo run the code generator, execute a one-time build in your project directory:
dart run build_runner build -dAlternatively, run a persistent build server that watches your package files for changes and rebuilds as necessary:
dart run build_runner watch -dSee 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 optionsIn 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
showorhidefilters. - A
hidefilter takes precedence over ashowfilter (i.e., anything excluded implicitly byshowwill 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.dartwill contain all exports.lib/core.dartwill contain exports tagged withcore.lib/models.dartwill 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.dartwill export all three symbols.UserandOrderwill be exported tolib/core.dartandlib/models.dart, respectively.Paymentis 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']