Webpack 工作箱 Serviceworker API 预缓存 index.html

Webpack workbox Serviceworker API Precache index.html

我正在将所谓的“PWA”转变为实际的 PWA。我已经成功地将一个 serviceworker 附加到应用程序,现在我想知道如何预缓存整个应用程序,以便“永远”不需要互联网连接来打开应用程序,如果它已经缓存在浏览器中。

在我看来,StaleWhileRevalidate 策略 应该 是最好的选择,但我还是被自己阅读文档或工作箱的能力打败了- webpack 在文档方面的可怕尝试(很可能是前者,而不是后者)

我有我的 webpack.common.js 文件,它是我所有类型构建的通用 webpack 配置入口点。

'use strict';

const helpers = require('./helpers');
const path = require('path');

const VueLoaderPlugin = require('vue-loader/lib/plugin')
const WorkboxPlugin = require('workbox-webpack-plugin')

module.exports = {
    entry: {
        polyfill: '@babel/polyfill',
        main: path.resolve(__dirname, '../src/main.js'),
        vendor: path.resolve(__dirname, '../src/vendor.js')
    },
    module: {
        rules: [{
                test: /\.(vue|Vue)$/,
                loader: 'vue-loader',
                include: [helpers.root('src')]
            },
            {
                test: /\.html$/,
                use: [
                   {
                    loader: 'html-loader',
                   }
                ]
            },
            {
                test: /\.ico$/,
                use: {
                    loader: 'file-loader',
                    options: {
                        name: '[name].[hash].[ext]',
                        outputPath: 'assets/img/icons'
                    }
                }
            },
            {
                test: /\.svg$/,
                use: [{
                        loader: 'svg-sprite-loader',
                        options: {
                            spriteFilename: 'sprites.svg',
                            runtimeCompat: true
                        }
                    },
                    {
                        loader: 'svgo-loader',
                        options: {
                            removeTitle: true,
                            removeUselessStrokeAndFill: true
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin(),
        new WorkboxPlugin.GenerateSW({
            exclude: ['./static/1pixel.png'],
            maximumFileSizeToCacheInBytes: 6291456,
            clientsClaim: true,
            skipWaiting: true,
            runtimeCaching: [
                {
                    handler: 'CacheFirst',
                    urlPattern: /\.(?:js|css|html)$/,
                    options: {
                        cacheName: 'static-assets-cache',
                        cacheableResponse: {
                            statuses: [200]
                        }
                    }
                }
            ]
        })
    ]
};

到目前为止,我已经到了可以从缓存中排除图像文件的地步,但这就是我所得到的。我想实现以下目标:

我打开应用程序 WITH 互联网连接。加载、缓存所有内容并准备就绪。然后我关闭了加载应用程序的选项卡,但我的 phone 在我的口袋里并继续我的业务。然后我想再次打开应用程序,但现在 WITHOUT 互联网连接。这应该是可能的,因为应用程序应该存在于缓存中。然而。我可以在我的应用程序缓存中看到我的所有字体、图像资产、polyfill 和商店 (js) 都已被缓存,但 index.html 文件没有。我想这就是为什么我的应用程序在浏览器中的选项卡被处理后拒绝加载的原因。

TL;DR - 我如何预缓存 index.html 以便即使在 browsertab 已被处理或浏览器使我的 PWA 所在的会话超时后应用程序仍会加载?

我目前的解决方案是添加:

{
    handler: 'CacheFirst',
    urlPattern: './index.html',
    options: {
        cacheName: 'index-assets-cache',
        cacheableResponse: {
            statuses: [200]
        }
    }
}

给我的runtimeCaching对象。我还修复了 manifest.json 配置以符合 Chrome 和 Safari 定义的标准。这样我就可以将 PWA 作为应用程序安装在 phone 上,这解决了我在 phone.

上安装应用程序时遇到的问题

在 phone 上的普通浏览器中问题仍然存在。登录并加载所有文件和预缓存后,我无法关闭选项卡并从离线状态再次打开它。所以这不是一个完整的答案。