【问题标题】:Can't add Vue.js PWA to homescreen无法将 Vue.js PWA 添加到主屏幕
【发布时间】:2018-02-25 12:45:35
【问题描述】:

我最近正在研究渐进式 Web 应用程序。我已经像这样链接了 manifest.json 和 sw.js:

在 index.html 中

<link rel="manifest" href="<%= htmlWebpackPlugin.files.publicPath %>static/manifest.json">

在我的 main.js 中

if('serviceWorker' in navigator) {
        const messaging = firebase.messaging()

        navigator.serviceWorker.register('/static/sw.js').then((registration) => {
            messaging.useServiceWorker(registration)
            console.log('Service Worker registered')
        }).catch((error) => {
            console.log('Service Worker failed to register')
        })
    }

看起来它可以工作,但是当我尝试使用 DevTools 将 webapp 添加到我的主屏幕时,它显示以下错误: “无法安装站点:未检测到匹配的服务工作人员。您可能需要重新加载页面,或检查当前页面的服务工作人员是否也控制清单中的启动 URL”

在做了一些研究后,我发现有人说将 sw.js 和 manifest.json 放在项目的根目录中。但是当我这样做时,它不会链接文件(当我将它们放在静态文件夹中时,它会链接它们)。顺便说一句,我使用的是标准的 Vue.js 模板。

有什么建议可以解决这个问题吗?

【问题讨论】:

标签: web web-applications vue.js progressive


【解决方案1】:

Service Worker 注册失败的原因可能是其中之一:

  1. 您没有通过 HTTPS 运行您的应用程序。
  2. Service Worker 文件的路径未正确写入 - 它 需要相对于原点而不是应用的根目录编写。

结构上应该是这样的

/static/
    /css/
    /js/
    /img/
manifest.json
index.html
service-worker.js

在索引文件中,你应该注册类似这样的service worker

<script type=text/javascript>
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js')
    .then(function(registration) {
      console.log('Registration successful, scope is:', registration.scope);
    })
    .catch(function(error) {
      console.log('Service worker registration failed, error:', error);
    });
  }
</script>

并连接 manifest.json

<link rel=manifest href=/manifest.json>

manifest.json 的内容可以是

{
  "name": "vue-vanilla-pwa",
  "short_name": "vue-vanilla-pwa",
  "icons": [
    {
      "src": "/static/img/icons/android-chrome-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/static/img/icons/android-chrome-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "/index.html",
  "display": "standalone",
  "background_color": "#000000",
  "theme_color": "#4DBA87"
}

sw-precache 专为预缓存一些关键静态资源的需求而设计。因此,如果您想在用户离线时对 service worker 执行其他操作,则不需要它。以下是您可以对服务人员执行的操作的示例列表:https://github.com/GoogleChrome/samples/tree/gh-pages/service-worker

【讨论】:

  • 您好,感谢您的出色回答,但我仍有一些问题。我试图重现您的相同步骤,但没有运气。我唯一不同的是把清单放在/static 文件夹中。当我尝试执行您所说的操作时,我不断收到此错误:Service worker registration failed, error: DOMException: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/html'). 我不使用开发模式,因为我已经有一个生产环境,所以我每次都构建整个应用程序。会不会有问题?
  • 好的,我自己得到了答案。我正在使用build 命令将我的所有代码推向生产环境。问题是service-worker 文件被忽略了。我只是将它添加到静态文件夹(因此它与整个项目一起构建)并在脚本中正确引用。无论如何,非常感谢您对答案的帮助!我可能会在它的持续时间结束时发放赏金,如果没有其他人以更好的形式回答你会得到它!再次感谢!
  • 没关系,我之前所说的对整个应用程序来说有点糟糕,因为将服务工作者文件放在不是/ 的目录中是不好的,因为它不能在它自己的范围之外工作.我所做的,我不知道这是否是一种解决方法,或者我需要更多地研究 webpack,只是将文件复制到 webpack 构建命令的生成输出中(/dist 文件夹)。这确保了 service worker 在/ 范围内并且可以正常工作。如果你知道如何更有效地做到这一点,请告诉我!干杯!
  • 好吧,几天后我会给你赏金,因为你回答的问题很深入而且很好。另外,为了后代,我使用 webpack 在构建过程中自动复制service worker。谷歌一下,你会找到的;P
  • 嗨@Eugenio,我很高兴你知道了!感谢您的更新和赏金 :) 关于确保 service worker 在 / 范围内正常工作,最好将此步骤添加到 npm 构建脚本中的 prod 构建步骤中。新的 Vue cli 基本上是在 prod 模式下执行此操作的。它使用 npmjs.com/package/sw-precache-webpack-plugin 在 /dist 文件夹的根级别生成一个服务工作者文件 :)
猜你喜欢
  • 2021-05-13
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
  • 2018-10-27
相关资源
最近更新 更多