Application cache 实用技巧

201 阅读1分钟
原文链接: github.com

application cache 场景问题解决方案

更新

要保证application cache 生效,并且更新。必不可少的是要配置html的 manifest属性。

<html manifest="manifest.appcache">

manifest.appcache文件内容大致如下。这里简单说明不做详细解释。一搜一大堆。

CACHE MANIFEST
#v1.0
CACHE:
assets/css/common.css
assets/js/common.js
assets/img/icon.png
NETWORK:
*
FALLBACK:
*.html /404.html

其中保证注释部分#v1.0的版本号动态更新是保证appcache生效的必要条件。 可以通过每次构建动态生成manifest.appcache文件 例如用我自己写的插件:AppCachePlugin.js

// AppCachePlugin.js
const uniq = require('lodash.uniq')
const isJS = function (file) { return /\.js(\?[^.]+)?$/.test(file) }
const isIMG = function (file) { return /\.(png|jpe?g|gif|svg)(\?[^.]+)?$/.test(file) }
const isCSS = function (file) { return /\.css(\?[^.]+)?$/.test(file) }

const AppCachePlugin = function (options) {
  if (options === void 0) options = {}
  this.options = Object.assign({
    filename: 'manifest.appcache'
  }, options)
}

AppCachePlugin.prototype.apply = function (compiler) {
  compiler.plugin('emit', (compilation, next) => {
    const stats = compilation.getStats().toJson()
    const allFiles = uniq(stats.assets.map((a) => { return a.name }))
    const cssFiles = uniq(allFiles.filter(isCSS))
    const jsFiles = uniq(allFiles.filter(isJS))
    const imgFiles = uniq(allFiles.filter(isIMG))
    const version = '1'
    const stamp = +(new Date())
    const files = [...cssFiles, ...jsFiles, ...imgFiles].join('\n')
    const ma = `CACHE MANIFEST
#v${ version} - ${stamp}
CACHE:
${files}
NETWORK:
*`
    compilation.assets[this.options.filename] = {
      source () { return ma },
      size () { return ma.length }
    }
    next()
  })
}

另外,要保证主动缓存更新,需要一段js代码帮助:

if (window.applicationCache) {
  window.applicationCache.addEventListener("updateready", function () {
    if (window.applicationCache.status === window.applicationCache.UPDATEREADY) {
      window.applicationCache.swapCache();
      window.location.reload();
    }
  }, false);
}

让cache 失效

让application cache 失效,只需要在服务器端删除对应的appcache文件即可