Webpacker: Service Workers

Created on 31 May 2017  路  11Comments  路  Source: rails/webpacker

Add service workers support.
There are 2 problems that I'm having now.
Service-worker should be served from the same origin as a website.
When adding service-worker.js into webpack entry points, and running ./bin/webpack-dev-server will produce this warning.
DOMException: Failed to register a ServiceWorker: The origin of the provided scriptURL ('http://0.0.0.0:8080') does not match the current origin ('http://localhost:3000')

Service workers have a scope which represents a URL that defines a service worker's registration scope, what range of URLs a service worker can control.
After the activation step, the service worker will control all pages that fall under its scope, so when registering worker from /packs/servise-worker.js and running ./bin/webpack-watcher it will control only localhost:300/packs/* pages.

Most helpful comment

I was trying to tackle this issue and I successfully patched webpacker configuration to the following:

  • compile service workers without a hash appended
  • put them into the public folder
  • compile everything else into public/packs as before
  • have public as root folder to be able to use hot module reloading.

I've put together a guide about it here and here is the patch I used. Not the best code so far but it's a proof of work! This can be achieved and it rocks! 馃憤 I had also to patch the rack proxy to webpack-dev-server to use hot module reload (it's in the same repository). Could this be taken as inspiration for a PR?

All 11 comments

I'm just starting to look into service workers and found the same issues. We already have a solution to the first problem: Use development: compile: true in webpacker.yml to lazy compile webpack from the development server and serve it there too. Then the URLs remain the same and that works. (Requires latest webpacker from github).

For the second issue, we need a different solution for the output directory. Really unfortunate that the service worker spec is so inflexible. Anyway, I'm thinking we might just make a specific configuration option for a root service worker. Feel free to open a PR attempting that!

@dhh Also, I forget to mention that there is a problem with caching rails assets pipeline generated files, as files cached by their name and my solution was to create serviceworker.js.erb file inside of which cache

 '<%= ActionController::Base.helpers.compute_asset_path("application.js") %>',
 '<%= ActionController::Base.helpers.compute_asset_path("application.css") %>'

files. Is there any way to give webpacker access on those file names so I can use them inside js file?

Yeah, we should come up with a complete solution for service workers and their configuration. I'm currently on a research trip into the land. Hopefully I'll come back with something. But agree that we should have some kind of bridge.

@artemgurzhii The issue is fixed in latest master so service workers should now register fine. Have you tried it lately?

@gauravtiwari We still have the problem that service workers are being mounted under /packs rather than the root. Which means they don't really work. Need a way to get them mounted on the root. One idea is to simply compile to /packs, as per now, but then find a way to either symlink or just copy the file into the root as well.

@dhh Ahh I see - giving this a try now. Are you using sw-precache plugin or custom implementation? https://github.com/goldhand/sw-precache-webpack-plugin

Not using any thing except a hand-rolled simple example at the moment. And I immediately hit the issue of service workers needing to be on the same origin and at the root.

As one point of reference, I'm using Webpack to bundle assets for my blog with a ServiceWorker without any special SW libraries or plugins: https://github.com/rossta/rossta.github.com/blob/develop/webpack.config.js

My example exports two separate Webpack configs, one for the site bundle and one for the serviceworker script. This allows me to target a different output for the serviceworker and decide which loaders and plugins to share or setup differently as needed.

For Webpacker, some considerations would be to omit the fingerprint from the filename so we can have a canonical URL and make it available at the root, e.g. /serviceworker.js. We'd also need to provide a host option separate from asset_host since the script must be available from the same domain (as opposed to a CDN).

Once registered, browsers are supposed to check for updated serviceworker script content regularly so devs would also want to avoid setting long term caching headers on the webservers for these scripts (not sure if browsers ignore caching headers for SW or not but it seems prudent to avoid setting them in the first place).

@gauravtiwari how you add the sw.js at the root domain using the sw-precache-webpack-plugin?
This issue was fixed?

Any update on this?

I was trying to tackle this issue and I successfully patched webpacker configuration to the following:

  • compile service workers without a hash appended
  • put them into the public folder
  • compile everything else into public/packs as before
  • have public as root folder to be able to use hot module reloading.

I've put together a guide about it here and here is the patch I used. Not the best code so far but it's a proof of work! This can be achieved and it rocks! 馃憤 I had also to patch the rack proxy to webpack-dev-server to use hot module reload (it's in the same repository). Could this be taken as inspiration for a PR?

Was this page helpful?
0 / 5 - 0 ratings