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文件即可