天天看點

基于 gulp 的自動化建構之“靜态資源版本管理”--2017年12月"gulp-rev"版本8.1.0

    我安裝完的版本号如下

    "gulp-rev": "^8.1.0",

    "gulp-rev-collector": "^1.2.3",

根據前人的經驗,和解決方法,發現12月的版本又有一些不同,為了讓大家更快的修改,釋出一下我的修改測試後的處理

以下為摘錄修改

在靜态資源版本管理方面,以前用過兩種方案(都是通過後端實作) :

第一種:擷取檔案最新修改時間。可以實作比較好的版本管理效果,但用戶端每一次通路一個資源檔案,伺服器都會動态讀取一次該檔案的最新修改時間。對這種方案,頭腦有限,暫時無法評估其對性能和通路速度的影響。但就版本管理效果來說,更傾向于這一種。

第二種:設定日期常量。版本管理效果非常差。
 
      

目前已實作的新方案如下:

在建構階段計算靜态資源的 hash 值,并将該值以參數的形式追加到 de><link> de>、 de><script> de>中的 URL。

大家需要知道的是,如果某個檔案發生了修改,我這裡會自動修改引用了該檔案的各個子產品的view檔案。

此方案可實作真正的版本管理效果,并且可以确定對性能和通路速度無影響。

1. 預設方案:

如果使用 de >gulp-rev de>  +  de >gulp-rev-collector de> ,預設效果如下:

"/css/style.css" => "/dist/css/style-1d87bebe.css"    
"/js/script1.js" => "/dist/script1-61e0be79.js"    
"cdn/image.gif"  => "//cdn8.example.dot/img/image-35c3af8134.gif"
        

但是如果用上面方法,實作的是非覆寫式更新:即每次修改檔案之後,生成帶新版本号的檔案,但是帶舊版本号的檔案不會被删除,長此以往,最後你會發現檔案夾裡累積了大量帶舊版本号的無用檔案。例如,style.css檔案經過三次更新之後,會累積一下三個檔案:

style-a3654c03aa.css
style-98c5f098bd.css
style-6e4cfcf9de.css      

2. 改良方案:

期望效果:

href="dist/css/style.css" target="_blank" rel="external nofollow"  => href="dist/css/style.css?v=1d87bebe" target="_blank" rel="external nofollow" 
src="dist/js/all.min.js" => src="dist/js/all.min.js?v=98c5f098bd"
src="dist/img/image.gif"  => src="dist/img/image.gif?v=35c3af8134"
      

原理:

(1)de >gulp-revde>根據檔案内容計算生成一個 hash 字元串,如:de >98c5f098bdde>

(2)de >gulp-revde>生成一個映射表,列出映射關系

{
  "all.min.js": "all.min.js?v=98c5f098bd"
}

      
(3)de>gulp-rev-collectorde>根據該映射表 将de><link>de>、de><script>de>URL中的檔案名de>all.min.jsde>替換為de>all.min.js?v=98c5f098bdde>


          

如何修改?

需要對de>gulp-revde>和de>gulp-rev-collectorde>進行修改。修改如下: 修改映射表中 屬性值的格式: 打開de>node_modules\gulp-rev\index.jsde>
第134行 manifest[originalFile] = revisionedFile;


修改為: manifest[originalFile] = originalFile + '?v=' + file.revHash;

第164行 regexp: new RegExp( prefixDelim + pattern, 'g' ),
修改為:regexp: new RegExp( prefixDelim + pattern+'(\\?v=\\w{10})?', 'g' ),
      

修改生成檔案的檔案名(原來是将 hash 值加入到檔案名中,現要檔案名保持不變):

打開 de >node_modules\rev-path\index.js de>

第9行 return modifyFilename(pth, (filename, ext) => `${filename}-${hash}${ext}`);
修改為: return modifyFilename(pth, (filename, ext) => `${filename}${ext}`);

      

打開 de >node_modules\gulp-rev-collector\index.js de>

第40行 var cleanReplacement =  path.basename(json[key]).replace(new RegExp( opts.revSuffix ), '' );
修改為: var cleanReplacement =  path.basename(json[key]).split('?')[0];

      

避免引用 URL 中的版本号累積: de >

dist/js/all.min.js?v=6e4cfcf9de de>  =>  de >dist/js/all.min.js?v=54a62a8eb6?v=6e4cfcf9de de>

打開 de >node_modules\gulp-rev-collector\index.js de>

第139行 regexp: new RegExp(  dirRule.dirRX + pattern, 'g' ),
修改為: regexp: new RegExp( dirRule.dirRX + pattern+'(\\?v=\\w{10})?', 'g' ),

      

3. gulpfile.js 部配置設定置

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

gulp.task('css-rev', function () {
    console.log('開始--計算 css 資源版本号,并生成映射表...');
    return gulp.src(['./Data_Links/css/**/*.css'])
        .pipe(rev())
        //.pipe(gulp.dest('./Data_Links/dist/css'))
        .pipe(rev.manifest({
            path: 'rev-manifest-css.json'
        }))
        .pipe(gulp.dest('./Data_Links/rev'));
});

gulp.task('css', ['css-rev'], function () {
    console.log('開始--修改 css 引用連結的資源版本号...');
    return gulp.src(['./Data_Links/rev/rev-manifest-css.json', './src/tpls/**/*.html'])
        .pipe(revCollector())
        .pipe(gulp.dest('./Data_Links/tpls'));
});

gulp.task('js-rev',['css'],function () {
    console.log('開始--計算 js 資源版本号,并生成映射表...');
    return gulp.src(['./Data_Links/js/**/*.js'])
        .pipe(rev())
        // .pipe(gulp.dest('./Data_Links/dist/js'))
        .pipe(rev.manifest({
            path: 'rev-manifest-js.json'
        }))
        .pipe(gulp.dest('./Data_Links/rev'));
});

gulp.task('js', ['js-rev'], function () {
    console.log('開始--修改 js 引用連結的資源版本号...');
    return gulp.src(['./Data_Links/rev/rev-manifest-js.json', './Data_Links/tpls/**/*.html'])
        .pipe(revCollector())
        .pipe(gulp.dest('./Data_Links/tpls'));
});


      

gulp.task在執行時,會先執行[]中的task任務,以上代碼隻要執行js這個任務,其他3個也會一起執行。

在這裡,我采用源檔案位置和生成後的位置不同的方式,css加版本号的時候引用的是源檔案位,js加版本号的時候引用的是css生成的檔案位,這個可以避免一個情況,js在生成的時候源檔案中css連結沒有版本号,而在生成的時候覆寫css生成的版本号。也可以解決 URL 中的版本号累積的問題?v=xxx?v=xxx

下面的二個被我注釋了,會備份css,js如果你需要可以開啟。

.pipe(gulp.dest('./Data_Links/dist/css')) 
.pipe(gulp.dest('./Data_Links/dist/js'))      

繼續閱讀