gulp打包静态资源并给引用资源自动添加版本号

最近在做pc端网站开发,现在项目已基本上线,但是每次修改文件上传后,都要清除浏览器缓存,这对用户来说是很不方便的,因此给引用资源添加版本号就非常有必要了,网上打包工具很多,最终选择了gulp,使用过程中遇到的问题做了以下记录,和大家分享,当然也有很多不足的地方,欢迎指正。
原html文件代码:

<link rel="stylesheet" href="../css/default.css">
<script src="../js/app.js"></script>

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

<link rel="stylesheet" href="../css/default.css?v=5a636d79c4">
<script src="../js/app.js?v=3a0d844594"></script>

实现方法:
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'),
  less = require('gulp-less'),
  assetRev = require('gulp-asset-rev'),
  minifyCss = require('gulp-minify-css'),
  connect=require("gulp-connect"),//搭建本地服务
  uglify = require('gulp-uglify'),
  htmlmin = require('gulp-htmlmin'),
  rename = require('gulp-rename'),
  imagemin = require('gulp-imagemin'),
  runSequence = require('run-sequence'),
  rev = require('gulp-rev'),
  revCollector = require('gulp-rev-collector'),
  babel = require('gulp-babel');
 
//定义css、js源文件路径
var cssSrc = 'style/css/**/*.css',
  cssMinSrc = 'dist/style/css/**/*.css',
  jsSrc = 'style/js/**/*.js',
  jsMinSrc = 'dist/style/js/**/*.js',
  imgSrc = 'style/images/**/*.{png,jpg,gif,ico}',
  imgMinSrc = 'dist/style/images/**/*.{png,jpg,gif,ico}',
  htmlSrc = 'view/**/*.html',
  htmlMinSrc = 'dist/view/**/*.html';
 
//编译less 定义一个less任务(自定义任务名称)
/* gulp.task('less', function(){
  return gulp.src(lessSrc)  //该任务针对的文件
   .pipe(less()) //该任务调用的模块
   .pipe(gulp.dest('css'));//编译后的路径
}); */
 
//压缩css
gulp.task('cssMin', function() {
  return gulp.src(cssSrc)   //压缩的文件 
    .pipe(minifyCss()) //执行压缩
    .pipe(gulp.dest('dist/style/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/style/css'));  //将rev-manifest.json 保存到 dist/css 目录内
});
//压缩js
/* gulp.task('uglify',function(){
  return gulp.src(jsSrc)
   .pipe(babel({
                presets: ['es2015'] // es5检查机制
            }))           
   .pipe(uglify())
   .pipe(gulp.dest('dist/style/js'));
}); */
 //拷贝js
 gulp.task("jsCopy",function(){
 	 return gulp.src(jsSrc).
	 pipe(gulp.dest("dist/style/js")).
	 pipe(connect.reload());
 });
//js生成文件hash编码并生成 rev-manifest.json文件名对照映射
gulp.task('revJs', function(){
  return gulp.src(jsMinSrc)
    .pipe(rev())
    .pipe(rev.manifest())
    .pipe(gulp.dest('dist/style/js'));
});
//压缩image
gulp.task('imageMin', function () {
     return gulp.src(imgSrc)
    .pipe(imagemin())
    .pipe(gulp.dest('dist/style/images'));
});
 //image生成文件hash编码并生成 rev-manifest.json文件名对照映射
gulp.task('revImage', function(){
  return gulp.src(imgMinSrc)
    .pipe(rev())
    .pipe(rev.manifest())  //必须有这个方法
    .pipe(gulp.dest('dist/style/images'));
});
 
//压缩html
gulp.task('htmlMin',function(){
  var options = {
    collapseWhitespace:true,  //从字面意思应该可以看出来,清除空格,压缩html,这一条比较重要,作用比较大,引起的改变压缩量也特别大。
    collapseBooleanAttributes:true,  //省略布尔属性的值,比如:<input checked="checked"/>,那么设置这个属性后,就会变成 <input checked/>。
    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/view'));
});
 //html生成文件hash编码并生成 rev-manifest.json文件名对照映射
gulp.task('revHTML', function(){
  return gulp.src(htmlMinSrc)
    .pipe(rev())
    .pipe(rev.manifest())
    .pipe(gulp.dest('dist/view'));
});
//Html替换css、js文件版本
gulp.task('revHtml', function () {
  return gulp.src(['dist/**/*.json', 'dist/view/**/*.html'])//此处的dist/view/**/*.html是指压缩后的html文件所在目录
    .pipe(revCollector())
    .pipe(gulp.dest('dist/view'));
});
gulp.task('default', function (done) {
  //condition = false;
  runSequence(  //此处不能用gulp.run这个最大限度并行(异步)执行的方法,要用到runSequence这个串行方法(顺序执行)才可以在运行gulp后顺序执行这些任务并在html中加入版本号   
    'cssMin',
	'jsCopy',
    'revCss',
    'revJs',
    'imageMin',
    'revImage',
	'htmlMin', 
	'revHTML',  
    'revHtml',    
    done);
});

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

1.打开node_modules\gulp-rev\index.js
第144行 manifest[originalFile] = revisionedFile;
更新为: manifest[originalFile] = originalFile + '?v=' + file.revHash;
2.打开nodemodules\gulp-rev\nodemodules\rev-path\index.js
10行 return filename + '-' + hash + ext;
更新为: return filename + ext;
3.打开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) ) {
4.打开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;
5.打开node_modules\gulp-rev-collector\index.js
第107行 regexp: new RegExp( '([\/\\\\\'"])' + pattern, 'g' ),
更新为: regexp: new RegExp( '([\/\\\\\'"])' + pattern+'(\\?v=\\w{10})?', 'g' ),
4.执行gulp命令
此时我的执行结果是报了以下错误
《1》报错:gulp hastask is not a function
解决办法:查看 gulp版本,发现是4.0的,将gulp全局和本地版本切回3.9.1

npm i  --save-dev gulp@3.9.1
npm i  --g gulp@3.9.1

接着又报了第二个错
《2》cant find babel-core

1.检查babel版本并替换成7.0.1

2.npm i babel-core babel-loader --save-dev
再次执行就可以了
补充:压缩js文件的时候,会因为 es语法报错,此时需要安装babel,安装完成可能会报第二个错误,最后js文件压缩成功后,项目执行时候会因为js压缩过程中语法的改变又报错,因此我放弃了压缩js文件,把它复制到了目标文件进行了版本替换,整个过程很是曲折,基本达到了想要的效果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥啥都知道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值