Fwd: [DRAFT] Pub/Barback: Lazy and Declaring Transformers

99 views
Skip to first unread message

Nathan Weizenbaum

unread,
Apr 16, 2014, 7:36:25 PM4/16/14
to General Dart Discussion, Pete Blois, Sigmund Cherem, Emily Fortuna, Alan Knight
Hi everyone,

Since version 0.11.1, barback has supported two special types of transformers: lazy transformers and declaring transformers. However, until recently the fact that a transformer was lazy or declaring was ignored by pub; it was treated like any other transformer. As of r35139, lazy and declaring transformers are fully supported in pub, so you can start using them.

Lazy Transformers

When using pub serve, lazy transformers don't run their apply methods until one of their outputs is requested. If a transformer takes so long to run that it's painful to run it eagerly every time a file changes, it's a good candidate for a lazy transformer. The built-in dart2js transformer is a good example: it can take a considerable amount of time to compile a large program, so it's lazy. This allows you to run pub serve in an application with many entrypoints and tests and only compile the entrypoints that you access when you access them—or, if you're using Dartium, never compile them at all.

In order to mark your transformer as lazy, it should implement the LazyTransformer interface. This interface has one method, declareOutputs, which takes a DeclaringTransform and uses it to declare which outputs it will emit. This is necessary so that barback knows which outputs should trigger a call to apply.

Here's an example of the dart2js transformer's declareOutputs method:

class Dart2JSTransformer extends Transformer implements LazyTransformer {
// ...
Future declareOutputs(DeclaringTransform transform) {
// Note that DeclaringTransform only gives access to the primary input's id, not its
// contents. This allows lazy transformers to be piped into one another while preserving
// their laziness.
transform.declareOutput(transform.primaryId.addExtension(".js"));
transform.declareOutput(transform.primaryId.addExtension(".precompiled.js"));
if (_generateSourceMaps) {
transform.declareOutput(transform.primaryId.addExtension(".js.map"));
}
return new Future.value();
}
}

Declaring Transformers

Declaring transformers are like lazy transformers in that they tell barback what outputs they'll emit via declareOutputs. Otherwise, though, they're just like normal transformers: they'll run eagerly whenever their inputs change. Telling barback what they'll output lets it figure out the asset graph quickly, which enables some optimizations, but the big benefit comes from how declaring transformers interact with lazy transformers. If a lazy transformer's output is used as a declaring transformer's primary input, laziness will be preserved.

For example, suppose the dart2js transformer is followed by a jsmin transformer. This transformer implements the DeclaringTransformer interface to indicate that it's declaring:

class JSMin extends Transformer implements DeclaringTransformer {
// ...
Future declareOutputs(DeclaringTransform transform) {
transform.declareOutput(transform.primaryId.addExtension(".min"));
return new Future.value();
}
}

For the file app/myapp.dart, dart2js will declare that it emits app/myapp.dart.js. Then jsmin in turn will declare that it emits app/myapp.dart.js.min. When using pub serve, neither dart2js nor jsmin will run until app/myapp.dart.js.min is requested.

Note that LazyTransformer is a subtype of DeclaringTransformer, so laziness will be preserved through multiple lazy transformers as well.

What You Should Do

If your transformer takes a long time to run, mark it as lazy. That way, users of pub serve can only run your transformer when they need its outputs.

If you can tell what assets your transformer will emit by looking at its primary input, mark it as declaring. This will help barback optimize your asset graph and make your transformer interact well with lazy transformers.

If you make your transformer lazy or declaring, make sure your barback version constraint's lower bound is at least 0.11.1. You don't need to worry about compatibility with pub: older versions will just treat your transformers as though they weren't lazy or declaring, but will otherwise work fine.

Let me know if you have any questions!

- N

Nathan Weizenbaum

unread,
Apr 16, 2014, 7:39:11 PM4/16/14
to General Dart Discussion, Pete Blois, Sigmund Cherem, Emily Fortuna, Alan Knight
Please ignore the "DRAFT" at the beginning of this email! It is not in fact a draft.

James Hurford

unread,
Apr 16, 2014, 7:54:39 PM4/16/14
to mi...@dartlang.org
Is there any way to enforce order of lazy transformers, so that a transformer only happens after say dart2js?  That way you can write POST dart2js transformer that do some extra things to the compiled JS.

James


--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
James Hurford
terr...@gmail.com

There are two ways of constructing a software design: one way is to
make it so simple that there are obviously no deficiencies; the other is
to make it so complicated that there are no obvious deficiencies.
                                                       -- C.A.R. Hoare

Nathan Weizenbaum

unread,
Apr 16, 2014, 8:04:39 PM4/16/14
to General Dart Discussion
The author of the package using transformers has control over the transformer order. They can put a transformer after dart2js like so:

transformers:
- $dart2js
- post_dart2js_transformer

James Hurford

unread,
Apr 16, 2014, 8:23:16 PM4/16/14
to mi...@dartlang.org
So that works now, thanks, as based upon my imperfect memory, that wouldn't have worked previously.  Awesome now it does :-)

James


--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.

Nathan Weizenbaum

unread,
Apr 16, 2014, 8:45:59 PM4/16/14
to General Dart Discussion

You're right, previously adding any transformer after dart2js would have negated its laziness.

Sharon Zakhour

unread,
Apr 17, 2014, 11:39:44 AM4/17/14
to mi...@dartlang.org
Nathan, are you putting this info in the barback readme? Where will it go?

Nathan Weizenbaum

unread,
Apr 17, 2014, 3:07:37 PM4/17/14
to General Dart Discussion
In the internal barback documentation, this is all in the API documentation for the transformer classes. Issue 16684 is tracking adding appropriate documentation to dartlang.org.
Reply all
Reply to author
Forward
0 new messages