Skip to content

[web] Add onEntrypointLoaded to FlutterLoader.#108776

Merged
auto-submit[bot] merged 4 commits intoflutter:masterfrom
ditman:web-hot-restart-proper-init
Aug 3, 2022
Merged

[web] Add onEntrypointLoaded to FlutterLoader.#108776
auto-submit[bot] merged 4 commits intoflutter:masterfrom
ditman:web-hot-restart-proper-init

Conversation

@ditman
Copy link
Member

@ditman ditman commented Aug 2, 2022

The current promise-based API of flutter.js to inject the entrypoint and report back with an "engine initializer" object does not work well with Flutter web's hot-restart feature, and in fact, reverts to "auto" initialization upon hot restart as a "fix". See: #108403. This is a problem for incoming changes on flutter, where we might want to pass custom parameters to the initializeEngine/runApp JS methods.

onEntrypointLoaded event

This PR adds a new onEntrypointLoaded method to the FlutterLoader provided by flutter.js that triggers a new "flutter:entrypoint-loaded" event every time the app (hot)restarts, so the rest of the custom initialization code can run.

The new init sequence of a flutter app that survives hot-restart looks like:

<script>
  window.addEventListener('load', function(ev) {
      // Download main.dart.js
      _flutter.loader.loadEntrypoint({
        onEntrypointLoaded: onEntrypointLoaded,
        serviceWorker: {
          serviceWorkerVersion: serviceWorkerVersion,
        }
      });

      // Once the entrypoint is ready, do things!
      async function onEntrypointLoaded(engineInitializer) {
        const appRunner = await engineInitializer.initializeEngine();
        appRunner.runApp();
      }
  });
</script>

This separation also makes quite obvious what things will run once (loadEntrypoint) vs what will run every time the engine hot-restarts (onEntrypointLoaded).

Detangle flutter.js ServiceWorkerLoader from EntrypointLoader

In a first (small) step towards modularization of the library, this change detangles the old "loadWithServiceWorker" logic into: load service worker, then load the entrypoint.

The old logic basically attempted very hard to load a service worker, but if for any case it'd fail, it'd always "fall back" to the _loadEntrypoint method.

The new logic separates the Service Worker install logic from the Entrypoint loader, so it can be loaded in two steps:

loadServiceWorker --(warn of errors, but always continue)--> loadEntrypoint

The new structure makes it easier to ES-Modularize the file in the future, or inject custom behavior for any/all of the steps of the bootstrap. (Some extra modularization is still required from the FlutterLoader bits, but this looks like a nice start).

Issues

Tests

Backwards-compatibility

  • The code above is backwards compatible with all former initializations of flutter, as demonstrated by the different types of integration tests we have so far.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App c: contributor-productivity Team-specific productivity, code health, technical debt. e: flutter.js Issues with Flutter web custom initialization through JS APIs platform-web Web applications specifically tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[web] Custom Flutter initialization should survive hot restart

3 participants