神奇的 Workbox 3.0

workbox 是 GoogleChrome 团队推出的一套 Web App 静态资源和请求结果的本地存储的解决方案,该解决方案包含一些 Js 库和构建工具,在 Chrome Submit 2017 上首次隆重面世。而在 workbox 背后则是 Service WorkerCache API 等技术和标准在驱动。在 Workebox 以前,GoogleChrome 团队较早时间推出过 sw-precachesw-toolbox 库,可是在 GoogleChrome 工程师们看来,workbox 才是真正能方便统一的处理离线能力的更完美的方案,因此中止了对 sw-precache 和 sw-toolbox 的维护。css

从 sw-precache 和 sw-toolbox 的相关 issue 来看,众多开发者对它们也是很有怨言。可是 workbox 发布了 2.x 版本后其实反响通常,总的来讲我认为仍是 API 太混乱了,虽然功能很强大可是设计条理不清晰,其学习成本致使很难推广开,可是从目前 workbox3 alpha 版本的文档和 API 来看,我我的认为 workbox3 终于成为了可以很方便简单的解决 Service Worker 绝大多数问题的神器,因此写这篇文章来全面介绍一下。html

注意,当前 workbox 3 仍是 alpha 发布阶段,API 和接口还有可能调整,文中所提到的一些工具可能 Google 方面尚未彻底 ready, 本文为正式发布前的尝鲜版,后续正式发布后本会随版更新。node

概述

workbox 如今已经发布到了 3.0 alpha 版本,咱们能够先了解一下 workbox:webpack

  • 无论你的站点是何种方式构建的,均可觉得你的站点提供离线访问能力。
  • 就算你不考虑离线能力,也能让你的站点访问速度更加快。
  • 几乎不用考虑太多的具体实现,只用作一些配置。
  • 简单却不失灵活,能够彻底自定义相关需求(支持 Service Worker 相关的特性如 Web Push, Background sync 等)。
  • 针对各类应用场景的多种缓存策略。

bingo! 若是你被这些特性吸引住了,能够往下看看,咱们在这里讲的是 workbox 3.0 的内容,固然 workbox 在解决的核心问题方面和以前的版本没有太大的出入,只是 API 进行了一些调整,而且在构建相关方面考虑的更加完善,workbox 进入 3.0 之后,API 看起来清晰多了,接下来一块儿看看 workbox 3 具体内容吧。git

用法

想要使用 workbox,首先须要在你的项目中建立一个 Service Worker 文件 sw.js 而且在你的站点上注册:github

123456789复制代码
<script>// 能够这么注册 Service Workerif ('serviceWorker' in navigator) {    // 为了保证首屏渲染性能,能够在页面 load 完以后注册 Service Worker    window.onload = function () {        navigator.serviceWorker.register('/sw.js');    };}</script>复制代码

有了 sw.js 以后就可使用 workbox 了,你只须要在 sw.js 中导入 workbox 就可使用了:web

1234567891011复制代码
// workbox 2.x 是将 workbox 核心内容放在 workbox-sw node_modules 包里维护的// workbox 3.x 开始是将 workbox 核心 lib 放在 CDN 维护// 固然也能够挪到本身的 CDN 维护importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.0.0-alpha.3/workbox-sw.js');if (workbox) {    console.log(`Yay! workbox is loaded 🎉`);}else {    console.log(`Boo! workbox didn't load 😬`);}复制代码

当在 sw.js 可以拿到 workbox 全局变量,代表 workbox 可使用了,workbox 能干什么呢?正则表达式

  • 经过 workbox.precaching 模块来处理 Service Worker 静态资源的预缓存。
  • 经过 workbox.routing 模块提供的路由控制和 workbox.strategies 模快提供的缓存策略控制帮助你作动态缓存。
  • 使用 workbox 插件作一些 Service Worker 相对独立的工做,好比 更新提醒, Background Sync 等

precache (预缓存) 静态文件

