Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails & service worker

I'm trying to use a service worker in my Ruby on Rails application.

I need to use some erb features in my app/javascripts/service-worker.js.erb file. The service worker registration script looks like this:

var registerServiceWorker = function() {
  navigator.serviceWorker.register(
    '<%= asset_path('service-worker.js') %>',
    { scope: '/assets/' }
  )
  .then(function() {
    console.info('Service worker successfully registered');
  })
  .catch(function(error) {
    console.warn('Cannot register sercie worker. Error = ', error);
  });
}

This does not work; I never get promise here:

navigator.serviceWorker.ready.then

I also tried ./ and / scopes but I got this error:

DOMException: Failed to register a ServiceWorker: The path of the provided scope ('/') is not under the max scope allowed ('/assets/'). Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope.

If I move my service-worker.js to the public folder, remove the .erb extension and change scope to ./, everything works great, but I have no template engine there.

Any suggestions?

like image 498
user525717 Avatar asked May 02 '15 21:05

user525717


People also ask

What is Ruby on the Rails used for?

Ruby on Rails is used in all types of industries to build web apps and services. This includes applications like marketing websites, CMSs, eCommerce sites, and custom web applications. It's a popular web framework for startups because its ease of use makes for quick application development with small teams.

Is Ruby on Rails still relevant 2022?

Ruby's and Ruby on Rails' Overall Popularity Although way behind main contenders, such as PHP or Python, Ruby still makes the cut for the 20 most popular programming languages list in 2022. The 2022 edition of Stack Overflow Annual Developer Survey also places RoR in a similar spot.

What programming language is Ruby on Rails?

Ruby on Rails, sometimes known as "RoR" or just "Rails," is an open source framework for Web development in Ruby, an object-oriented programming (OOP) language similar to Perl and Python.

Is Ruby on Rails backend or frontend?

Seeing as Ruby on Rails runs on a web server and serves up information to client programs (web browsers), it's said to be a server-side or backend application.

Is Ruby on Rails vs node JS?

Node. js is very flexible and can do things out of the box, but you will have to write some code and install some modules. Ruby on Rails is not a flexible framework and makes you adhere to its way of doing things out of the box. You have to build your app in a particular way.

Is Ruby on Rails outdated?

In the modern tech world, AI-powered applications are entering the scene. And it becomes significant for a programming language or framework to be ML-friendly. That's why some developers may claim Ruby and Rails outdated – Rails is really not designed for Machine learning.


4 Answers

There's now a gem, serviceworker-rails that will allow you to proxy requests for serviceworker scripts in the asset pipeline. Because of the way browsers register serviceworker scripts, it's best to avoid caching them.

Sprockets will fingerprint assets and Rails (or your webserver) typically serves the compiled files with aggressive caching headers from the /assets directory.

What we want is the ability to customize service worker paths and response headers and still get Sprockets preprocessing, i.e. CoffeeScript/ES2015 to JavaScript transpilation.

The serviceworker-rails gem inserts middleware to your Rails stack that will proxy a request for /serviceworker.js (for example) to the corresponding fingerprinted, compiled asset in production. In development, you get the auto-reloading behavior you would expect. You can set up multiple serviceworkers at different scopes as well.

https://github.com/rossta/serviceworker-rails

like image 170
rossta Avatar answered Sep 20 '22 19:09

rossta


Because of the security purpose, you can't register ServiceWorker in higher scope than from where it was executed.

If you really need template engine, you may try to dynamically load JS file from file in your /public folder (How do I include a JavaScript file in another JavaScript file?). Currently Service-Worker-Allowed HTTP header is not implemented yet in Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=1130101)

like image 35
Karol Klepacki Avatar answered Sep 23 '22 19:09

Karol Klepacki


I'm running into this problem now as well. Based on my research, I think the proper way for a Rails application to handle service workers is to serve the service worker javascript file normally using the Asset pipeline, scope the service worker using the scope option (like you have done), and then use the Service-Worker-Allowed HTTP header to explicitly allow the new scope.

Unfortunately, at the moment there are several barriers to implementing this method:

  1. Rails 4 (apparently) does not allow adding HTTP headers to Assets it serves, other than the cache-control header. To work around this you could add a Rack plugin as detailed in this S.O. answer, or in production if you are using an Asset server such as Nginx, you can get around this by having Nginx add the HTTP header. Though this doesn't help during development.
  2. Rails 5 does allow adding HTTP headers to Assets however, as detailed in this blog post.
  3. Browser support for service workers and the Service-Worker-Allowed HTTP header is currently poor.
like image 42
John Avatar answered Sep 23 '22 19:09

John


Just do it in the root directory. For example, I put a route

get 'service-worker(.format)', to: 'core#service_worker'

Then just put in your controller (core_controller.rb in my example)

def service_worker
end

Then create app/views/core/service_worker.js.erb and put your JS there (including any <%= stuff %>).

like image 29
Jason Avatar answered Sep 24 '22 19:09

Jason