[第八屆IT邦幫忙鐵人賽] Deploy : CDN Solution 1 - Hash and Replace

前言

CDN 的原意是透過節點與快取方式於增加網站的速度與穩定度,但在開發、維護專案的過程中,常常遭遇到更新javascript、css或圖片檔案後沒有作用的情形發生(因為快取),有些 CDN 網站有提供 flush 功能清除快取,但使用上卻有次數限制,若修改程式次數較頻繁,仍會遇到修改無法及時生肖的問題。在收集 CDN 相關資料後發現多數開發人員建議在 CDN 上放置靜態或不常更動的檔案,若將常異動的檔案放上則違背 CDN 的原始用意的意思,但為了解決程式更新問題,本篇與下篇文章將透過一些**特殊方法(旁門左道)**的方式進行排除 cache 問題(僅供參考),若有錯誤或任何建議,請各位先進不吝提出,謝謝!


 

介紹

首先,我們先了解本篇文章的專案架構,如下圖:
http://ithelp.ithome.com.tw/upload/images/20161215/20091494IXa59zRTc2.png
publish: 經過處理後的程式放置資料夾,進行 deploy 的資料夾
js: 放置專案所需要的 js 檔案
index.html: 首頁

`

我們這次實作的步驟如下:

  1. 清除 publish 內所有程式
  2. 依據 TeamCity 傳入的版本號碼產生一組 hash code。
  3. 依據產生的hash code,將所有 .js 檔案重新命名為 name-HashCode.js,如:
    app_desktop.js 改成 app_desktop-1db6qa.js 後放入 publish\js\ 下。
  4. 更改 index.html 內引入的js檔案名稱,並放入 publish\js\ 下,如:
    <script src="app_desktop.js"></script> //改成
    <script src="app_desktop-1db6qa.js"></script> 

透過更改檔案名稱與引入名稱,讓 CDN 認定是不同的檔案,進而達到清除cache的效果。

`

我們需要用到三個套件,分別為 gulp-replace, gulp-hash 與 gulp-clean。分別可以透過下列指令進行安裝。

npm install --save-dev gulp-replace
npm install --save-dev gulp-hash
npm install --save-dev gulp-clean

http://ithelp.ithome.com.tw/upload/images/20161215/20091494ayTQ9Rii8P.png

http://ithelp.ithome.com.tw/upload/images/20161215/200914949pAER7wFuR.png

http://ithelp.ithome.com.tw/upload/images/20161215/20091494NmoE3ginFb.png

`

首先,我們透過下列程式碼清除 publish 資料夾,完成我們第一項工作。

var	clean = require('gulp-clean');

gulp.task('uploadCDN',function(){
    gulp.src(['publish/*'], {read: false})
        .pipe(clean({force: true}));
        
        //下方程式碼略
});

`

接下來,我們透過 buildVersion(透過 yarg 取得 TeamCity 目前佈署的版本號)參數產生一組 hash code,變更 js 檔案名稱後放入publish/js;並且產生一個assets.json,裡面儲存剛才產生的新檔名。

var args = require('yargs').argv;
var hash = require('gulp-hash');

gulp.task('HashProcess',function(){
  
  //上方程式碼略
  
  var hashcode = hash({'version': args.buildVersion });
  gulp.src(['js/app_desktop.js','js/vendors.js'])
    .pipe(hashcode)
    .pipe(gulp.dest('publish/js'))
    .pipe(hash.manifest('assets.json'))
    .pipe(gulp.dest(''));
  
  //下方程式碼略
});

產生的asset.json如下圖:
http://ithelp.ithome.com.tw/upload/images/20161215/20091494xsjIfj4zjg.png

`

最後我們要更改 index.html 內的程式碼,更改方法如下:
Step 1.從 assets.json取得目前新js檔案名稱。
Step 2.替換 index.html 內的檔案名稱(cdn url + 新js檔名)。

var replace = require('gulp-replace');

    
gulp.task('uploadCDN',function(){
   
  //上方程式碼略
  var json = require('./assets.json');
  gulp.src(['index.html'])
    .pipe(replace('app_desktop.js', 'http://cdn.website.com/' + json['app_desktop.js']))
    .pipe(replace('vendors.js', 'http://cdn.website.com/' + json['vendors.js']))
    .pipe(gulp.dest('publish/js'));       
});

`

最後我們的程式碼會像這樣:

var gulp = require('gulp');
var args = require('yargs').argv;
var hash = require('gulp-hash');
var	clean = require('gulp-clean');
var replace = require('gulp-replace');

gulp.task('HashProcess',function(){
	gulp.src(['publish/*'], {read: false})
        .pipe(clean({force: true}));
		
    var hashcode = hash({'version': args.buildVersion });
    gulp.src(['js/app_desktop.js','js/vendors.js'])
        .pipe(hashcode)
        .pipe(gulp.dest('publish/js'))
        .pipe(hash.manifest('assets.json'))
        .pipe(gulp.dest(''));

    var json = require('./assets.json');
        console.log(json['app_desktop.js']);
        console.log(json['vendors.js']);

    gulp.src(['index.html'])
        .pipe(replace('app_desktop.js', 'http://cdn.website.com/js/' + json['app_desktop.js']))
        .pipe(replace('vendors.js', 'http://cdn.website.com/js/' + json['vendors.js']))
        .pipe(gulp.dest('publish/'));
});

輸入下列指令後,您可以在publish看到處理好的 js 與 index.html,接下來只要透過前面幾個章節介紹的 delpoy 的方法放上網頁伺服器或 CDN 完成工作。

gulp HashProcess --build-version 1.0.0.1

http://ithelp.ithome.com.tw/upload/images/20161215/20091494wwtSPwLOuG.png

http://ithelp.ithome.com.tw/upload/images/20161215/20091494DbYevQPRdf.png

http://ithelp.ithome.com.tw/upload/images/20161217/20091494STCGz4fq3P.png


上一篇:Deploy : Deploy to Azure CDN
下一篇:Deploy : Deploy : CDN Solution 2 - 資料夾命名規則
返回目錄


參考資料

註:本系列文章將於2016 IT邦幫忙鐵人賽進行同時,一併發佈於個人blogger與dotblog。