Questions? Suggestions? Found a bug? Please file an issue or start a discussion.
Web compilers for build_runner.
Installation
This package is intended to be used as a development dependency for users
of package:build who want to run code in a browser. Simply add the
following to your pubspec.yaml:
dev_dependencies:
build_web_compilers:
Usage
If you are using the autogenerated build script (going through
dart run build_runner <command> instead of handwriting a build.dart file),
then all you need is the dev_dependency listed above.
Configuration
By default, this package uses the Dart development compiler (dartdevc,
also known as DDC) to compile Dart to JavaScript. In release builds (running
the build tool with --release), dart2js is used as a compiler.
In addition to compiling to JavaScript, this package also supports compiling to
WebAssembly. Currently, dart2wasm needs to be enabled with builder options.
To understand the impact of these options, be aware of differences between
compiling to JavaScript and compiling to WebAssembly:
- Dart has two compilers emitting JavaScript:
dart2jsanddartdevc(which supports incremental rebuilds but is typically only used for development). For both JavaScript compilers,build_web_compilersgenerates a primary entrypoint script and additional module files or source maps depending on compiler options. - Compiling with
dart2wasmgenerates a WebAssembly module (a.wasmfile) and a JavaScript module (a.mjsfile) exporting functions to instantiate that module.dart2wasmalone generates no entrypoint file that could be added as a<script>tag.
In addition to invoking compilers, build_web_compilers can emit an entrypoint
file suitable for dart2wasm. When both dart2wasm and a JavaScript compiler
are enabled, the entrypoint file runs a feature detection for WasmGC and loads
either the WebAssembly module or the JavaScript file depending on what the
browser supports.
Compiler arguments
To customize compilers, you will need to add a build.yaml file configuring
the build_web_compilers:entrypoint builder, similar to the following:
targets:
$default:
builders:
build_web_compilers:entrypoint:
# These are globs for the entrypoints you want to compile.
generate_for:
- test/**.browser_test.dart
- web/**.dart
options:
compilers:
# All compilers listed here are enabled:
dart2js:
# List any dart2js specific args here, or omit it.
args:
- O2
dart2wasm:
args:
- O3
build_runner runs development builds by default, but can use builders with a
different configuration for --release builds. For instance, if you wanted to
compile with dartdevc only on development and dart2js + dart2wasm for
release builds, you can use this configuration as a starting point:
targets:
$default:
builders:
build_web_compilers:entrypoint:
generate_for:
- test/**.browser_test.dart
- web/**.dart
dev_options:
compilers:
dartdevc:
release_options:
compilers:
dart2js:
args:
- O2
dart2wasm:
args:
- O3
Customizing emitted file names
The file names emitted by build_web_compilers can be changed. The default
names depend on which compilers are enabled:
- When only
dart2jsordartdevcis enabled, a single.dart.jsentrypoint is emitted. - When only
dart2wasmis enabled, a single.dart.jsentrypoint (loading a generated.wasmmodule through a.mjshelper file) is generated. - When both
dart2wasmand a JavaScript compiler are enabled, then:- The output of the JavaScript compiler is named
.dart2js.jsor.ddc.jsdepending on the compiler. dart2wasmcontinues to emit a.wasmand a.mjsfile.- An entrypoint loader named
.dart.jsthat loads the appropriate output depending on browser features is generated.
- The output of the JavaScript compiler is named
All names can be overridden by using the loader option or the extension
flag in compiler options:
targets:
$default:
builders:
build_web_compilers:entrypoint:
options:
loader: .load.js
compilers:
dart2js:
extension: .old.js
dart2wasm:
extension: .new.mjs
This configuration uses both dart2js and dart2wasm, but names the final
entrypoint for a main.dart file main.load.js. That loader will either load
a .new.mjs file for WebAssembly or a .old.js for pure JavaScript.
Note that the loader option is ignored when dart2wasm is not enabled, as
it's the compiler requiring an additional loader to be emitted.
Customizing the WebAssembly loader
In some cases, for instance when targeting Node.JS, the generated loader for
dart2wasm may be unsuitable. The builtin loader can be disabled by setting
the option to null:
targets:
$default:
builders:
build_web_compilers:entrypoint:
options:
loader: null
compilers:
dart2js:
dart2wasm:
In this case, you need to use another builder or a predefined loader instead.
Configuring -D environment variables
dartdevc is a modular compiler, so in order to ensure consistent builds
in every module environment variables must be configured globally. Configure
with a mapping in YAML. Environment defined variables can be read with
const String.fromEnvironment and const bool.fromEnvironment. For example:
global_options:
build_web_compilers:ddc:
options:
environment:
SOME_VAR: some value
ANOTHER_VAR: false
These may also be specified on the command line with a --define argument.
webdev serve -- '--define=build_web_compilers:ddc=environment={"SOME_VAR":"changed"}'
For dart2js, use the args option within the dart2js compiler entry. This
may be configured globally, or per target.
targets:
$default:
builders:
build_web_compilers:entrypoint:
options:
compilers:
dart2js:
args:
- -DSOME_VAR=some value
- -DANOTHER_VAR=true
To apply variables across multiple compilers, they have to be added to each one:
targets:
$default:
builders:
build_web_compilers:entrypoint:
options:
compilers:
dart2js:
args:
- -DSOME_VAR=some value
- -DANOTHER_VAR=true
dart2wasm:
args:
- -DSOME_VAR=some value
- -DANOTHER_VAR=true