build
#Defines the basic pieces of how a build happens and how they interact.
Builder
#The business logic for code generation. Most consumers of the build
package
will create custom implementations of Builder
.
BuildStep
#The way a Builder
interacts with the outside world. Defines the unit of work
and allows reading/writing files and resolving Dart source code.
Resolver
classAn interface into the dart analyzer to allow resolution of code that needs static analysis and/or code generation.
build
package and pub
+ barback
.If you currently implement transformers with package:barback
for use with
Dart v1 pub build
and pub serve
, see Upgrading from barback.
If you have written a barback
Transformer
in the past, then the
Builder
API should be familiar to you. The main difference
is that Builders
must always configure outputs based on input extensions.
The basic API looks like this:
abstract class Builder {
/// You can only output files in `build` that are configured here. You are not
/// required to output all of these files, but no other [Builder] is allowed
/// to produce the same outputs.
Map<String, List<String>> get buildExtensions;
/// Similar to `Transformer.apply`. This is where you build and output files.
Future build(BuildStep buildStep);
}
Here is an implementation of a Builder
which just copies files to other files
with the same name, but an additional extension:
/// A really simple [Builder], it just makes copies!
class CopyBuilder implements Builder {
final String extension;
CopyBuilder(this.extension);
Future build(BuildStep buildStep) async {
/// Each [buildStep] has a single input.
var inputId = buildStep.inputId;
/// Create a new target [AssetId] based on the old one.
var copy = inputId.addExtension(extension);
var contents = await buildStep.readAsString(inputId);
/// Write out the new asset.
///
/// There is no need to `await` here, the system handles waiting on these
/// files as necessary before advancing to the next phase.
buildStep.writeAsString(copy, contents);
}
/// Configure output extensions. All possible inputs match the empty input
/// extension. For each input 1 output is created with `extension` appended to
/// the path.
Map<String, List<String>> get buildExtensions => {'': [extension]};
}
It should be noted that you should never touch the file system directly. Go
through the buildStep#readAsString
and buildStep#writeAsString
methods in
order to read and write assets. This is what enables the package to track all of
your dependencies and do incremental rebuilds. It is also what enables your
Builder
to run on different environments.
If you need to do analyzer resolution, you can use the BuildStep#resolver
object. This makes sure that all Builder
s in the system share the same
analysis context, which greatly speeds up the overall system when multiple
Builder
s are doing resolution.
Here is an example of a Builder
which uses the resolve
method:
class ResolvingCopyBuilder implements Builder {
Future build(BuildStep buildStep) async {
// Get the [LibraryElement] for the primary input.
var entryLib = await buildStep.inputLibrary;
// Resolves all libraries reachable from the primary input.
var resolver = buildStep.resolver;
// Get a [LibraryElement] for another asset.
var libFromAsset = await resolver.libraryFor(
new AssetId.resolve('some_import.dart', from: buildStep.inputId));
// Or get a [LibraryElement] by name.
var libByName = await resolver.findLibraryByName('my.library');
}
/// Configure outputs as well....
}
Once you have gotten a LibraryElement
using one of the methods on Resolver
,
you are now just using the regular analyzer
package to explore your app.
The build package includes a Resource
class, which can give you an instance
of an expensive object that is guaranteed to be unique across builds, but may
be re-used by multiple build steps within a single build (to the extent that
the implementation allows). It also gives you a way of disposing of your
resource at the end of its lifecycle.
The Resource<T>
constructor takes a single required argument which is a
factory function that returns a FutureOr<T>
. There is also a named argument
dispose
which is called at the end of life for the resource, with the
instance that should be disposed. This returns a FutureOr<dynamic>
.
So a simple example Resource
would look like this:
final resource = new Resource(
() => createMyExpensiveResource(),
dispose: (instance) async {
await instance.doSomeCleanup();
});
You can get an instance of the underlying resource by using the
BuildStep#fetchResource
method, whose type signature looks like
Future<T> fetchResource<T>(Resource<T>)
.
Important Note: It may be tempting to try and use a Resource
instance to
cache information from previous build steps (or even assets), but this should
be avoided because it can break the soundness of the build, and may introduce
subtle bugs for incremental builds (remember the whole build doesn't run every
time!). The build
package relies on the BuildStep#canRead
and
BuildStep#readAs*
methods to track build step dependencies, so sidestepping
those can and will break the dependency tracking, resulting in inconsistent and
stale assets.
Please file feature requests and bugs at the issue tracker.
<3.0.0
.AssetId
s can no longer be constructed with paths that reach outside their
package.Resolvers.reset
method.List<String> get pathSegments
to AssetId
.log
will now always return a Logger
instance.package:analyzer
0.32.0
.FileDeletingBuilder
.FileDeletingBuilder
.PostProcesBuilderFactory
typedef.isRoot
boolean to BuilderOptions
, which allows builders to have
different behavior for the root package, if desired.PostProcessBuilder
. This is only supported by build_runner
.BuilderOptions.empty
and BuilderOptions.overrideWith
.AssetId
s as URI
s when they contain
characters which are not valid for a path segment.analyzer
package.Future<Digest> digest(AssetId id)
method to the AssetReader
interface. There is a default implementation which uses readAsBytes
and
md5
.MultiplexingBuilder
now filters inputs rather than calling every
builder on any input that matched any builder.BuilderOptions
and BuilderFactory
interfaces. Along with
package:build_config
this will offer a consistent way to describe and create
the Builder instances exposed by a package.AssetReader.findAssets
now returns a Stream<AssetId>
instead of an Iterable<AssetId>
. This also impacts BuildStep
since that
implements AssetReader
.ResourceManager
s would share Resource
instances if running at the same time.MultiPackageAssetReader
interface which allows globbing within
any package.BuildStep
class does not implement this interface.AssetReader#findAssets
have changed such that it globs within
the current package instead of the root package (typically defined as
buildStep.inputId.package
).Resource
class, and BuildStep#fetchResource
method.BuildStep.hasInput
- all uses should
be going through BuildStep.canRead
.Resolver
has asynchronous APIs for resolution and is retrieved
synchronously from the BuildStep
.Resolver.getLibrary
with libraryFor
and
getLibraryByName
with findLibraryByName
.AssetReader.canRead
to always return a Future.asset:
URIs into AssetIdsuri
property on AssetIdBuildStep.hasInput
in favor of BuildStep.canRead
.AssetReader.hasInput
as canRead
. This is breaking for implementers
of AssetReader
and for any clients passing a BuildStep
as an AssetReader
canRead
return a FutureOr
for more flexibilityManagedBuildStep
class.BuildStep.logger
. All logging should go through the top level log
.BuildStep.writeAs*
methods now take a FutureOr
for content. Builders which
produce content asynchronously can now set up the write without waiting for it
to resolve.declareOutputs
is replaced with buildExtensions
. All Builder
implementations must now have outputs that vary only based on the extensions
of inputs, rather than based on any part of the AssetId
.AssetReader.findAssets
to allow listing assets by glob.BuildStep.inputLibrary
as a convenience.AssetId.resolve
to prepend lib/
when resolving packages.AssetId.resolve
constructor to easily construct AssetIds from import
uris.log.info
. Depending on the environment a print can be hazardous so this
makes all builders safe and consistent by default.log
getter which is scoped to running builds and can be used
anywhere within a build rather than passing around a logger. This replaces the
BuildStep.logger
field.BuildStep.logger
- it is replaced by log
ManagedBuildStep
, all build runs should go through runBuilders
.A number of changes to the apis, primarily to support reading/writing as bytes,
as this is going to inevitably be a required feature. This will hopefully be the
last breaking change before the 1.0
release, but it is a fairly large one.
AssetWriter
class now has a
Future writeAsBytes(AssetId id, List<int> bytes)
method.AssetReader
class now has a Future<List<int>> readAsBytes(AssetId id)
method.Resolver#release
on any resolvers you get from
a BuildStep
(in fact, the Resolver
interface no longer has this method).BuildStep#resolver
getter, which resolves the primary input,
and returns a Future<Resolver>
. This replaces the BuildStep#resolve
method.Resolver
has a new isLibrary
method to check whether an asset is a Dart
library source file before trying to resolve it's LibraryElementAsset
class has been removed entirely.AssetWriter#writeAsString
signature has changed to
Future writeAsString(AssetId id, String contents, {Encoding encoding})
.AssetWriterSpy#assetsWritten
getter has changed from an
Iterable<Asset>
to an Iterable<AssetId>
.BuildStep#input
has been changed to BuildStep#inputId
, and its type has
changed from Asset
to AssetId
. This means you must now use
BuildStep#readAsString
or BuildStep#readAsBytes
to read the primary input,
instead of it already being read in for you.Resolver
no longer has a release
method (they are released for you).BuildStep#resolve
no longer exists, and has been replaced with the
BuildStep#resolver
getter.Resolver.getLibrary
will now throw a NonLibraryAssetException
instead of
return null if it is asked to resolve an impossible library.Note: The changes to AssetReader
and AssetWriter
also affect BuildStep
and other classes that implement those interfaces.
build_barback
to write assets from a FutureBuildStep
now implements AssetReader
and AssetWriter
so it's easier to
share with other code paths using a more limited interface.build
, watch
, or serve
, along with PhaseGroup
and related
classes add a dependency on build_runner
. If you are using
BuilderTransformer
or TansformerBuilder
add a dependency on
build_barback
.const Resolvers()
as a default instance import build_barback
and used const BarbackResolvers()
instead.dev_dependencies
so tests run.useSharedSources
when constructing Resolverspackages
paths in the file watcher to their absolute paths. This
fixes #109.Fix duplicate logs issue when running as a BuilderTransformer.
Support crypto
2.0.0.
BuildType
, BuildStatus
, and PackageDependencyType
.buildStep.resolve
.Resolvers
instance.deleteFilesByDefault
option to all top level methods. This will
skip the prompt to delete files, and instead act as if you responded y
.PhaseGroup
instead of a
List<List<Phase>>
..build
folder to .dart_tool/build
. Other packages in the future
may also use this folder.serve
function.watch
, but it provides a server which blocks on any ongoing
builds before responding to requests.lastModified
to AssetReader
(only matters if you implement it).watch
function. This can be used to watch the file
system and run incremental rebuilds on changes.build
function. This can be used to run builds..build
directory which should be added to your .gitignore
.resolve
method to BuildStep
which can give you a Resolver
for an
AssetId
.listAssetIds
to AssetReader
(only matters if you implement it).delete
to AssetWriter
(also only matters if you implement it).Add this to your package's pubspec.yaml file:
dependencies:
build: ^0.12.7+2
You can install packages from the command line:
with pub:
$ pub get
with Flutter:
$ flutter packages get
Alternatively, your editor might support pub get
or flutter packages get
.
Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:build/build.dart';
Version | Uploaded | Documentation | Archive |
---|---|---|---|
1.1.1 | Jan 31, 2019 |
|
|
1.1.0 | Jan 14, 2019 |
|
|
1.0.2 | Dec 5, 2018 |
|
|
1.0.1 | Oct 8, 2018 |
|
|
1.0.0 | Sep 25, 2018 |
|
|
0.12.8 | Sep 24, 2018 |
|
|
0.12.7+3 | Aug 1, 2018 |
|
|
0.12.7+2 | Jul 16, 2018 |
|
|
0.12.7 | Jun 21, 2018 |
|
|
0.12.6 | May 14, 2018 |
|
|
Popularity:
Describes how popular the package is relative to other packages.
[more]
|
90
|
Health:
Code health derived from static analysis.
[more]
|
100
|
Maintenance:
Reflects how tidy and up-to-date the package is.
[more]
|
70
|
Overall:
Weighted score of the above.
[more]
|
89
|
We analyzed this package on Feb 14, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:
Detected platforms: Flutter, other
Primary library:
package:build/build.dart
with components:io
,isolate
,build
.
The package description is too short. (-20 points)
Add more detail to the description
field of pubspec.yaml
. Use 60 to 180 characters to describe the package, what it does, and its target use case.
Maintain an example. (-10 points)
Create a short demo in the example/
directory to show how to use this package.
Common filename patterns include main.dart
, example.dart
, and build.dart
. Packages with multiple examples should provide example/README.md
.
For more information see the pub package layout conventions.
Package | Constraint | Resolved | Available |
---|---|---|---|
Direct dependencies | |||
Dart SDK | >=2.0.0-dev.9 <3.0.0 | ||
analyzer | >=0.27.1 <0.33.0 | 0.32.6 | 0.35.1 |
async | >=1.13.3 <3.0.0 | 2.0.8 | |
crypto | >=0.9.2 <3.0.0 | 2.0.6 | |
glob | ^1.1.0 | 1.1.7 | |
logging | ^0.11.2 | 0.11.3+2 | |
meta | ^1.1.0 | 1.1.7 | |
path | ^1.1.0 | 1.6.2 | |
Transitive dependencies | |||
args | 1.5.1 | ||
charcode | 1.1.2 | ||
collection | 1.14.11 | ||
convert | 2.1.1 | ||
csslib | 0.14.6 | ||
front_end | 0.1.4+2 | 0.1.11 | |
html | 0.13.3+3 | ||
kernel | 0.3.4+2 | 0.3.11 | |
package_config | 1.0.5 | ||
plugin | 0.2.0+3 | ||
source_span | 1.5.4 | ||
string_scanner | 1.0.4 | ||
term_glyph | 1.1.0 | ||
typed_data | 1.1.6 | ||
utf | 0.9.0+5 | ||
watcher | 0.9.7+10 | ||
yaml | 2.1.15 | ||
Dev dependencies | |||
build_resolvers | ^0.2.1 | ||
build_test | ^0.10.0 | ||
test | ^1.2.0 |