解決前端靜態資源版本更新與緩存的問題——通過gulp 在原html文件上自動化添加js、css、img版本號


原理

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試下,我們非常完美的添加上了版本號

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM