Skip to content

Conversation

@jonahwilliams
Copy link
Contributor

@jonahwilliams jonahwilliams commented Jan 7, 2020

Description

A service worker allows for add to home screen, along with offline support. The worker contains a map of all resource files to be cached, along with the file hash of each. This will allow us to support incremental updates in a future change, as well as ensuring that any changes to the web project trigger the byte-difference algorithm to cause a service worker update (without requiring manual intervention or changes by the project author)

@fluttergithubbot fluttergithubbot added tool Affects the "flutter" command-line tool. See also t: labels. work in progress; do not review labels Jan 7, 2020
@jonahwilliams jonahwilliams changed the title [WIP][flutter_tools] Add basic service worker generation support to web applications [flutter_tools][web] Add basic service worker generation support to web applications Jan 12, 2020
@jonahwilliams jonahwilliams marked this pull request as ready for review January 12, 2020 02:57
<!-- 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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent -2 spaces

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/service_worker.js');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason I feel like we should use a more specific name, such as flutter_service_worker.js.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment above still references to service_worker.js, just so you know

if (!basename.contains('main.dart.js')) {
continue;
}
// In release mode, do not output deps file or source map.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not? It is common for one to need to debug a release build.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They can still be debugged with run release though. Do you want sourcemaps in release builds?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least on our side we'd like to build the gallery on every commit and deploy it to something like Firebase hosting, so that if there's a bug we can quickly find the version where it started and debug it. So in that case it would be useful to have sourcemaps for all types of builds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, I'll leave them in for now then

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

${resources.entries.map((MapEntry<String, String> entry) => '"${entry.key}": "${entry.value}"').join(",\n")}
};
self.addEventListener('install', function (event) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers, activation always follows installation, so if we add all keys to the cache here, then in the activation even we will delete them all and add them again. It seems the only thing that should go in the "install" event is things that do not change from one version of the service worker to the next.

IOW, I think if you delete the "install" event listener entirely the service worker will continue working.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

install is only triggered when the sw is added, removing 'install' sgtm

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

jonahwilliams added 2 commits January 13, 2020 13:02
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/service_worker.js');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 here - other places are calling this flutter_service_worker.js - this template produces an error message:

Uncaught (in promise) TypeError: Failed to register a ServiceWorker for scope ('http://localhost:8000/') with script ('http://localhost:8000/service_worker.js'): A bad HTTP response code (404) was received when fetching the script.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, forgot to update this one. Thanks for the heads up!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix pending here: #48778

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello. I have same errror. Created issue: #49479

final String serviceWorker = generateServiceWorker(uriToHash);
serviceWorkerFile
.writeAsStringSync(serviceWorker);
depfile.writeToFile(environment.buildDir.childFile('service_worker.d'));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this file also be a flutter_service_worker.d ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this matches the name declared on 293

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, I was just testing you. 😉

@jonahwilliams jonahwilliams deleted the add_service_worker_generation branch January 14, 2020 03:22
mehere pushed a commit to mehere/flutter that referenced this pull request Jan 14, 2020
return response;
}
return fetch(event.request, {
credentials: 'include'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're breaking all outgoing CORS requests with this (#51252). Any particular reason for overriding the credentials?

@BirjuVachhani
Copy link

BirjuVachhani commented Jun 9, 2020

I tried flutter's master channel and dev channel but myPWA is not showing Install to Home Screen button on desktop or mobile. I traced it back to the generated flutter_service_worker.js file and following modifications fixed the issue.
Instead of

return cache.addAll(Object.keys(RESOURCES));

replacing it with:

cache.addAll(Object.keys(RESOURCES));
return cache;

here's the working code:

self.addEventListener("install", (event) => {
  return event.waitUntil(
    caches.open(TEMP).then((cache) => {
      // Provide a no-cache param to ensure the latest version is downloaded.
      cache.addAll(CORE.map((value) => new Request(value, {'cache': 'no-cache'})));
      return cache;
    })
  );
});

Since the file is auto-generated, my changes won't survive future builds. Could someone look into this? I am happy to provide any needed information.

@rafa-js
Copy link

rafa-js commented Jun 23, 2020

As flutter_service_worker.js fetches from cache first of all, it doesn't detect new deployed version of my app.

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request)
      .then(function (response) {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

Do you guys have anything in mind to allow different fetch strategies?

@hiroshihorie
Copy link

@rseibane I'm having the same issue, this was confusing, did you solve this?

@lukeblevins
Copy link

@rseibane I was having the same issue, and that fixes it temporarily. Thank you!

@jonahwilliams
Copy link
Contributor Author

Hi, looks like there has been a lot of activity on this PR, I'd really appreciate it if you opened new bugs instead of discussing here - you are essentially shouting into the void, because by default most people unsubscribe from submitted PRs.

@phackwer
Copy link

Guys, feature requested for cleaning up the cache based on Build Number. Obviously, there is a problem that PackageInfo is broken on the web (which would be great to have this to be able to implement the feature requested) but I've done a workaround to force cache clearing before service worker instantiation based on saving the build number in a version.txt file during the pipelines. Well, there is a "workaround" in the link bellow, but definitely this should be done in the service worker based in the package info.

#63500

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.