Pub has two commands for working with transformers,
serve. Both of those currently are hardcoded to only see stuff in your package's
lib/ directories. We've been wanting to have support for
example, and others for a while (see #14673 and #15924). This sketches out what I'm thinking to handle this. Feedback is welcome!
The basic idea is that build and serve will be able to see of these directories:
web/. Transformers will be able to run on assets in any of those.
Right now, pub build creates a
build/ directory containing the output of the build process. That directory only contains the outputs whose path is within
web/. If we start building tests and examples into there, stuff could start colliding.
So the first change is that we'll reorganize the
build/ directory to match your package. Outputs within
web/ will be within
web/ in the
build/ directory. Instead of:
This means if you have deploy scripts that read stuff out of
build/, you'll need to change them to look in
build/web/ when/if we make this change.
pub build command
The main problem with running pub build on all of those directories is performance. If your
To handle that, we'll allow an argument to
pub build to specify which directory (or directories) to build. I'm thinking something like:
pub build # Just build "web", like current behavior. pub build web # Equivalent to above. pub build * # Build everything. pub build test # Build tests. pub build web test example # Build all three of those. pub build example/foo # Just build the "foo" example subdirectory.
I just made this up, though, so it probably needs some hashing out.
When you run this, it will still completely clean out your
build directory. If you run:
pub build test
and then run:
pub build example
build/ directory will only have
example in it. You could have made changes to stuff between those two
pub build runs. If we left the previous build in there, you'd end up with a mixture of inconsistent outputs from different points in time.
pub serve command
The dev server will follow this. It will serve files out of all of the above directories. This means the URL structure needs to change a bit. To hit your
myapp.html file in
web/ instead of:
That way we can have non-colliding URLs to reach stuff outside of
Again, the challenge here is dart2js compile times. Pub serve waits until everything has been built once before it serves any assets (since it doesn't know which outputs will exist until the transformers have run). If we ran dart2js on all of your tests, the server would take forever to start up. Worse, touching a file imported by any of those tests would trigger a rebuild on all of them.
Our plan for that is to make the dart2js transformer run lazily. By default, it won't run the dart2js transformer on any entrypoints. You'll get a nice, fast startup, and you can keep iterating in dartium quickly without dart2js being in the loop at all.
When you do want to compile something to JS, it will determine this automatically. The first time your browser requests the compiled JS for some file (i.e. the first time pub serve gets a request for a
.dart.js URL), pub serve will say, "OK, looks like I need to enable dart2js for that entryoint."
It will then enable dart2js to run on just that entrypoint. After that, it will keep it enabled. So when you make changes to Dart code, it will immediately start re-compiling it to JS for you.
Making the above work correctly in the general case is tricky, but I've got some ideas here that I think will work.
What do you think?