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?
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.
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.
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.
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.
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.
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.
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
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)
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:
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 %>).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With