首页 > 解决方案 > Webpack 工作箱 Serviceworker API Precache index.html

问题描述

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

在我看来,该StaleWhileRevalidate策略应该是这里的最佳选择,但我已经被我自己阅读文档的能力或 workbox-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]
                        }
                    }
                }
            ]
        })
    ]
};

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

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

TL;DR - 我如何预缓存,index.html以便即使在浏览器选项卡已被释放或浏览器超时我的 PWA 所在的会话之后,应用程序也会加载?

标签: javascriptwebpackprogressive-web-appsworkboxworkbox-webpack-plugin

解决方案


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

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

对我的runtimeCaching对象。我还修复了 manifest.json 配置以符合 Chrome 和 Safari 定义的标准。通过这种方式,我可以将 PWA 作为应用程序安装在手机上,从而解决了我在手机上安装应用程序时遇到的问题。

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


推荐阅读