原理
1、执行gulp指令js、css和img内文件添加版本号,生成一个文件的唯一hash字符串
2、更新js和css内代码,通过对js,css文件内容进行分析,如果文件修改则hash号会发生变化
3、替换html中的js,css文件名,生成一个带版本号的文件名
原html文件代码
预期效果:在原目录结构下html文件代码
具体操作方法如下:
1、首先安装nodejs和淘宝镜像
从官网(https://nodejs.org/en/)下载nodejs,然后无脑下一步。
安装淘宝镜像: 打开终端将如下代码贴进去回车,registry = https://registry.npm.taobao.org
2、安装gulp和gulp插件
cnpm install gulp -g
3、编写gulpfile.js(里面的路径更具个人项目而定)
var gulp = require('gulp'); var less = require('gulp-less'); var sass = require('gulp-sass'); var connect = require('gulp-connect'); var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); var rename = require('gulp-rename'); var minifyCSS = require('gulp-minify-css'); var imagemin = require('gulp-imagemin'); var debug = require('gulp-debug'); var changed = require('gulp-changed'); var gulpif = require('gulp-if'); var useref = require('gulp-useref'); var rev = require('gulp-rev'); var revCollector = require('gulp-rev-collector'); var fileinclude = require('gulp-file-include'); var gulpSequence = require('gulp-sequence'); var plumber = require('gulp-plumber'); var postcss = require('gulp-postcss'); var px2rem = require('postcss-px2rem'); var autoprefixer = require('gulp-autoprefixer'); var htmlmin = require('gulp-htmlmin'); gulp.task('copyhtml', function(){ return gulp.src(['html/**/*html'],{base:"."}) // .pipe(changed('../../dist/wap')) .pipe(fileinclude({ prefix: '@@', basepath: '@file' })) .pipe(gulp.dest('../dist')) .pipe(debug({title: 'HTML文件:'})) }); //压缩拷贝images gulp.task('images', function(){ return gulp.src('img/**/*.{jpg,png,gif}',{base:"."}) .pipe(changed('../dist')) .pipe(rev()) .pipe(imagemin()) .pipe(gulp.dest('../dist')) .pipe(rev.manifest()) .pipe(gulp.dest('rev/img')) .pipe(debug({title: 'img文件:'})) }); //拷贝data gulp.task('data', function(){ return gulp.src('data/**/*') .pipe(changed('../dist/data')) .pipe(rev()) .pipe(gulp.dest('../dist/data')) .pipe(rev.manifest()) .pipe(gulp.dest('rev/data')) .pipe(debug({title: 'data文件:'})) }); //拷贝font gulp.task('copyfont', function(){ return gulp.src('font/**/*') .pipe(changed('../dist/font')) .pipe(gulp.dest('../dist/font')) .pipe(debug({title: 'font文件:'})) }); //拷贝music gulp.task('music', function(){ return gulp.src('music/**/*') .pipe(changed('../dist')) .pipe(rev()) .pipe(gulp.dest('../dist/music')) .pipe(rev.manifest()) .pipe(gulp.dest('rev/music')) .pipe(debug({title: 'music文件:'})) }); //压缩 单个 css gulp.task('css', function(){ return gulp.src(['./**/*.css','!node_modules/**/*.css'],{base:"."}) .pipe(changed('../dist')) .pipe(minifyCSS()) .pipe(gulp.dest('../dist')) .pipe(debug({title: '拷贝CSS文件:'})) }); //js gulp.task('js', function(){ return gulp.src(['js/**/*.js','vendor/**/*.js'],{base:"."}) .pipe(changed('../dist')) .pipe(uglify().on('error', function (e) { console.log('错误:'+e) })) .pipe(gulp.dest('../dist')) .pipe(debug({title: 'JS文件:'})) }); //合并页面资源 gulp.task('useref',['copyhtml'],function(){ return gulp.src('./html/**/*.html',{base:'.'}) // .pipe(changed('../../develop/wap')) .pipe(useref()) .pipe(gulpif('*.css',minifyCSS())) .pipe(gulpif('*.css',gulp.dest('../dist/css'))) .pipe(gulpif('*.js',uglify())) .pipe(gulpif('*.js',gulp.dest('./../dist/js'))) .pipe(gulpif('*.html',gulp.dest('../dist'))) .pipe(debug({title: '合并文件:'})) }); gulp.task('cssHash',['useref'], function(){ return gulp.src(['./../dist/**/*.css'],{base:"."}) // .pipe(changed('../../dist/wap')) .pipe(rev()) .pipe(gulp.dest('../dist')) .pipe(rev.manifest()) .pipe(gulp.dest('rev/css')) }); gulp.task('jsHash',['useref'], function(){ return gulp.src(['./../dist/**/*.js','./../dist/vendor/**/*.js'],{base:"."}) // .pipe(changed('../../dist/wap')) .pipe(rev()) .pipe(gulp.dest('../dist')) .pipe(rev.manifest()) .pipe(gulp.dest('rev/js')) }); //替换HTML中的hash引用 gulp.task('rev',function () { return gulp.src(['rev/**/*.json', './../dist/**/*.html'],{base:"."}) .pipe(revCollector({replaceReved: true})) .pipe(gulp.dest('../dist')) console.log('加版本号...') }); gulp.task('htmlmin', function () { var options = { removeComments: true,//清除HTML注释 collapseWhitespace: true,//压缩HTML collapseBooleanAttributes: true,//省略布尔属性的值 <input checked="true"/> ==> <input /> removeEmptyAttributes: true,//删除所有空格作属性值 <input id="" /> ==> <input /> removeScriptTypeAttributes: true,//删除<script>的type="text/javascript" removeStyleLinkTypeAttributes: true,//删除<style>和<link>的type="text/css" minifyJS: true,//压缩页面JS minifyCSS: true//压缩页面CSS }; }); gulp.task('default', ['copyhtml','css','js','images','data','copyfont','music','useref','cssHash','jsHash'], function(){ gulp.run('rev') console.log('打包成功-------------------------------------'); }); gulp.task('test', ['copyhtml','css','js','images','data','copyfont','music'], function(){ console.log('测试版打包成功-------------------------------------'); }); // gulp.task('default', ['build','watch']); // 1、拷贝HTML 到 dist // 2、拷贝css 到 dist 加hash // 3、拷贝js 到 dist 加hash // 4、拷贝img 到 dist 加hash // 5、拷贝data 到 dist 加hash // 6、拷贝music 到 dist 加hash // 6、useref合并页面资源 到 dist 并加hash(使用时添加特定格式标签 不使用的话 不影响其他配置)
4、到指定目录下执行cnpm install
执行gulp指令后的结果
很显然,结果并不是我们想要得到,需要我们继续看下去~
5、去node_moduls找到gulp-rev和gulp-rev-collector进行更改
打开node_modules\gulp-rev\index.js 第144行 manifest[originalFile] = revisionedFile; 更新为: manifest[originalFile] = originalFile + '?v=' + file.revHash;
打开node_modules\gulp-rev\node_modules\rev-path\index.js 10行 return filename + '-' + hash + ext; 更新为: return filename + ext;
打开node_modules\gulp-rev-collector\index.js 40行let cleanReplacement = path.basename(json[key]).replace(new RegExp( opts.revSuffix ), '' ); 更新为: let cleanReplacement = path.basename(json[key]).split('?')[0];
163行regexp: new RegExp( prefixDelim + pattern, 'g' ) 更新为: regexp: new RegExp( prefixDelim + pattern+'(\\?v=\\w{10})?', 'g' )
好了再执行下gulp试下,我们非常完美的添加上了版本号