若是你有一些静态资源是须要永远的离线缓存,除非从新上线才更新缓存的话,那 precache 预缓存应该是你所期待的,若是了解 Service Worker 的生命周期的话,precache 的工做是在 Service Worker install 时候经过 Cache API 完成的,具体能够了解 Service Work 生命周期shell

workbox 提供了一种很是方便的 API 帮助咱们解决 precache 的问题,和以前 Google 的 precache 方案 sw-precache 的工做相似。workbox 经过使用 precaching.precacheAndRoute 接口完成 precache 操做:npm

12345678复制代码
workbox.precaching.preacheAndRoute([    '/styles/index.0c9a31.css',    '/scripts/main.0d5770.js',    {        url: '/index.html',        revision: '383676'    },]);复制代码

以上这段代码会在 Service Worker 安装成功的时候下载 /styles/index.0c9a31.css/scripts/main.0d5770.js, /index.html 文件,而且会以构造路由的方式将这些文件都存储到 Cache Storage 中。这个传入的数组其实就是预缓存内容列表,有两种形式,一种是直接写文件名的字符串(带 Hash 的),一种是以下所示带有 url 和 revesion 值的对象:

1234复制代码
{    url: '将要预缓存的文件 URL, revision: '文件内容的 Hash 值'}复制代码

这里须要注意的是这个 revision 的值,当预缓存的文件就职何变更的时候就会被更新,若是 revision 没有更新,那当你更新 Service Worker 的时候,被缓存的文件也不会被更新。

咱们接下来介绍一些帮助咱们生成预缓存内容列表的 precaching.precacheAndRoute API 的配置选项。

处理 / 和 /index.html

一般当用户访问 / 时,对应的访问的页面 HTML 文件是 /index.html,默认状况下,precache 路由机制会在任何 URL 的结尾的 / 后加上 index.html,这就觉得着你预缓存的任何 index.html均可以经过 /index.html 或者 / 访问到。

固然,你也能够经过 directoryIndex 参数禁用掉这个默认行为:

12345678910111213复制代码
workbox.precaching.preacheAndRoute(    [        '/styles/index.0c9a31.css',        '/scripts/main.0d5770.js',        {            url: '/index.html',            revision: '383676'        },    ],    {        directoryIndex: null    });复制代码

忽略请求参数

例如,若是我么想要让 key1 参数不是 /example.html?key1=1&key2=2 的一部分,你只须要设置 ignoreURLParametersMatching 参数把它排除掉:

1234567891011复制代码
workbox.precaching.precacheAndRoute(    [        {            url: '/example.html?key2=2',            revision: '6821e0'        }    ],    {        ignoreUrlParametersMatching:[/key1/],    });复制代码

这样 /example.html?key1=1&key2=2 这个路由对应的内容就能够被预缓存了。

生成预缓存列表

靠手动维护 precache.precacheAndRoute API 中的预缓存内容列表是不可能的,revision 咱们没法手动维护,因此咱们确定是要借助一些工具来干这个事情,好在 workbox 提供了多种方式让咱们选择:

  • workbox 命令行
  • workbox-build npm 包
  • workbox-webpack-plugin

在使用以上三种方式生成预缓存内容列表以前,咱们先预设一下应用场景:假设你的项目在目录 /app 下,必须保证在你的项目根目录下有一个 app/sw.js 包含如下内容:

12复制代码
// 一般项目中的 sw.js 源文件都是经过这样预留一个空数组的方式来预缓存内容列表的workbox.precaching.precacheAndRoute([]);复制代码

这样才能保证能将生成的预缓存内容列表内容注入到 Service Worker 文件中。

workbox 命令行

workbox 提供了一套命令行,专门来帮助咱们注入预缓存内容列表,能够帮助咱们生成注入预缓存内容列表所须要的 workbox-cli-config.js 配置文件,而后经过命令行使用配置文件就能够生成一个预缓存列表的代码并注入到以前自定义的 app/sw.js 文件中,最终编译成线上所须要的 Service Worker 文件:dist/sw.js

安装命令行:

1复制代码
npm install -g workbox-cli复制代码

因此咱们先要有一个 workbox-cli-config.js 文件,而后根据这个文件结合 /app/sw.js 源文件来生成一个含有预缓存列表的 dist/sw.js 文件。接下来咱们能够看下具体这一系列流程须要怎么操做。

首先执行 workbox generate:sw 命令生成一个配置文件 workbox-cli-config.js,这个命令执行以后将会弹出一些问题让你选择,以下所示:

12345复制代码
>$ workbox generate:sw? What is the root of your web app? app? Which file types would you like to cache? (Press <space> to select, <a> to toggle all, <i> to inverse selection)html,ico,svg,png,js,css? What should the path of your new service worker file be (i.e. './build/sw.js')? dist/sw.js? Last Question - Would you like to save these settings to a config file? Yes复制代码

回答完这些问题以后你就能够在你的项目里导出一个新的 workbox-cli-config.js 配置文件了大概长如下这个样子:

123456789复制代码
// workbox-config.jsmodule.exports = {    "globDirectory": "app/",    "globPatterns": [        "**/*.{html,ico,svg,png,js,css}"    ],    "swDest": "dist/sw.js",    "swSrc": "app/sw.js"};复制代码

拿到了 workbox-cli-config.js 配置文件以后能够执行 workbox inject:manifest workbox-cli-config.js 命令生成编译后的 dist/sw.js 文件了,这一步干的事情就是把预缓存内容列表注入到 app/sw.js 中,通常只有在上线前才用命令行注入预缓存内容列表,一般咱们都不会手动去执行这些命令的,比较合理的作法是实现生成好 workbox-cli-config.js 文件,而后在构建脚本中配置上自动执行 workbox inject:manifest 命令。

workbox inject:manifest 命令的作法就是去匹配 /app/sw.js 中的 workbox.precaching.precacheAndRoute([]) 方法的正则,而后经过 replace 内容注入的,能够参考下面的 workbox-build 的介绍。

workbox-build

使用命令行总感受太傻了,操做步骤也比较繁琐,为了使得预缓存工做更加简便灵活,workbox 也提供了一个 NPM 包 – workbox-build,你能够在任何构建工具中都使用。

能够在你的工程根目录中执行如下命令安装 workbox-build 包:

1复制代码
npm install --save-dev workbox-build复制代码

而后直接能够在你想要处理 Service Worker 预缓存的地方引入 workbox-build 库,而且调用其 injectManifest 方法:

12345678910111213141516171819复制代码
const workboxBuild = require('workbox-build');workboxBuild.injectManifest({    swSrc: path.join(__dirname, 'app', 'sw.js'),    swDest: path.join(__dirname, 'dist', 'sw.js'),    globDirectory: './dist/',    globPatterns: ['**\/*.{html,js,css}'],    globIgnores: ['admin.html'],    templatedUrls: {        '/shell': ['dev/templates/app-shell.html', 'dev/**\/*.css'],    },    // 要替换的预留代码区正则    injectionPointRegexp: /(\.precacheAndRoute\()\s*\[\s*\]\s*(\))/,}).catch(err => {    console.error(`Unable to inject the precache manifest into sw.js`);    throw err;});复制代码

在构建文件中执行这段代码就会读取 app/sw.js 文件而后生成一个 dist/sw.js 文件含有注入的预缓存内容列表。

关于如何使用 injectManifest 方法能够查看 workbox-build 的 injectManifest 方法 所有参数

workbox-webpack-plugin

有了 workbox-build 可想而知就能搞出不少实用的预缓存插件方案,好比 Webpack、Gulp 等插件,workbox 官方也提供了一个插件 workbox-webpack-plugin,只须要经过如下方式,就能够将插件安装到你的 webpack 项目中:

1复制代码
npm install --save-dev workbox-webpack-plugin复制代码

而后就只须要将插件添加到 Webpack 配置中就能够正常使用了,插件参数和 workbox-build 的 injectManifest 方法保持一致:

123456789101112131415复制代码
const workboxPlugin = require('workbox-webpack-plugin');// ...webpack({    plugins: [        // ...        new workboxPlugin({            swSrc: './src/sw.js',            swDest: './dist/sw.js',            globDirectory: './dist/',            globPatterns: ['**/*.{html,js,css}'],        })    ]    // ...});复制代码

这里有个地方和以前提到的替换预留的 app/sw.js 不同:使用 workbox 提供的 Webpack 插件必须在 app/sw.js 中包含如下代码才能完成预缓存内容列表注入工做

1复制代码
workbox.precaching.precacheAndRoute(self.__precacheManifest || []);复制代码

当插件跑起来以后,会在 /dist/sw.js 中增长一段 importScripts() 代码用来引入一个模块,这个模块的内容就是 self.__precacheManifest,也就是预缓存内容列表的内容,具体的效果能够在项目中使用 workbox-webpack-plugin 尝试一下,看看 build 后的 dist/sw.js 结果就会比较清楚了。

路由请求缓存

路由请求缓存是经过文件路由匹配的模式分别对制定的路由文件作不一样策略缓存的方式,这部分工做能够在 app/sw.js 中直接使用 workbox 提供的 workbox.routing.registerRoute API 完成,这个 API 能够理解为干了两件事情,1、经过请求路由配置匹配到指定待缓存文件或请求内容2、经过第二个参数的处理回调函数决定用何种策略来缓存匹配上的文件。有 三种 方法能够经过 workbox-route 来匹配一个请求 URL

  • 字符串方式
1234567891011复制代码
// 能够直接是当前项目下的绝对路径workbox.routing.registerRoute(    '/logo.png',    handler // handler 是作缓存策略的回调函数,一般指后面所会降到的 '缓存策略函数');// 也能够是完整的带完整 host 的 URL 路径,这里的 URL 必须是 https 的workbox.routing.registerRoute(    'https://some-host/some-path/logo.png',    handler);复制代码
  • 正则表达式方式
1234复制代码
workbox.routing.registerRoute(    new RegExp('.*\.js'), // 这里是任何正则都行,只要能匹配得上的请求路由地址    handler);复制代码
  • 回调函数方式
12345678910复制代码
// 经过回调函数来匹配请求路由将会让策略更加灵活const matchFunction = ({url, event}) => {    // 若是请求路由匹配了就返回 true,也能够返回一个参数对象以供 handler 接收处理    return false;};workbox.routing.registerRoute(    matchFunction,    handler);复制代码

上面讲到了匹配请求路由的三种方式,接下来能够讲讲如何处理匹配上的请求所返回的内容,也就是上面三种路由匹配方式的 handler,一般有两种作法:

  • 使用一种 workbox 经过 workbox.strategies API 提供的 缓存策略
  • 提供一个自定义返回带有返回结果的 Promise 的回调方法。

路由请求缓存策略

下面介绍一下 workbox 默认提供的几种缓存策略 API,这些 API 能够被当成 handler 使用。

Stale While Revalidate

这种策略的意思是当请求的路由有对应的 Cache 缓存结果就直接返回,在返回 Cache 缓存结果的同时会在后台发起网络请求拿到请求结果并更新 Cache 缓存,若是原本就没有 Cache 缓存的话,直接就发起网络请求并返回结果,这对用户来讲是一种很是安全的策略,能保证用户最快速的拿到请求的结果,可是也有必定的缺点,就是仍是会有网络请求占用了用户的网络带宽。能够像以下的方式使用 State While Revalidate 策略:

1234复制代码
workbox.routing.registerRoute(    match, // 匹配的路由    workbox.strategies.staleWhileRevalidate());复制代码

Network First

这种策略就是当请求路由是被匹配的,就采用网络优先的策略,也就是优先尝试拿到网络请求的返回结果,若是拿到网络请求的结果,就将结果返回给客户端而且写入 Cache 缓存,若是网络请求失败,那最后被缓存的 Cache 缓存结果就会被返回到客户端,这种策略通常适用于返回结果不太固定或对实时性有要求的请求,为网络请求失败进行兜底。能够像以下方式使用 Network First 策略:

1234复制代码
workbox.routing.registerRoute(    match, // 匹配的路由    workbox.strategies.networkFirst());复制代码

Cache First

这个策略的意思就是当匹配到请求以后直接从 Cache 缓存中取得结果,若是 Cache 缓存中没有结果,那就会发起网络请求,拿到网络请求结果并将结果更新至 Cache 缓存,并将结果返回给客户端。这种策略比较适合结果不怎么变更且对实时性要求不高的请求。能够像以下方式使用 Cache First 策略:

1234复制代码
workbox.routing.registerRoute(    match, // 匹配的路由    workbox.strategies.cacheFirst());复制代码

Network Only

比较直接的策略,直接强制使用正常的网络请求,并将结果返回给客户端,这种策略比较适合对实时性要求很是高的请求。能够像以下方式使用 Network Only 策略:

1234复制代码
workbox.routing.registerRoute(    match, // 匹配的路由    workbox.strategies.networkOnly());复制代码

Cache Only

这个策略也比较直接,直接使用 Cache 缓存的结果,并将结果返回给客户端,这种策略比较适合一上线就不会变的静态资源请求。能够像以下方式使用 Cache Only 策略:

1234复制代码
workbox.routing.registerRoute(    match, // 匹配的路由    workbox.strategies.networkOnly());复制代码

不管使用何种策略,你均可以经过自定义一个缓存来使用或添加插件(后面咱们会介绍 workbox 插件)来定制路由的行为(以何种方式返回结果)。

123456789复制代码
workbox.strategies.staleWhileRevalidate({    // 使用用户自定义的缓存名称    cacheName: 'my-cache-name',    // 使用 workbox 插件    plugins: [        // ...    ]});复制代码

固然,这些配置一般须要在缓存请求时更安全,也就是说,须要限制缓存的时间或者确保设备上用的数据是被限制的。

自定义策略

若是以上的那些策略都不太能知足你的请求的缓存需求,那就得想一想办法本身定制一个合适的策略,甚至是不一样状况下返回不一样的请求结果,workbox 也考虑到了这种场景(这也是为何我会极力推荐 workbox 的缘由),固然,最简单的方法是直接在 Service Worker 文件里经过最原始的 fetch 事件控制缓存策略。也可使用 workbox 提供的另外一种方式:传入一个带有对象参数的回调函数,对象中包含匹配的 url 以及请求的 fetchEvent 参数,回调函数返回的就是一个 response 对象,具体用法以下所示:

1234567891011121314复制代码
workbox.routing.registerRoute(    ({url, event}) => {        return {            name: 'workbox',            type: 'guide',        };    },    ({url, event, params}) => {        // 返回的结果是:A guide on workbox        return new Response(            `A ${params.type} on ${params.name}`        );    });复制代码

第三方请求的缓存

若是有些请求的域和当前 Web 站点不一致,那能够被认为是第三方资源或请求,针对第三方请求的缓存,由于 Workbox 没法获取第三方路由请求的状态,当请求失败的状况下 workbox 也只能选择缓存错误的结果,因此 workbox 3 原则上默认不会缓存第三方请求的返回结果。也就是说,默认状况下以下的缓存策略是不会生效的:

1234复制代码
workbox.routing.registerRoute(    'https://notzoumiaojiang.com/example-script.min.js',    workbox.strategies.cacheFirst(),);复制代码

固然,并非全部的策略在第三方请求上都不能使用,workbox 3 能够容许 networkFirststalteWhileRevalidate 缓存策略生效,由于这些策略会有规律的更新缓存的返回内容,毕竟每次请求后都会更新缓存内容,要比直接缓存安全的多。

若是你强制使用 workbox 3 不推荐的缓存策略去缓存第三方请求,那 workbox 在 DevTools 里的 console 中会报警报哦。

若是你仍是执意要缓存第三方请求的结果的话,workbox 3 也考虑到了确实会有这种难以扼杀的需求,提供了一个很是人性化的方式知足需求:利用 workbox.cacheableResponse.Plugin 来指定只缓存请求成功的结果,这样就打消掉咱们以前对于不安全结果被缓存的顾虑了。鹅妹子英!(后面咱们会介绍插件机制)

1234567891011复制代码
workbox.routing.registerRoute(    'https://notzoumiaojiang.com/example-script.min.js',    workbox.strategies.cacheFirst({        plugins: [            // 这个插件是让匹配的请求的符合开发者指定的条件的返回结果能够被缓存            new workbox.cacheableResponse.Plugin({                statuses: [0, 200]            })        ]    }),);复制代码

workbox 配置

workbox 3 提供了一些配置项,都封装在 workbox.core API 中,能够稍微了解一下。

配置缓存名称

经过 DevTools -> Applications -> Caches 能够发现,workbox 对于缓存命名有一些规则的:

1复制代码
<prefix>-<ID>-<suffix>复制代码

每一个命名都有个前缀和后缀,中间才是真正的命名 ID,主要是为了更大限度的防止重名的状况发生,能够经过如下这种方式分别对 precache 和 runtime 形式的缓存进行自定义命名:

123456复制代码
workbox.core.setCacheNameDetails({    prefix: 'my-app',    suffix: 'v1',    precache: 'custom-precache-name',// 不设置的话默认值为 'precache'    runtime: 'custom-runtime-name' // 不设置的话默认值为 'runtime'});复制代码

经过以上设置后,precache 类型的缓存名称为 my-app-custom-precache-name-<ID>-v1,runtime 类型的缓存名称为 my-app-custom-runtime-name-<ID>-v1。workbox 推荐尽可能为你的每一个项目设置不一样的 prefix,这样你在本地 locahost 调试 Service Worker 的时候能够避免冲突。而 suffix 能够用来控制缓存版本,让站点的 Service Worker 更新机制变得清晰维护。

workbox 为了让 Web App 的缓存管理的更加细粒度的清晰可维护,也提供了策略级别的缓存命名设置,能够经过策略 API 的 cacheName 参数进行设置:

123456复制代码
workbox.routing.registerRoute(    /.*\.(?:png|jpg|jpeg|svg|gif)/g,    new workbox.strategies.CacheFirst({        cacheName: 'my-image-cache',    }));复制代码

这样,对应的图片相关的 cacheFirst 策略的缓存都会以 my-image-cache-<ID> 的形式命名,这里要注意的是:prefix 和 suffix 是不须要设置的

指定 development 环境

workbox 开发过程当中是须要 debug 的,因此 workbox 3 也提供了 logger 机制帮助咱们排查问题,可是在生产环境下,咱们不但愿也产生 logger 信息,因此 workbox 提供了「指定当前环境」 的设置:

12345复制代码
// 设置为开发模式workbox.setConfig({debug: true});// 设置为线上生产模式workbox.setConfig({debug: false});复制代码

配置日志 Level

workbox 3 提供 logger 机制帮助咱们更好的调试 workbox,一共有四种 log level:debuglogwarnerror

workbox logs

能够经过如下方式设置 log 的 level,这样就能够只看到某个 level 的 log 信息,让调试的过程当中更加专一。具体的设置方式是经过 worbox.core API 中的 setLogLevel 方法来完成:

1234567891011121314复制代码
// 展现全部的 logworkbox.core.setLogLevel(workbox.core.LOG_LEVELS.debug);// 只展现 log, warning 和 error 类型的 logworkbox.core.setLogLevel(workbox.core.LOG_LEVELS.log);// 只展现 warning 和 error 类型的 logworkbox.core.setLogLevel(workbox.core.LOG_LEVELS.warn);// 只展现 error 类型的 logworkbox.core.setLogLevel(workbox.core.LOG_LEVELS.error);// 啥 log 都没有,这个适用于线上生产环境workbox.core.setLogLevel(workbox.core.LOG_LEVELS.silent);复制代码

workbox 插件

插件机制应该是 workbox 3 最大的改进了,在 2.x 中,现有的插件大部分功能都是直接以 API 的形式抛给开发者,让开发者一头雾水,如今 3.0 中每一个内置插件本身封装了以前的 API,对开发者来讲专门解决了一个个独立的问题。除此以外,workbox 3 还提供插件扩展机制以及事件钩子可让开发者本身扩展插件。workbox 插件可让你经过操做一个请求的生命周期中的返回内容和请求内容添加其余的一些行为。

workbox 插件一般都是在缓存策略中使用的,可让开发者的缓存策略更加灵活,workbox 内置了一些插件:

  • workbox.backgroundSync.Plugin: 若是网络请求失败,就将请求添加到 background sync 队列中,而且在下一个 sync 事件触发以前从新发起请求。

  • workbox.broadcastUpdate.Plugin: 当 Cache 缓存更新的时候将会广播一个消息给全部客户端,相似于 sw-register-webpack-plugin 作的事情。

  • workbox.cacheableResponse.Plugin: 让匹配的请求的符合开发者指定的条件的返回结果能够被缓存,能够经过 status, headers 参数指定一些规则条件。

  • workbox.expiration.Plugin: 管理 Cache 的数量以及 Cache 的时间长短。

能够像以下方式来使用 workbox 插件,以 workbox.expiration.Plugin 为例:

123456789101112复制代码
workbox.routing.registerRoute(    /\.(?:png|gif|jpg|jpeg|svg)$/,    workbox.strategies.cacheFirst({        cacheName: 'images',        plugins: [            new workbox.expiration.Plugin({                maxEntries: 60, // 最大的缓存数,超过以后则走 LRU 策略清除最老最少使用缓存                maxAgeSeconds: 30 * 24 * 60 * 60, // 这只最长缓存时间为 30 天            }),        ],    }),);复制代码

自定义插件

固然,workbox 也知道这些插件确定不能知足你们的自定义策略的要求,因此索性将整个请求生命周期中的关键事件以事件钩子回调函数的方式暴露出来,也就是说,咱们可使用这些事件钩子打造本身更加灵活的 workbox 插件。一个插件就是一个构造函数,而钩子就是以构造函数的方法的形式供开发者们自定义开发,下面介绍一下有哪些事件钩子:

cacheWillUpdate

cacheWillUpdate({request, response}),在请求返回结果替换 Cache 结果以前被调用,你能够在这个事件钩子中在更新缓存以前修改返回的结果,若是将结果直接设为 null 来避免当前请求的返回的结果被更新到缓存。

cacheDidUpdate

cacheDidUpdate({cacheName, request, oldResponse, newResponse}),当有新的缓存写入记录或者 Cache 缓存被更新时被调用,你能够调用这个方法在 Cache 缓存更新以后干点什么。

cachedResponseWillBeUsed

cachedResponseWillBeUsed({cacheName, request, matchOptions, cachedResponse}),在 Cache 缓存的结果在 fetch 事件中被触发响应返回以前调用,可使用这个回调来容许或阻止正在使用的 Cache 响应返回。

requestWillFetch

requestWillFetch({request}),当任何 fetch 事件被触发的时候都会被调用,能够在这个毁掉中修改请求的 request 内容。

fetchDidFail

fetchDidFail({originalRequest, request}),当 fetch 事件触发失败的时候被调用,fetch 事件触发失败是网络根本没法请求,而不是请求返回为 非 200 的状态的时候,能够用这个钩子在检测到断网的时候干点什么。

若是你想写一个本身的 workbox 插件,只须要参照以下方式:

12345678复制代码
// my-workbox-plugin.jsexport default const MyWorkboxPlugin = {    cacheWillUpdate({request, response}) {        // ... 搞事情    },    // ... 继续搞事情};复制代码

本文参考了 Google 官方文档,在文档的基础上作了一些本身的解读和总结,有兴趣的开发者能够阅读原始文档,文档中还列出了一些「最佳实践」以及 「debug」 的方式,能够帮助咱们更好的使用 workbox。

相关文章
相关标签/搜索