Webpack 工作箱 Serviceworker API Precache index.html

Posted

技术标签:

【中文标题】Webpack 工作箱 Serviceworker API Precache index.html【英文标题】:Webpack workbox Serviceworker API Precache index.html 【发布时间】:2021-11-19 09:50:37 【问题描述】:

我正在将所谓的“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 所在的会话之后也能加载应用程序?

【问题讨论】:

【参考方案1】:

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


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

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

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

【讨论】:

以上是关于Webpack 工作箱 Serviceworker API Precache index.html的主要内容,如果未能解决你的问题,请参考以下文章

工作箱 webpack 插件从预缓存清单中排除文件夹

React如何通过Webpack优雅的接入serviceWorker的成熟方案workBox && Google Analytics

PWA

PWA

使用 Webpack 仅使用 Workbox 插件构建服务工作者代码 -> 无法指定用于预缓存的入口目录

如何为生成的 service worker 禁用 workbox-webpack-plugin 的警告