详解前端自动化工具gulp自动添加版本号

网友投稿 359 2023-06-24


详解前端自动化工具gulp自动添加版本号

之前,我介绍了学习安装并配置前端自动化工具Gulp,觉得gulp确实比grunt的配置简单很多,于是我决定再深入学习一下gulp,就去网上查了资料,发现gulp还可以自动添加版本号,这个功能就为我平时在更新css或js时老是在客户端存在缓存导致更新后的效果无法实时展现的苦恼。所以就赶紧去试了一下,果真可以,很高兴啊,真是为项目开发,为效果的快速展现提供了很多的便利。

实现原理:

1、修改js和css文件;

2、通过对js,css文件内容进行hash运算,生成一个文件的唯一hash字符串(如果文件修改则hash号会发生变化);

3、替换html中的js,css文件名,生成一个带版本号的文件名。

原html文件代码

预期效果:在原目录结构下html文件代码

background:url("../images/none.png?v=8f204d4")

实现方法:

1、安装gulp和gulp插件

npm install --save-dev gulp

npm install --save-dev gulp-rev

npm install --save-dev gulp-rev-collector

npm install --save-dev gulp-asset-rev

npm install --save-dev run-sequence

2、编写gulpfile.js

//引入gulp和gulp插件

var gulp = require('gulp'),

assetRev = require('gulp-asset-rev'),

runSequence = require('run-sequence'),

rev = require('gulp-rev'),

revCollector = require('gulp-rev-collector');

//定义css、js源文件路径

var cssSrc = 'css/*.css',

jsSrc = 'js/*.js';

//为css中引入的图片/字体等添加hash编码

gulp.task('assetRev', function(){

return gulp.src(cssSrc) //该任务针对的文件

.pipe(assetRev()) //该任务调用的模块

.pipe(gulp.dest('src/css')); //编译后的路径

});

//CSS生成文件hash编码并生成 rev-manifest.json文件名对照映射

gulp.task('revCss', function(){

return gulp.src(cssSrc)

.pipe(rev())

.pipe(rev.manifest())

.pipe(gulp.dest('rev/css'));

});

//js生成文件hash编码并生成 rev-manifest.json文件名对照映射

gulp.task('revJs', function(){

return gulp.src(jsSrc)

.pipe(rev())

.pipe(rev.manifest())

.pipe(gulp.dest('rev/js'));

});

//Html替换css、js文件版本

gulp.task('revHtml', function () {

return gulp.src(['rev/**/*.json', 'View/*.html'])

.pipe(revCollector())

.pipe(gulp.dest('View'));

});

//开发构建

gulp.task('default', function (done) {

condition = false;

runSequence( //需要说明的是,用gulp.run也可以实现以上所有任务的执行,只是gulp.run是最大限度的并行执行这些任务,而在添加版本号时需要串行执行(顺序执行)这些任务,故使用了runSequence.

['assetRev'],

['revCss'],

['revJs'],

['revHtml'],

done);

});

执行gulp命令后的效果

//rev目录下生成了manifest.json对应文件

{

"default.css": "default-803a7fe4ae.css"

}

很显然这不是我们需要的效果

3、更改gulp-rev和gulp-rev-collector

打开node_modules\gulp-rev\index.js

第144行 manifest[originalFile] = revisionedFile;

更新为: manifest[originalFile] = originalFile + '?v=' + file.revHash;

打开nodemodules\gulp-rev\nodemodules\rhttp://ev-path\index.js

10行 return filename + '-' + hash + ext;

更新为: return filename + ext;

打开node_modules\gulp-rev-collector\index.js

