如何在 rails 7 中使用 importmap 注册 service-worker?

问题描述 投票:0回答:2

更新于 1/18/2023 以反映 Bijan

的回答

面对问题

我想将使用 importmap 的 Rails 7 创建的 Web 应用程序转换为 PWA。 但是,我在使用 importmap 注册服务工作者时遇到了问题。 如果你能给我一些建议,我将不胜感激。

现状

开始尝试使用this gem,但是在importmap环境下不行,于是参考了this site,但是不行

灯塔检查的结果如下。

开发环境

红宝石 3.1.3
轨道 7.0.3
importmap-rails 1.1.2
tailwindcss-rails 2.0.10
链轮 4.1.1.

相关源码

config/route.rb


    get '/service_worker', to: 'service_workers#service_worker'
    get '/offline', to: 'service_workers#offline'

./应用程序/控制器
├──

service_workers_controller.rb

class ServiceWorkerController < ApplicationController
    protect_from_forgery except: :service_worker
    skip_before_action :require_login
    
    def service_worker; end
    
    def offline; end
end

./app/views/service_worker
├── offline.html.erb
└──

service-worker.html.erb

<script>
  const VERSION = 'v1';
  const NAME = 'app_name-';
  const CACHE_NAME = NAME + VERSION;
  const urlsToCache = [
      "./offline.html"
  ];
    
    
  self.addEventListener('install', function (event) {
      event.waitUntil(
        caches.open(CACHE_NAME).then(function (cache) {
          console.log('Opened cache');
          return cache.addAll(urlsToCache);
        })
      );
  });
    
  self.addEventListener('fetch', function (event) 
      if (event.request.cache === 'only-if-cached' && 
  event.request.mode !== 'same-origin')
          return;
      event.respondWith(
          cache.match(event.request).then(function (response) {
              if (response) {
                  return response;
              }
              return fetch(event.request);
          })
      );
  });
    
  self.addEventListener('activate', event => {
      event.waitUntil(
          cache.keys().then(keys => Promise.all(
              keys.map(key => {
                  if (!CACHE_NAME.includes(key)) {
                      return cache.delete(key);
                  }
              })
          )).then(() => {
              console.log(CACHE_NAME + "activated");
          })
      );
  });
</script>

/应用程序/javascript/控制器
└──

service-worker_controller.js

import { Controller } from "@hotwired/stimulus"
    
export default class extends Controller {
    connect () {
        if ('serviceWorker' in navigator) {
            window.addEventListener('load', function() {
                navigator.serviceWorker.register("/service-worker", {scope: "/" }).then(function (registration) {
                console.log("ServiceWorker registration successful with scope: ", registration.scope);
                }, function (err) {
                    console.log("ServiceWorker registration failed: ", err);
                });
            });
        }
    }
}

应用程序/视图/布局/
└──

application.html.erb


    <!DOCTYPE html>
    <html lang="ja">
      <head>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <%= csrf_meta_tags %>
        <%= csp_meta_tag %>
        <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
    
        <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
        <%= javascript_importmap_tags %>
    
        <title><%= page_title(yield(:title)) %></title>
        <%= render 'application/favicon' %>
        <%= display_meta_tags(default_meta_tags) %>
      </head>
    
      <body class="dark:bg-gray-800 break-words flex flex-col min-h-screen">
        <%= render 'static_pages/navbar' %>
        <div id="flash" class="z-50 flex-col fixed top-16 right-1 ">
          <%= render 'shared/flash' %>
        </div>
        <%= tag.main class: "mb-auto relative" do %>
          <div class="w-full" data-controller="service-worker">
            <%= yield %>
          </div>
        <% end %>
        <%= render 'static_pages/footer' %>
      </body>
    </html>

错误信息

当我重新加载页面时,以下错误出现在 chrome DV 工具的控制台上。

The script has an unsupported MIME type ('text/html').

此外,以下消息出现在 chrome DV 工具控制台上。

如果你发现任何奇怪的事情,请告诉我。

progressive-web-apps service-worker ruby-on-rails-7 stimulusjs import-maps
2个回答
0
投票

到目前为止,除了通过控制器呈现 service-worker.js 文件外,您的示例看起来还不错。你的控制器抱怨它没有找到模板。您可以为 service_worker 方法创建一个视图,并将 service-worker.js 文件的内容粘贴到其中。你也可以让你的控制器方法直接发送文件。应该很容易解决。


0
投票

这不是模板问题。您发布的错误消息中提到了该错误。当脚本应该是 javascript 时,脚本以 text/html 形式返回。

您当前的代码将 JS 作为文本/html 发送,这让浏览器感到困惑,然后停止执行工作人员的代码。

你需要在标题中提到工作人员的代码是 application/javascript 或类似的东西,以确保浏览器以正确的方式解释它。

© www.soinside.com 2019 - 2024. All rights reserved.