Flutter Web Engine
This directory contains the source code for the Web Engine.
Hacking on the Web Engine
If you are setting up a workspace for the first time, start by following the
instructions at Setting up the Engine development environment. In addition,
it is useful to add the following to your PATH environment variable:
ENGINE_ROOT/src/flutter/lib/web_ui/dev, so you can run thefeltcommand from anywhere.FLUTTER_ROOT/bin, so you can rundartandfluttercommands from anywhere.
Using felt
felt (stands for "Flutter Engine Local Tester") is a command-line tool that
aims to make development in the Flutter web engine more productive and pleasant.
To tell felt to do anything you call felt SUBCOMMAND, where SUBCOMMAND is
one of the available subcommands, which can be listed by running felt help. To
get help for a specific subcommand, run felt help SUBCOMMAND.
The most useful subcommands are:
felt build- builds a local Flutter Web engine ready to be used by the Flutter framework. To use the local engine build, pass--local-engine=host_debug_unoptto thefluttercommand, or todev/bots/test.dartwhen running a web shard, such asweb_tests.felt test- runs web engine tests. By default, this runs all tests using Chromium. Passing one or more paths to specific tests would run just the specified tests. Runfelt help testfor more options.
build and test take the --watch option, which automatically reruns the
subcommand when a source file changes. This is handy when you are iterating
quickly.
Examples
Builds the web engine, the runs a Flutter app using it:
felt build
cd path/to/some/app
flutter --local-engine=host_debug_unopt run -d chrome
Runs all tests in Chromium:
felt test
Runs a specific test:
felt test test/engine/util_test.dart
Runs multiple specific tests:
felt test test/engine/util_test.dart test/alarm_clock_test.dart
Enable watch mode so that the test re-runs every time a source file changes:
felt test --watch test/engine/util_test.dart
Runs tests in Firefox (requires a Linux computer):
felt test --browser=firefox
Chromium and Firefox support debugging tests using the browser's developer
tools. To run tests in debug mode add --debug to the test command, e.g.:
felt test --debug --browser=firefox test/alarm_clock_test.dart
Optimizing local builds
Concurrency of various build steps can be configured via environment variables:
FELT_DART2JS_CONCURRENCYspecifies the number of concurrentdart2jsprocesses used to compile tests. Default value is 8.FELT_TEST_CONCURRENCYspecifies the number of tests run concurrently. Default value is 10.
If you are a Google employee, you can use an internal instance of Goma (go/ma) to parallelize your ninja builds. Because Goma compiles code on remote servers, this option is particularly effective for building on low-powered laptops.
Test browsers
Chromium, Firefox, and Safari for iOS are version-locked using the browser_lock.yaml configuration file. Safari for macOS is supplied by the computer's operating system. Tests can be run in Edge locally, but Edge is not enabled on LUCI. Chromium is used as a proxy for Chrome, Edge, and other Chromium-based browsers.
Changing parameters in the browser lock is effective immediately when running tests locally. To make changes effective on LUCI follow instructions in [Rolling Browsers][#rolling-browsers].
Local testing in Safari using the iOS Simulator
- If you haven't already, install Xcode.
- The iOS version and device type used by web engine tests are specified in the browser_lock.yaml file. Install the iOS Simulator version using: Xcode > Preferences > Components
- Run
xcrun simctl list devices. If the simulator you want is not installed use step 4. - Use felt to create a simulator:
felt create_simulator
To run tests on ios-safari use the one of the following commands:
felt test --browser=ios-safari
felt test --browser=ios-safari test/alarm_clock_test.dart
Rolling browsers
When running tests on LUCI using Chromium, LUCI uses the version of Chromium fetched from CIPD.
Since the engine code and infra recipes do not live in the same repository there are few steps to follow in order to upgrade a browser's version. For now these instructins are most relevant to Chrome.
- Dowload the binaries for the new browser/driver for each operaing system (macOS, linux, windows).
- Create CIPD packages for these packages (more documentation is available for Googlers at go/cipd-flutter-web)
- Update the version in this repo. Do this by changing the related fields in
browser_lock.yamlfile.
Resources:
- For Chrome downloads link.
- Browser and driver CIPD packages (required speciall access; ping hackers-infra on Discord for more information)
- LUCI web recipe
- More general reading on CIPD packages link
Rolling CanvasKit
CanvasKit is versioned separately from Skia and rolled manually. Flutter consumes a pre-built CanvasKit provided by the Skia team, currently hosted on unpkg.com. When a new version of CanvasKit is available (check https://www.npmjs.com/package/canvaskit-wasm or consult the Skia team directly), follow these steps to roll to the new version:
- Make sure you have
depot_toolsinstalled (if you are regularly hacking on the engine code, you probably do). - If not already authenticated with CIPD, run
cipd auth-loginand follow instructions (this step requires sufficient privileges; contact #hackers-infra-🌡 on Flutter's Discord server). - Edit
dev/canvaskit_lock.yamland update the value ofcanvaskit_versionto the new version. - Run
dart dev/canvaskit_roller.dartand make sure it completes successfully. The script uploads the new version of CanvasKit to theflutter/web/canvaskit_bundleCIPD package, and writes the CIPD package instance ID to the DEPS file. - Send a pull request containing the above file changes. If the new version contains breaking changes, the PR must also contain corresponding fixes.
If you have questions, contact the Flutter Web team on Flutter Discord on the #hackers-web-🌍 channel.
Configuration files
browser_lock.yaml contains the version of browsers we use to test Flutter for
web. Versions are not automatically updated whenever a new release is available.
Instead, we update this file manually once in a while.
goldens_lock.yaml refers to a revision in the https://github.com/flutter/goldens
repo. Screenshot tests are compared with the golden files at that revision.
When making engine changes that affect screenshots, first submit a PR to
flutter/goldens updating the screenshots. Then update this file pointing to
the new revision.
canvaskit_lock.yaml locks the version of CanvasKit for tests and production
use.
Troubleshooting
Can't load Kernel binary: Invalid kernel binary format version.
Sometimes .dart_tool cache invalidation fails, and you'll end up with a
cached version of felt that is not compatible with the Dart SDK that you're
using.
In that case, any invocation to felt will fail with:
Can't load Kernel binary: Invalid kernel binary format version.
The solution is to delete the cached felt.snapshot files under lib/web_ui:
rm .dart_tool/felt.snapshot*
Hacking on the felt tool itself
If you are making changes in the felt tool itself, you need to be aware of
Dart snapshots. We create a Dart snapshot of the felt tool to make the startup
faster.
To run felt from sources, disable the snapshot using the FELT_USE_SNAPSHOT
environment variable:
FELT_USE_SNAPSHOT=false felt <command>