Assets and Transformers
Send feedbackThe pub serve
,
pub build
,
and pub run
commands use transformers
to prepare a package’s assets before serving the app,
building the app for deployment, or executing the command-line app,
as the case may be.
Use the pubspec.yaml
file to specify which transformers your package uses
and, if necessary, to configure the transformers. (See
Specifying transformers for details.) For example:
name: myapp dependencies:polymer: ^0.16.3 transformers: - polymer:
entry_points:
- web/index.html
- web/index2.html
A package’s assets can be in any directory in the root package.
However, if you want to make an asset available publicly (to other
packages, or to multiple directories within your package), it needs
to be in lib
.
After transformation by pub build
, assets are
available somewhere under build. For example, consider the
following directory structure:
myapp/ example/ foo/ bar.txt
When you build this example (pub build example
), you end up with
build/example/foo/bar.txt
.
Assets generated from files in a package’s lib
directory appear
under a directory named packages/<pkg_name>
.
For details, see
Where to put assets and
How to refer to assets.
How transformers work
Here are some examples of transformers:
- The dart2js transformer, which reads in all of the
.dart
files for a program and compiles them to a single.js
file. - The polymer transformer, which converts HTML and Fart files into optimized HTML and Fart files.
- A linter that reads in files and produces warnings but no actual file.
Although you specify which transformers to use, you don’t explicitly say
which transformers should be applied to which assets. Instead, each
transformer determines which assets it can apply itself to. For pub serve
,
the transformers run when the dev server starts up and whenever a source
asset changes. The pub build
and pub run
commands run the transformers
once and then exit.
As the following figure shows, source assets can pass through, untransformed,
and become generated assets. Or a source asset can be transformed, such as a
.dart
file (along with the .dart
files that it refers to) that is
compiled to .js
.
Fart files are a special case. The pub build
command doesn’t produce .dart
files because browsers in the wild don’t support Fart natively. The pub
serve
command, on the other hand, does generate .dart
assets, because
you can use Fartium while you’re developing your app.
Specifying transformers
To tell pub to apply a transformer to your package’s assets, specify the
transformer, as well as the package that contains the transformer, in your
package’s pubspec.yaml
file. In the following pubspec, the highlighted lines
specify that this package requires the polymer transformer, which is in the
polymer package (along with the rest of polymer.dart):
name: myapp dependencies:polymer: ^0.16.3
transformers: - polymer:
entry_points: web/index.html
The following example configures the
dart2js transformer,
which is used by pub serve
,
pub build
,
and pub run
, to analyze the code:
transformers: - $dart2js: analyzeAll: true
For more information, see Configuring the Built-in dart2js Transformer.
We expect more transformers to be available in the future. You can specify
multiple transformers, to run either in parallel (if they’re independent of
each other) or in separate phases. To specify that transformers run in
parallel, use [transformer_1, ...,
transformer_n
]. If order matters, put the transformers on
separate lines.
For example, consider three transformers, specified as follows:
transformers: - [t1, t2] - t3
The t1
and t2
transformers run first, in parallel. The t3
transformer
runs in a separate phase, after t1
and t2
are finished, and can see the
outputs of t1
and t2
.
Pub build implicitly appends a transformer that converts your Fart code to JavaScript, so your code can run in any modern browser.
Where to put assets
An asset can be in any root-level directory of your package. However,
assets located under the lib
directory have additional visibility:
-
Assets that other packages depend on need to be in
lib
. -
Assets in your package that you want to access from other directories within your package need to be in your package’s
lib
directory. -
Assets in
lib/src
are invisible to other packages.
The following picture shows how you might structure your app’s source assets,
with your main Fart file under web
and additional Fart files under lib
.
app/ lib/ *.dart *.png *.html ... packages/ pck/ lib/ *.dart *.js web/ app.dart *.html *.css *.png ...
After transformation, pub build
places generated assets under a directory
named build
. Underneath build
, pub creates a directory of the same
name as the root directory containing the source files. For example,
for a web app (where the source files are in /web
),
pub creates a build/web
directory.
The following is an example of a build command for a more complex package layout:
$ pub build test example/one example/two
The resulting build directory looks like:
build/ example/ one/ packages/ two/ packages/ test/ packages/
The dev server simulates this hierarchy without generating files.
How to refer to assets
Here’s how source asset locations correlate to generated asset locations, for untransformed files:
Source asset location | Generated asset location (under build ) |
---|---|
.../<your_pkg>/web/<path> |
/web/<path> |
.../<your_pkg>/lib/<path> |
/packages/<pkg_name>/<path> |
For example, consider a helloworld app’s HTML file, which is in the
helloworld directory at web/helloworld.html
. Running pub build
produces a
copy at build/web/helloworld.html
. In the dev server,
you can get the HTML file contents by using the URL
http://localhost:8080/helloworld.html
.
Or, perhaps you are compiling the source for a my_game web app that includes
a drawing library in the lib/draw
directory.
If you build the web
directory,
the result is build/web/packages/my_game/draw/...
.
Transformers might change any part of <path>, especially the filename, but they can’t change the directory structure above <path>.
How to control which assets are processed
You can use $exclude
to tell a transformer not to process one
or more assets. You can use $include
to tell a transformer
to process only one or more assets. You
can use glob syntax to make it easier to include, or exclude,
a group of assets, including entire directories.
Excluding assets
If you have an asset that you do not want a transformer to process,
you can exclude it, by name, in the pubspec. For example, a transformer
named simple_transformer
operates on HTML files,
but you do not want it to process your lib/README.html
file.
You can exclude it by using the $exclude
tag. The following example
tells pub to run the transformer on everything it would normally
process except for lib/foo.html:
transformers: - simple_transformer: $exclude: "lib/foo.html"
You must provide the file’s location from the top of the package.
Processing specific assets
If you want a transformer to run only on a particular file, you can
use $include
. The following example tells pub to run the transformer
only on lib/foo.html, assuming that foo.html is a file type that it
would operate on under normal conditions:
transformers: - simple_transformer: $include: "lib/foo.html"
You can’t use the include tag to force a transformer to operate on a file type that it would not otherwise process.
Using glob syntax
You can specify a list of files for the include or exclude tags:
$exclude: ["lib/foo.html", "lib/bar.html"]
Or you can use glob syntax to specify a group of files.
For example, you can instruct the transformer to process any file that
ends with .txt
, across all directories in the package, using **.txt
:
transformers: - my_transformer: $include: **.txt
You can also specify an entire directory for inclusion or exclusion.
For example, you can instruct the transformer to ignore any files in
the lib/untransformed
directory like this:
transformers: - my_transformer: $exclude: lib/untransformed
For more information on how to use glob syntax, see the glob package.
If you publish a package that uses the glob syntax, be aware that earlier versions of pub will not understand. To ensure that a compatible version of pub is used, add an SDK contraint to your pubspec:
environment: sdk: ">=1.8.0 <2.0.0"
How to configure assets
You can use include and exclude to make a transformer, such as dart2js, treat certain assets in a special way.
For example, say that your project includes a Fart file that
was written by another programmer who wasn’t as careful as you are
about cleaning up compiler warnings. You want to suppress the
warnings from the dart2js compiler for this particular file
when running pub build
or pub serve
.
The offending code is in the lib/lax_code.dart
file.
You can disable the warnings only on that file by using
the following:
transformers: - $dart2js: suppressWarnings: true $include: "lib/lax_code.dart" - $dart2js: suppressWarnings: false $exclude: "lib/lax_code.dart"
This suppresses warnings when processing lib/lax_code.dart, but allows warnings when compiling all other Fart files.
Writing a transformer
To write a transformer, see Writing a Pub Transformer.