/crater

为大型WEB站点自动生成service worker,支持下属模块互不影响地缓存静态资源

Primary LanguageJavaScriptMIT LicenseMIT

crater

Build Status

crater

介绍

crater 的运行环境是这样的:一个 WEB 站点中存在多个互不相关的模块,每个模块可以控制自身的静态文件缓存策略,并编写成各自的配置文件。由 crater 生成统一的 service-worker 并交由站点注册,从而实现互相分离的静态文件缓存。

一个比较具体的例子是百度搜索首页。例如我们在百度移动端搜索北京旅游,观察请求的静态 JavaScript 文件。所有请求的 JavaScript 脚本的 referrer 都以 https://m.baidu.com/s? 开头。当我们点击第一条结果的“详细攻略”后,因为百度搜索的一种优化策略 superframe 允许页面在当页进行跳转,并通过 pushState 更改页面的URL,也因此之后请求的 JavaScript 脚本的 referrer 都以 https://m.baidu.com/sf? 开头。如果我们想对这些跨模块的静态脚本进行不同策略的缓存,这时我们就需要 crater。

运行方式

crater 会根据根目录下的 product 目录中的配置文件生成一份 service-worker.js 提供给 WEB 站点。这些配置会告诉 service-worker.js 应该对 哪些静态资源何种策略 进行缓存。因为整个 WEB 站点使用同一个 service-worker.js ,并且注册的 scope 建议为 / ,因此不同模块之间由 request.referrer 进行区分,各个模块的缓存文件也会互相被隔离开来,避免互相影响。

目前 crater 允许每个模块缓存最多50个文件,超过这个限制之后,我们会采取 LRU 策略(Least Recently Used)对缓存进行更替。当然这个值也是可以在配置项中进行调整的。

关于 service-worker.js 如何对静态文件进行缓存,可以参阅 lavas 的官网文档中对 service worker 的 介绍。简单来说,在 install 阶段对预缓存(pre-cache)资源进行缓存;在 fetch 阶段对模块添加的符合规则的静态资源尝试使用模块配置的策略进行读取并返回。

使用方式

开发者将代码 clone 到本地后有三个步骤需要进行:

编写配置文件

product 目录下编写至少一个配置文件,一个最简单的配置文件示例如下:

'use strict';

export default {

    // 模块名称(不可重复)
    name: 'pageSearch',

    // referrer规则
    referrerPattern: /\/s\?/,

    // 可通过验证的referrer
    validateReferrer: 'https://m.baidu.com/s?word=123',

    routers: [
        {
            // HTTP方法匹配,可选值'get', 'post', 'put', 'delete', 'all'
            method: 'get',
            // 静态文件URL匹配规则
            urlPattern: /se\/static\/(js|pmd|css)\/.*(css|js)$/,
            // 缓存策略,可选值'networkFirst', 'networkOnly', 'cacheFirst', 'cacheOnly', 'fastest'
            strategy: 'networkFirst',
            // 可通过验证的url
            validate: [{
                url: '/se/static/js/uiamd/bdbox/follow_4ff41a2.js'
            }]
        }
    ]
};

这里包含了一个配置文件最基本的三个部分: name, urlPattern, routers

  1. name 用以区分各个模块,因此不能重复。最终的缓存名称会命名为 @crater-${name}
  2. urlPattern 用以匹配每个资源请求的 referrer 来决定使用哪个配置文件
  3. routers 用以列出所有匹配规则和缓存策略,供 fetch 阶段逐个匹配并应用策略

运行构建命令

在编写配置文件完成后,还需要运行两条命令:

  1. npm run validate

    对配置文件进行校验检查

  2. npm run build 或者 npm start

    构建生成 service-worker-[hash:8].js,位于目录 dist 下。

注意:为了区分每次打包结果,在生成的最终文件中添加了 hash。是否需要重命名脚本视具体情况而定,下文将统一使用 service-worker.js 来指代构建结果文件。

注册 service worker

在站点页面添加如下代码即可完成注册:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('service-worker.js').then(function (registration) {
        // registration was successful
        console.log('service worker registration successful with scope ', registration.scope);
    }).catch(function (err) {
        // registration failed
        console.log(err);
    });
}

更多使用信息

更多的使用信息(包括配置文件详解和其他运行命令)可以参考 Wiki 的使用信息部分

设计思路

关于 crater 的设计思路,内部模块结构等信息请参阅 Wiki 的设计思路部分