31行 if ( !_.isString(json[key]) || path.basename(json[key]).replace(new RegExp( opts.revSuffix ), '' ) !==  path.basename(key) ) {

更新为: if ( !_.isString(json[key]) || path.basename(json[key]).split('?')[0] !== path.basename(key) ) {

打开node_modules\gulp-assets-rev\index.js

78行 var verStr = (options.verConnecter || "-") + md5;

更新为:var verStr = (options.verConnecter || "") + md5;

80行 src = src.replace(verStr, '').replace(/(\.[^\.]+)$/, verStr + "$1");

更新为:src=src+"?v="+verStr;

再执行gulp命令,得到的结果如下(效果正确):

background:url("../images/none.png?v=8f204d4")

但是假如我们更改了css和js后,再执行gulp命令,得到的结果会如下:

有没有发现,会在版本号后面再添加一个版本号,因为gulp只替换了原来文件名,这样又不符合预期效果了,所以我们想到,还需要修改插件的替换正则表达式。

4、继续更改gulp-rev-collector

打开node_modules\gulp-rev-collector\index.js

第107行 regexp: new RegExp( '([\/\\\\\'"])' + pattern, 'g' ),

更新为: regexp: new RegExp( '([\/\\\\\'"])' + pattern+'(\\?v=\\w{10})?', 'g' ),

现在你不管执行多少遍gulp命令,得到的html效果都是

//引入gulp和gulp插件

var gulp = require('gulp'),

less = require('gulp-less'),

assetRev = require('gulp-asset-rev'),

minifyCss = require('gulp-minify-css'),

uglify = require('gulp-uglify'),

htmlmin = require('gulp-htmlmin'),

rename = require('gulp-rename'),

imagemin =http:// require('gulp-imagemin'),

runSequence = require('run-sequence'),

rev = require('gulp-rev'),

revCollector = require('gulp-rev-collector');

//定义css、js源文件路径

var cssSrc = 'css/*.css',

cssMinSrc = 'dist/css/*.css',

jsSrc = 'js/*.js',

jsMinSrc = 'dist/js/*.js',

lessSrc = 'less/*.less',

imgMinSrc = 'dist/images/*.{png,jpg,gif,ico}',

htmlSrc = '*.html';

//编译less 定义一个less任务(自定义任务名称)

gulp.task('less', function(){

return gulp.src(lessSrc) //该任务针对的文件

.pipe(less()) //该任务调用的模块

.pipe(gulp.dest('css'));//编译后的路径

});

//为css中引入的图片/字体等添加hash编码

gulp.task('assetRev', function(){

return gulp.src(cssSrc) //该任务针对的文件

.pipe(assetRev()) //该任务调用的模块

.pipe(gulp.dest('src')); //编译后的路径

});

//压缩css

gulp.task('cssMin', function() {

return gulp.src(cssSrc) //压缩的文件

.pipe(rename({suffix: '.min'}))

.pipe(minifyCss()) //执行压缩

.pipe(gulp.dest('dist/css')); //输出文件夹

});

//CSS生成文件hash编码并生成 rev-manifest.json文件名对照映射

gulp.task('revCss', function(){

return gulp.src(cssMinSrc)

.pipe(rev()) //文件名加MD5后缀

.pipe(rev.manifest()) //必须有这个方法 生成一个rev-manifest.json

.pipe(gulp.dest('dist/css')); //将rev-manifest.json 保存到 dist/css 目录内

});

//压缩js

gulp.task('uglify',function(){

return gulp.src(jsSrc)

.pipe(rename({suffix: '.min'}))

.pipe(uglify())

.pipe(gulp.dest('dist/js'));

});

//js生成文件hash编码并生成 rev-manifest.json文件名对照映射

gulp.task('revJs', function(){

return gulp.src(jsMinSrc)

.pipe(rev())

.pipe(rev.manifest())

.pipe(gulp.dest('dist/js'));

});

//压缩html

gulp.task('htmlMin',function(){

var options = {

collapseWhitespace:true, //从字面意思应该可以看出来,清除空http://格,压缩html,这一条比较重要,作用比较大,引起的改变压缩量也特别大。

collapseBooleanAttributes:true, //省略布尔属性的值,比如:,那么设置这个属性后,就会变成

removeComments:true, //清除html中注释的部分,我们应该减少html页面中的注释。

removeEmptyAttributes:true, //清除所有的空属性。

removeScriptTypeAttributes:true, //清除所有script标签中的type="text/javascript"属性。

removeStyleLinkTypeAttributes:true, //清楚所有Link标签上的type属性。

minifyJS:true, //压缩html中的javascript代码。

minifyCSS:true //压缩html中的css代码。

};

return gulp.src(htmlSrc)

.pipe(htmlmin(options))

.pipe(gulp.dest('dist/html'));

});

//Html替换css、js文件版本

gulp.task('revHtml', function () {

return gulp.src(['dist/**/*.json', 'dist/html/*.html'])

.pipe(revCollector())

.pipe(gulp.dest('dist/html'));

});

//压缩image

gulp.task('imageMin', function () {

gulp.src('images/*.{png,jpg,gif,ico}')

.pipe(imagemin())

.pipe(gulp.dest('dist/images'));

});

gulp.task('revImage', function(){

return gulp.src(imgMinSrc)

.pipe(rev())

.pipe(rev.manifest()) //必须有这个方法

.pipe(gulp.dest('dist/images'));

});

gulp.task('default', function (done) {

//condition = false;

runSequence( //此处不能用gulp.run这个最大限度并行(异步)执行的方法,要用到runSequence这个串行方法(顺序执行)才可以在运行gulp后顺序执行这些任务并在html中加入版本号

'less',

'assetRev',

'cssMin',

'revCss',

'uglify',

'revJs',

'imageMin',

'revImage',

'htmlMin',

'revHtml',

done);

});

目前,不知为何必须要运行两次gulp才可以给html中引入的图片添加版本号,所以还在摸索中,也请大神给指点指点,谢谢!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:简单实现Bootstrap标签页
下一篇:bootstrap实现图片自动轮播
相关文章

 发表评论

暂时没有评论,来抢沙发吧~