gulp添加版本號解決靜態資源緩存問題

實現原理:

第一步:修改js和css文件;
第二步:通過對js,css文件內容進行hash運算,生成一個文件的唯一hash字符串(如果文件修改則hash號會發生變化);
第三步:替換html中的js,css文件名,生成一個帶版本號的文件名;

最終效果

  • 原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>
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
  1. 編寫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"
}

在html中如下:

<link rel="stylesheet" href="../css/default-803a7fe4ae.css">
<script src="../js/app-3a0d844594.js"></script>

顯然這不是我們需要的效果。

  1. 修改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\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];
打開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命令,得到的結果如下(效果正確):

<link rel="stylesheet" href="../css/default.css?v=803a7fe4ae">
<script src="../js/app.js?v=3a0d844594"></script>
background:url("../images/none.png?v=8f204d4")

但是假如我們更改了css和js后,再執行gulp命令,得到的結果會如下:

<link rel="stylesheet" href="../css/default.css?v=33379df310?v=803a7fe4ae">
<script src="../js/app.js?v=3a0d844594?v=3a0d844594"></script>

有沒有發現,會在版本號后面再添加一個版本號,因為gulp只替換了原來文件名,這樣又不符合預期效果了,所以我們想到,還需要修改插件的替換正則表達式。

  1. 繼續更改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效果都是

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

參考文章

如何讓前端強制從服務器拉取最新資源(html、css、js、圖像)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容