
This makes several changes to flutter web app bootstrapping. * The build now produces a `flutter_bootstrap.js` file. * By default, this file does the basic streamlined startup of a flutter app with the service worker settings and no user configuration. * The user can also put a `flutter_bootstrap.js` file in the `web` subdirectory in the project directory which can have whatever custom bootstrapping logic they'd like to write instead. This file is also templated, and can use any of the tokens that can be used with the `index.html` (with the exception of `{{flutter_bootstrap_js}}`, see below). * Introduced a few new templating tokens for `index.html`: * `{{flutter_js}}` => inlines the entirety of `flutter.js` * `{{flutter_service_worker_version}}` => replaced directly by the service worker version. This can be used instead of the script that sets the `serviceWorkerVersion` local variable that we used to have by default. * `{{flutter_bootstrap_js}}` => inlines the entirety of `flutter_bootstrap.js` (this token obviously doesn't apply to `flutter_bootstrap.js` itself). * Changed `IndexHtml` to be called `WebTemplate` instead, since it is used for more than just the index.html now. * We now emit warnings at build time for certain deprecated flows: * Warn on the old service worker version pattern (i.e.`(const|var) serviceWorkerVersion = null`) and recommends using `{{flutter_service_worker_version}}` token instead * Warn on use of `FlutterLoader.loadEntrypoint` and recommend using `FlutterLoader.load` instead * Warn on manual loading of `flutter_service_worker.js`. * The default `index.html` on `flutter create` now uses an async script tag with `flutter_bootstrap.js`.
90 lines
3.3 KiB
HTML
90 lines
3.3 KiB
HTML
<!DOCTYPE HTML>
|
|
<!-- Copyright 2014 The Flutter Authors. All rights reserved.
|
|
Use of this source code is governed by a BSD-style license that can be
|
|
found in the LICENSE file. -->
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
|
|
|
<title>Web Test</title>
|
|
<!-- iOS meta tags & icons -->
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
|
<meta name="apple-mobile-web-app-title" content="Web Test">
|
|
|
|
<!-- Favicon -->
|
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
|
<link rel="manifest" href="manifest.json">
|
|
</head>
|
|
<body>
|
|
<!-- This script installs service_worker.js to provide PWA functionality to
|
|
application. For more information, see:
|
|
https://developers.google.com/web/fundamentals/primers/service-workers -->
|
|
<script>
|
|
var serviceWorkerVersion = null;
|
|
var scriptLoaded = false;
|
|
function loadMainDartJs() {
|
|
if (scriptLoaded) {
|
|
return;
|
|
}
|
|
scriptLoaded = true;
|
|
var scriptTag = document.createElement('script');
|
|
scriptTag.src = 'main.dart.js';
|
|
scriptTag.type = 'application/javascript';
|
|
document.body.append(scriptTag);
|
|
}
|
|
|
|
if ('serviceWorker' in navigator) {
|
|
// Service workers are supported. Use them.
|
|
window.addEventListener('load', function () {
|
|
// Wait for registration to finish before dropping the <script> tag.
|
|
// Otherwise, the browser will load the script multiple times,
|
|
// potentially different versions.
|
|
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
|
|
navigator.serviceWorker.register(serviceWorkerUrl)
|
|
.then((reg) => {
|
|
function waitForActivation(serviceWorker) {
|
|
serviceWorker.addEventListener('statechange', () => {
|
|
if (serviceWorker.state == 'activated') {
|
|
console.log('Installed new service worker.');
|
|
loadMainDartJs();
|
|
}
|
|
});
|
|
}
|
|
if (!reg.active && (reg.installing || reg.waiting)) {
|
|
// No active web worker and we have installed or are installing
|
|
// one for the first time. Simply wait for it to activate.
|
|
waitForActivation(reg.installing ?? reg.waiting);
|
|
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
|
|
// When the app updates the serviceWorkerVersion changes, so we
|
|
// need to ask the service worker to update.
|
|
console.log('New service worker available.');
|
|
reg.update();
|
|
waitForActivation(reg.installing);
|
|
} else {
|
|
// Existing service worker is still good.
|
|
console.log('Loading app from service worker.');
|
|
loadMainDartJs();
|
|
}
|
|
});
|
|
|
|
// If service worker doesn't succeed in a reasonable amount of time,
|
|
// fallback to plaint <script> tag.
|
|
setTimeout(() => {
|
|
if (!scriptLoaded) {
|
|
console.warn(
|
|
'Failed to load app from service worker. Falling back to plain <script> tag.',
|
|
);
|
|
loadMainDartJs();
|
|
}
|
|
}, 4000);
|
|
});
|
|
} else {
|
|
// Service workers not supported. Just drop the <script> tag.
|
|
loadMainDartJs();
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|