引言
众所周知,在前端开发过程中,在文件版本更新之时,会面临恼人的缓存问题(关于缓存相关问题说明可以参考这篇文章https://www.cnblogs.com/lyzg/p/5125934.html )。在更新版本时,最常见的解决由于缓存所引发的工程问题的方法不外乎两种,一种是覆盖式方法,一种是非覆盖式方法。
所谓覆盖式就是指更新js或者css文件时直接用待发布版本文件替换已发布版本文件,这种方法比较简单,适用于在系统用户量较少的情况下,而且在版本更新时还必须尽量在系统闲置期间进行操作。如每次更新css、js文件时不修改文件名,而是在html引用目录中添加版本号,如......./js/index.js?v=12345678。
而非覆盖式方法,是在版本更新时不直接用待发布版本替换已发布版本,而是每次都对待发布的文件修改文件名,并对html的引用目录进行修改。这种方法稍微繁琐,但是相对来讲更加安全可靠。本文所介绍之方法即属于这一种。
目的
本文目的是基于gulp自动化构建工具,实现一种非覆盖式的js、css文件自动压缩以及版本修改的方法。
构建前
原文件目录结构:
原html文件
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<title>测试</title>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<article>
这里是测试.....
</article>
<script src="../js/jquery-1.12.3.min.js"></script>
<script src="js/index.js"></script>
</body>
</html>
构建后
构建生成目录结构:
css版本更新中间文件
{
"index.css": "index_d41d8cd98f.min.css"
}
js版本更新中间文件
{
"index.js": "index_d41d8cd98f.min.js"
}
版本更新后html文件
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<title>测试</title>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" href="css/index_d41d8cd98f.min.css">
</head>
<body>
<article>
这里是测试.....
</article>
<script src="js/jquery-1.12.3.min.js"></script>
<script src="js/index_d41d8cd98f.min.js"></script>
</body>
</html>
实现过程
gulp是基于node.js,node.js以及gulp的安装配置过程比较简单,这里就不多说了。直接上gulp构建文件gulpfile.js如下:
/*
非覆盖式自动化构建,静态文件修改之后,修改其文件名,并更新html中对静态文件的引用路径
Created by fasily on 2017-03-13
*/
var gulp = require('gulp'),
rev = require('gulp-rev'),
revC = require('gulp-rev-collector'),
RevAll = require('gulp-rev-all'),
cssMin = require('gulp-csso'),
rename = require('gulp-rename'),
uglify = require('gulp-uglify'),
clearAll = require('del'),
runSequence = require('run-sequence');
// 开发js、css打版本入口
gulp.task('default', ['clearAll','dev']);
//开发构建
gulp.task('dev', function (done) {
runSequence(
['revCss'],
['revJs'],
['cssPathUpdate'],
['jsPathUpdate'],
['revHtml'],
done);
});
//定义css、js、html源文件路径
var cssSrc = 'src/html/css/index.css',
jsSrc = 'src/html/js/index.js',
htmlSrc = 'src/html/test.html';
// css打版本
gulp.task('revCss', function() {
return gulp.src(cssSrc) //指定获取到src下的所有css文件。
.pipe(cssMin()) //执行压缩操作
.pipe(RevAll.revision({ hashLength: 10 }))
.pipe(rename({ //重命名
suffix: '.min'
}))
.pipe(gulp.dest('./dist/css'));//生成目标压缩css文件
});
//生成css版本修改中间文件
gulp.task('cssPathUpdate', function() {
return gulp.src(cssSrc) //指定获取到src下的所有css文件。
.pipe(cssMin()) //执行压缩操作
.pipe(rev())
.pipe(rev.manifest())
.pipe(gulp.dest('./dist/css'));
});
// js打版本
gulp.task('revJs',function () {
return gulp.src(jsSrc) //指定获取到src下的所有js文件。
.pipe(uglify()) //执行压缩操作
.pipe(RevAll.revision({hashLength: 10 }))
.pipe(rename({
suffix: '.min'
}))
.pipe(gulp.dest('./dist/js'));//生成目标压缩js文件
});
//生成js版本修改中间文件
gulp.task('jsPathUpdate', function() {
return gulp.src(jsSrc) //指定获取到src下的所有js文件。
.pipe(uglify()) //执行压缩操作
.pipe(rev())
.pipe(rev.manifest())
.pipe(gulp.dest('./dist/js'));
});
//Html替换css、js引用文件版本
gulp.task('revHtml', function () {
return gulp.src(['dist/**/*.json', htmlSrc])
.pipe(revC())
.pipe(gulp.dest('dist'));
});
//清空dist文件夹
gulp.task('clearAll', function () {
clearAll('./dist/*');
});
另外需要修改gulp-rev-all目录下revisioner.js文件第333行,修改为
filename = filename + '_' + file.revHash.substr(0, this.options.hashLength) + ext;
修改/rev-path/index.js第10行,修改为
return filename + '_' + hash + '.min' + ext;
修改gulp-rev-collector/index.js第11行,修改为
revSuffix: '_[0-9a-f]{8,10}-?.min'
总结
本文旨在通过介绍基于gulp的css、js文件压缩以及版本修改来解决前端文件版本更新时所遇到的更新失效问题,由于时间关系,难免有不当或不细支出,望您提出宝贵意见和建议。
参考文章
https://www.zhihu.com/question/20790576
http://www.jb51.net/article/100652.htm