tool: build both Wasm and JS targets for flutter run --wasm#186253
tool: build both Wasm and JS targets for flutter run --wasm#186253shivanshu877 wants to merge 8 commits into
flutter run --wasm#186253Conversation
Fixes flutter#172006. `flutter build web --wasm` already produces both a Wasm and a JS build of the app so the runtime web loader can fall back to JS at runtime on browsers that don't support WasmGC. `flutter run --wasm` only produces the Wasm build, so attempting to run on a non-WasmGC browser (e.g. iOS Safari) fails with: FlutterLoader could not find a build compatible with configuration and environment. Bring the run path in line with build by returning a list of compiler configurations (Wasm + JS when --wasm is set, JS-only otherwise) from ResidentWebRunner._compilerConfigs and passing it through to WebBuilder.buildWeb at both call sites.
Per @stuartmorgan-g's feedback, this PR makes a behavioral change (returning a list of compiler configs instead of a single one when --wasm is passed to `flutter run`) and was missing the corresponding tests. Adds: * @VisibleForTesting accessor `debugCompilerConfigs` on ResidentWebRunner that exposes the otherwise-private getter. * Two regression tests: - `--wasm produces both Wasm and JS compiler configs for runtime fallback` — asserts that with `webUseWasm: true` the runner emits exactly two configs, one per CompileTarget. - `no --wasm produces only a JS compiler config` — asserts the default path still emits a single JsCompilerConfig.
There was a problem hiding this comment.
Code Review
This pull request modifies ResidentWebRunner to support multiple compiler configurations, specifically adding a JavaScript fallback when WebAssembly is enabled. It replaces the single _compilerConfig property with a list-based _compilerConfigs getter and introduces a @VisibleForTesting property for verification. Regression tests have been added to ensure the correct configurations are generated based on the Wasm flag. Feedback suggests refactoring the _compilerConfigs getter to eliminate duplication by extracting the shared JsCompilerConfig initialization into a local variable.
Extract the JsCompilerConfig.run constructor into a local variable so the JS-fallback (Wasm + JS) and JS-only branches share a single source. Pure refactor — no behaviour change.
bkonyi
left a comment
There was a problem hiding this comment.
Overall, this LGTM! I do want a member of the Flutter Web team to sign off as well.
|
autosubmit label was removed for flutter/flutter/186253, because - The status or check suite Linux analyzer_benchmark has failed. Please fix the issues identified (or deflake) before re-applying this label. |
* lib/src/isolated/resident_web_runner.dart:
- Omit obvious JsCompilerConfig type annotation on the dedup'd local
introduced by the previous refactor (omit_obvious_local_variable_types).
* test/general.shard/resident_web_runner_test.dart:
- Reorder web/compiler_config.dart import so the web/ block stays
alphabetical (directives_ordering).
- Replace const BuildInfo(BuildMode.debug, null, ...) with BuildInfo.dummy
in the new --wasm regression test — the linter confirmed they're
equivalent objects (use_named_constants).
- Drop two obvious ResidentWebRunner type annotations on locals where
the right-hand side already includes 'as ResidentWebRunner'
(omit_obvious_local_variable_types).
Verified locally with 'flutter analyze' on both files: no issues found.
|
Hi @shivanshu877! If you can please address the comment left by myself and @mdebbar, we can move forward with merging this PR. Thanks! |
|
@nshahan can I get you to rubber stamp this PR? |
nshahan
left a comment
There was a problem hiding this comment.
To me it seems like this change complicates our support matrix and makes it less clear to a developer what version of the app they are running and what tooling should be supported.
What mode is this running? IIUC flutter run defaults to the debug mode. There are actually two JavaScript compilers under the hood. DDC is used for --debug and also runs developer tooling infra to support hot reload, hot restart, and debugging. --profile and --release use dart2js which doesn't support the extra developer tooling.
Running that with --wasm seems to force the use of dart2wasm potentially in any mode.
What JavaScript compiler should we use? This seems to use dart2js and skip the development tooling in any mode but I'm not really sure. The test doesn't tell me what actually happens if we run with this flag.
…nshahan @nshahan raised a real concern on flutter#186253: it wasn't clear from the code or tests which JavaScript compiler runs in which mode when the new '--wasm' JS fallback is picked, or whether the fallback silently loses DDC-based dev tooling. Both concerns are documentation, not behavior — the code already picks JsCompilerConfig (dart2js) unambiguously. Make that explicit: * Docstring on ResidentWebRunner._compilerConfigs now spells out the full mode / --wasm matrix in a table, calls out which branch of _runOnce actually consults this getter (isDebug && !webUseWasm routes through WebDevFS + DDC and does not), and explains that hot reload was already unavailable with --wasm before this getter was added (see reloadIsRestart) — the new JS fallback only widens browser compatibility, it does not remove tooling. * Assertions in the two --wasm regression tests now check the concrete runtime types (WasmCompilerConfig / JsCompilerConfig) and their relative order — not just the CompileTarget enum count — so the test itself documents 'JS side is dart2js, never DDC'. Test names also updated to reflect the fallback-preference ordering.
|
Thanks for pushing back on this @nshahan — the ambiguity you're pointing at is real, and I think it's a documentation / test-clarity gap rather than a behavior change. Pushed Where DDC actually lives in Full mode /
The JS side of the fallback is always dart2js ( Tests strengthened. The two The commit message and PR body still describe the change accurately: no behavior change beyond the JS fallback, no new dev-tooling regression. If you'd like the docstring to also reference an issue tracker item that discusses adding a DDC fallback for the |
|
@shivanshu877 @kevmoo |

Description
Fixes #172006.
flutter build web --wasmalready produces both a Wasm and a JS build of the app, so the Flutter web loader can fall back to JS at runtime on browsers that don't support WasmGC.flutter run --wasmonly produces the Wasm build, so attempting to run on a non-WasmGC browser (e.g. iOS Safari connected via remote debugging) fails with:This PR brings the
flutter run --wasmpath in line withflutter build web --wasmby returning a list of compiler configurations (Wasm + JS when--wasmis set, JS-only otherwise) fromResidentWebRunner._compilerConfigsand passing it through toWebBuilder.buildWebat both invocation sites.Repro (from the original issue)
Tests
Added two regression tests in
resident_web_runner_test.dart:--wasm produces both Wasm and JS compiler configs for runtime fallback— asserts the runner emits exactly two configs (one perCompileTarget) whenwebUseWasm: true.no --wasm produces only a JS compiler config— asserts the default path still emits a singleJsCompilerConfig.Required exposing the otherwise-private getter as
@visibleForTesting List<WebCompilerConfig> get debugCompilerConfigs. All 52 tests inresident_web_runner_test.dartpass.This PR replaces #186237 (closed for a clean conversation timeline).
Pre-launch Checklist