###背景 前端页面中,静态文件的缓存可以加快网站的响应,但是开发人员如果修改js、css后直接发布线上,用户短时间内看到的依然是老的样式。访问最新的静态资源一般是两种
1. 强制刷新
2. 在修改的静态文件后面加上后缀比如时间戳等
显然第一种需要用户主动强刷页面,在pc端通过ctrl+f5勉强可以,但在移动端却要清理缓存数据了,显然不太友好 对于第二种,不需要用户手动刷新,但是对于开发人员则需要每次手动加一个时间戳,也比较浪费时间,接下来我有一种方法供大家参考
利用前端构建工具Gulp来协助完成 Gulp的安装就不赘述,网上一大把
通常前端尤其是移动端为了减少http请求提高响应速度都会压缩js、css静态资源,在前端页面中引用压缩后的代码如
是一个一般的写法,加了时间戳后,就变成
这样,整个流程就是
压缩文件、加时间戳
让我现在尝试用gulp把这个流程简化为一个步骤,这其中需要做的事情有
自动监听更新的源文件
自动重新压缩、合并源文件为待上线文件
自动为所有引用到这个文件的链接加上标识(这里用md5、也可以用时间戳或其他)
###代码 基于以上,生成的代码如下
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var watch = require('gulp-watch')
var md5 = require("md5-file");//根据摘要生成md5
var replace = require('gulp-replace')//替换文件中的文本
var fs = require('fs'); //文件系统
var versionFile='./version.log' //用来写入,每次版本更新的记录
// Rerun the task when a file changes
gulp.task('watch', function () {
//原文件更新
watch(['../js/common/**/*.js'], ['test']);
//观察编译后的文件更新
watch('../js/build/*.js', function () {
var localFilePath = arguments[0].history[0];//获取修改的本地文件名
var fileMd5 = md5(localFilePath) //获取文件md5
var fileName = localFilePath.match(/([^\\]+?(js|css))/g)//得到文件名
//全文检索fileName,用到的地方就加一个时间戳md5
console.log('===========', localFilePath, fileName, fileMd5)
var now = new Date()
var d = now.toISOString()
var content = '【'+d+'\t'+fileMd5+'\n'+localFilePath+'】\n'
fs.appendFile(versionFile,content) //将这个文件的md5写到文件中,方便查看
var js_r = new RegExp('(
gulp.src(['../view/**/*.html']) //遍历所有文件查看引用
.pipe(replace(js_r,'$1$2'+'?'+fileMd5+'$4'))//如果有引用,则加入md5 hash
.pipe(gulp.dest('../view'))
console.log('done')
});
});
//test
gulp.task('test', function () {
return gulp.src(['../js/common/*.js'])
.pipe(uglify())
.pipe(concat('test.min.js'))
.pipe(gulp.dest('../js/build'));
})
简单说明下,
首先是依赖,都是需要手动下载的 如replace,下载本地就是
npm install gulp-replace --save-dev
代码大致意思,定义一个watch的任务,监听 ['../js/common/**/*.js'] common下所有js文件的修改,如果修改,则执行任务test,之后打包到build目录下,第二个watch监听到文件变化,遍历所有文件,查找引用的地方,并加上md5 hash值。现在交给我们的任务就是一条命令了 gulp watch
###效果
可以看到,执行命令后,我手动修改了源码,然后压缩后的detail.js更新了,然后就去找所有文件有引用的地方,都替换成这个md5,我截图的只有一个地方,其实更新了几十个文件 同时 versionFile也会写入一条记录,对应时间、md5、文件
同理,css样式也可以仿照
###遗留的需要改进的地方 正则匹配的仅仅是文件名,如果不同路径下相同文件名,也会匹配到。中间需要多加一个校验的操作,即
判断修改的文件 与 正则匹配的文件 是否是同一个文件。