1. 程式人生 > >gulp自動新增靜態檔案版本號方案

gulp自動新增靜態檔案版本號方案

系統發版後客戶端快取更新方案

一。解決思路:
1. 利用gulp根據靜態檔案(JS,CSS,圖片)內容生成對應的HASH值作為它的版本號,檔案內容變化則版本號跟著變(需處理生成版本號的位置,不同路徑下同名檔案HASH值覆蓋問題,JSP檔案編碼問題等,已在下面給出的gulpfile.js和環境配置中給出處理方案)。

  1. minify型別的引用需做特殊處理,jsp中做過minfy優化後,為它加版本號必須加到最後一個引用檔案上,否則會出錯,由於不同的jsp檔案中每個minify引用的最後一個靜態檔案不同,所以需要新增一個公共minify_version.js 新增到需要處理快取問題的minify引用裡並放置最後,每次發版前修改公共minify_version.js(如寫入一條註釋或發版日期,只要改變檔案內容即可),這樣在使用gulp處理時可自動為此型別的引用新增版本號。

二。安裝配置gulp環境
1 安裝node.js https://nodejs.org/en/
node -v檢視安裝的nodejs版本,出現版本號,說明剛剛已正確安裝nodejs。
npm -v檢視npm的版本號,npm是在安裝nodejs時一同安裝的nodejs包管理器

(安裝cnpm 代替 npm*
npm(node package manager)nodejs的包管理器,用於node外掛管理(包括安裝、解除安裝、管理依賴等)
但是因為npm安裝外掛是從國外伺服器下載,受網路影響大,可能出現異常, cnpm“這是一個完整 npmjs.org 映象,你可以用此代替官方版本(只讀),同步頻率目前為 10分鐘 一次以保證儘量與官方服務同步。”;

  1. 安裝gulp外掛(新建個gulptest目錄,命令列切換到此目錄,然後順序執行)
    cnpm install gulp -g
    cnpm install –save-dev gulp
    cnpm install –save-dev gulp-rev
    cnpm install –save-dev gulp-rev-collector
    cnpm install –save-dev run-sequence
    cnpm install –save-dev gulp-convert-encoding

3.修改gulp外掛的index.js配置檔案:
詳見後續附錄1

  1. gulptest目錄下新建package.json,他是基於node.js必不可少的配置檔案
    詳見後續附錄2

5.編寫gulpfile.js任務檔案,修改為js檔案型別放到gulptest目錄下(專案使用的gulpfile.js,可根據具體專案修改裡面路徑即可)
詳見後續附錄3

6.DOS命令列切換到gulptest目錄下,執行gulp,觀察結果。

三。 GULP處理後的效果:

非MINIFY型別利用GULP給靜態檔案連結加上版本號效果:

 無版本號的引用:

 gulp新增版本號後的引用:

MINIFY型別利用GULP給靜態檔案連結加上版本號效果:

 無版本號的引用:

 新增版本號後的引用:

備註:
Css和靜態圖片的處理方式和js類似,不再詳述。

********************************************************** 附錄1 **********************************************************

一。更改gulp-rev和gulp-rev-collector(重要,不配置版本號不是加到?後面)

1.開啟node_modules\gulp-rev\index.js
第144行 manifest[originalFile] = revisionedFile;
更新為: manifest[originalFile] = originalFile + ‘?v=’ + file.revHash;

2.開啟nodemodules\gulp-rev\nodemodules\rev-path\index.js
10行 return filename + ‘-’ + hash + ext;
更新為: return filename + ext;

3.開啟node_modules\gulp-rev-collector\index.js
31行if ( !_.isString(json[key]) || path.basename(json[key]).replace(new RegExp( opts.revSuffix ), ” ) !== path.basename(key) ) {
更新為: if ( !_.isString(json[key]) || path.basename(json[key]).split(‘?’)[0] !== path.basename(key) ) {

二。避免多次執行後加上多個版本號

  1. 開啟 node_modules\gulp-rev-collector\index.js 115 行
    regexp: new RegExp( ‘([\/\\\’”])’ + pattern, ‘g’ ),
    更新為 regexp: new RegExp( ‘([\/\\\’”])’ + pattern+’(\?v=\w{10})?’, ‘g’ ),

三。新增一個pwd_base引數,使其生成json檔案時可以指定字首(用於區分不同資料夾下相同檔名問題)

1.修改node_modules\gulp-rev\index.js,搜尋,新增一個pwd_base引數,用於設定根目錄
opts = objectAssign({
path: ‘rev-manifest.json’,
merge: false,
// Apply the default JSON transformer.
// The user can pass in his on transformer if he wants. The only requirement is that it should
// support ‘parse’ and ‘stringify’ methods.
transformer: JSON,
pwd_base:” //增加根目錄字首,避免不同路徑下同名檔案版本號相互覆蓋,wangwei 20170308
}, opts, pth);

2.修改node_modules\gulp-rev\index.js,搜尋下列程式碼,新增originalFile = opts.pwd_base + originalFile;行
return through.obj(function (file, enc, cb) {
// ignore all non-rev’d files
if (!file.path || !file.revOrigPath) {
cb();
return;
}

        var revisionedFile = relPath(file.base, file.path);
        var originalFile = path.join(path.dirname(revisionedFile), path.basename(file.revOrigPath)).replace(/\\/g, '/');

        originalFile = opts.pwd_base + originalFile;  //新增行 wangwei 20170308

        //manifest[originalFile] = revisionedFile;
        manifest[originalFile] = originalFile + '?v=' + file.revHash;

        cb();
}

********************************************************** 附錄1 **********************************************************

********************************************************** 附錄2 **********************************************************
{
“name”: “test”,
“version”: “1.0.0”,
“description”: “This is for study gulp project !”,
“homepage”: “”,
“repository”: {
“type”: “git”,
“url”: “https://git.oschina.net/xxxx
},
“author”: {
“name”: “surging”,
“email”: “[email protected]
},
“license”: “ISC”,
“devDependencies”: {
“gulp”: “^3.9.1”,
“gulp-bom”: “^1.0.0”,
“gulp-cheerio”: “^0.6.2”,
“gulp-concat”: “^2.6.1”,
“gulp-convert-encoding”: “^1.0.0”,
“gulp-less”: “^3.0.0”,
“gulp-replace”: “^0.5.4”,
“gulp-rev”: “^7.1.2”,
“gulp-rev-collector”: “^1.1.1”,
“gulp-uglify”: “^2.0.1”,
“run-sequence”: “^1.2.2”
}
}

********************************************************** 附錄2 **********************************************************

********************************************************** 附錄3 **********************************************************
/**
* wangwei 20170307
* 自動生成jsp檔案中引用的的js,css檔案的版本號,解決客戶端快取問題
*/

//引入gulp和gulp外掛
var gulp = require(‘gulp’),
runSequence = require(‘run-sequence’),
rev = require(‘gulp-rev’),
convertEncoding = require(‘gulp-convert-encoding’),
revCollector = require(‘gulp-rev-collector’);

//定義專案檔案跟目錄(修改為自己的)
var projectRootPath = ‘D:/MyEclipse8.5/Workspaces/CfgWebModule2017/WebContent’;

//定義css、js檔案路徑,是本地css,js檔案的路徑,可自行配置
var cssUrl = projectRootPath+’/*/.css’,
minifyCssVersionUrl = projectRootPath+’/css/minify_version.css’,
jsUrl = projectRootPath+’/*/.js’, //非minify方式引用的js檔案
minifyJsVersionUrl = projectRootPath+’/js/minify_version.js’; //控制minify方式引用的js檔案是否更新(發版前往此檔案中寫入一條註釋即可,註釋內容隨意,每個/min方式最後加上對此js檔案的引用)

//CSS生成檔案hash編碼並生成
gulp.task(‘revCss’, function(){
return gulp.src(cssUrl)
.pipe(rev())
.pipe(rev.manifest(‘rev-manifest-css1.json’,{pwd_base:’<%=request.getContextPath()%>/’}))
.pipe(gulp.dest(‘rev/css’));
});
//CSS生成檔案hash編碼並生成 minify 方式
gulp.task(‘revMinifyVersionCss’, function(){
return gulp.src(minifyCssVersionUrl)
.pipe(rev())
.pipe(rev.manifest(‘rev-manifest-css2.json’,{pwd_base:’css/’}))
.pipe(gulp.dest(‘rev/css’));
});

//js生成檔案hash編碼並生成
gulp.task(‘revJs’, function(){
return gulp.src(jsUrl)
.pipe(rev())
.pipe(rev.manifest(‘rev-manifest1.json’,{pwd_base:’<%=request.getContextPath()%>/’}))
.pipe(gulp.dest(‘rev/js’));
});

//js生成檔案hash編碼並生成 minify 方式
gulp.task(‘revMinifyVersionJs’, function(){
return gulp.src(minifyJsVersionUrl)
.pipe(rev())
.pipe(rev.manifest(‘rev-manifest2.json’,{pwd_base:’js/’}))
.pipe(gulp.dest(‘rev/js’));
});

//jsp更換css、js檔案版本 (此處測試只替換專案涉及到訂單頁面的幾個jsp檔案)
gulp.task(‘revJsp’, function () {
return gulp.src([‘rev//.json’, projectRootPath+’//orderEdit_body.jsp’]) /原始檔路徑*/
.pipe(convertEncoding({from:’GBK’,to: ‘utf-8’})) //專案中jsp檔案時utf-8編碼的註釋掉此行
//.pipe(replace(“<%=request.getContextPath()%>”,”E:/gulpTest/dest/jsp”)) //替換為真實路徑
//.pipe(replace(“,/js/”,”,/minify/js/”)) //minify裡檔案版本號處理
//.pipe(replace(“,/order/”,”,/minify2/order/”)) //minify裡檔案版本號處理
.pipe(revCollector())
//.pipe(replace(“,/minify/js/”,”,/js/”)) //minify裡檔案版本號處理
//.pipe(replace(“,/minify2/order/”,”,/order/”)) //minify裡檔案版本號處理
//.pipe(replace(“E:/gulpTest/dest/jsp”,”<%=request.getContextPath()%>”)) //替換為真實路徑
.pipe(convertEncoding({from:’utf-8’,to: ‘GBK’})) //專案中jsp檔案時utf-8編碼的註釋掉此行
.pipe(gulp.dest(projectRootPath+’/’)); /輸出路徑/
});

//開發構建
gulp.task(‘dev’, function (done) {
condition = false;
runSequence(
[‘revCss’],
[‘revMinifyVersionCss’],
[‘revJs’],
[‘revMinifyVersionJs’],
[‘revJsp’],
done);});
gulp.task(‘default’, [‘dev’]);
********************************************************** 附錄3 **********************************************************

備註:
如果輸入node -v,或npm -v或gulp提示不是外部命令,確認下使用者環境變數PATH中是否有此命令的輸出內容
npm config get prefix
確認全域性環境變數path中是否有nodejs的安裝路徑

//下面是一些備忘參考資訊,實際應用上面的部分就夠了

/******************************************************實際專案應用中需要解決的問題(備忘用,實際應用上面的部分就夠了):******************************************************/

原始檔路徑
js
orderConfig.js
order
order/edit
orderEdit_body.jsp(src指向js/orderConfig.js)
order/edit/sub
orderEdit_body.jsp(src指向order/edit/sub/js/orderConfig.js)
order/edit/sub/js
orderConfig.js
order/edit/std
orderEdit_body.jsp(src指向order/edit/std/js/orderConfig.js)
order/edit/std/js
orderConfig.js

  1. 不同路徑下相同檔名的問題,若直接生成,則所有引用orderConfig.js的版本號都一樣,取的都是js/orderConfig.js的hash值
    檢視生成的rev\js\rev-manifest.json檔案發現雖然為不同檔案生成了不同的版本號
    “js/orderConfig.js”: “<%=request.getContextPath()%>/js/orderConfig.js?v=4246752bdb”,
    “order/edit/std/js/orderConfig.js”: “<%=request.getContextPath()%>/order/edit/std/js/orderConfig.js?v=6123c4e86d”,
    “order/edit/sub/js/orderConfig.js”: “<%=request.getContextPath()%>/order/edit/sub/js/orderConfig.js?v=359a924f33”,
    但是因為jsp中引用時src都帶有<%=request.getContextPath()%>,所以導致沒有嚴格符合json的匹配項,進而匹配替換時可能使用最短的路徑給覆蓋了




    解決方法:
    生成rev\js\rev-manifest.json檔案時統一加上字首<%=request.getContextPath()%>,使其匹配jsp中的src能夠找到完全匹配項,新增引數方法見下面。
    引數使用方法如下:
    gulp.task(‘revJs2’, function(){
    return gulp.src(jsUrl)
    .pipe(rev())
    .pipe(rev.manifest(‘rev-manifest1.json’,{pwd_base:’<%=request.getContextPath()%>/’})) //指定字首,並指定生成的json檔名稱
    .pipe(gulp.dest(‘rev/js’));
    });

    新生成的rev-manifest1.json如下,重新gulp,這樣就解決了不同資料夾下相同檔名的問題.
    “<%=request.getContextPath()%>/js/orderConfig.js”: “<%=request.getContextPath()%>/js/orderConfig.js?v=4246752bdb”,
    “<%=request.getContextPath()%>/order/edit/std/js/orderConfig.js”: “<%=request.getContextPath()%>/order/edit/std/js/orderConfig.js?v=6123c4e86d”,
    “<%=request.getContextPath()%>/order/edit/sub/js/orderConfig.js”: “<%=request.getContextPath()%>/order/edit/sub/js/orderConfig.js?v=359a924f33”,

2.解決jsp檔案中minify型別的src引用問題(這樣不行,minify的版本號只能加到最後一個js檔案上,可根據這個方法簡單改造下)。

相關推薦

gulp自動新增靜態檔案版本方案

系統發版後客戶端快取更新方案 一。解決思路: 1. 利用gulp根據靜態檔案(JS,CSS,圖片)內容生成對應的HASH值作為它的版本號,檔案內容變化則版本號跟著變(需處理生成版本號的位置,不同路徑下同名檔案HASH值覆蓋問題,JSP檔案編碼問題等,已在下面

gulp自動新增版本

1.安裝Gulp npm install --save-dev gulp 2.分別安裝gulp-rev、gulp-rev-collerctor npm install --save-dev gulp-

修復BUG:gulp自動新增版本修復對CSS中background:url()的匹配問題

前天說要找到一個完美的解決方案,今天發動了各路大神,總算是搞定了.問題描述: 修改gulp-rev-append外掛實現自動修改檔案中靜態資源連結新增md5版本號。但是前天有一點點很遺憾,對CSS中background:url()的匹配還存在一點點不足,url()必須帶單引

Gulp開發:Gulp自動新增版本

"/css/style.css" => "/dist/css/style-1d87bebe.css" "/js/script1.js" => "/dist/script1-61e0be79.js" "cdn/image.gif" =>

maven-replacer-plugin 靜態資源版本解決方案(css/js等)

本文介紹如何使用 maven 的 com.google.code.maven-replacer-plugin 外掛來自動新增版本號,防止瀏覽器快取。 目錄 1.解決方案 2.原始檔案和最終生成效果 3.pom.xml 中外掛新增 4.html中 css/js 檔案引用規則 5.結語 1.解決方案 解

VS 2013 編譯 自動更新檔案版本

編譯自動生成檔案版本號,並隨著時間的改變而變化。 本工程是c#工程。 開啟assemblyInfo.cs檔案;修改如下 // 程式集的版本資訊由下面四個值組成: // // 主版本 //

Pycharm在建立py檔案時,如何自動新增預設檔案頭註釋?

PyCharm是一款很好用的編寫Python工程的IDE,用PyCharm建立一個Python檔案或者向工程新增一個.py檔案時,為了更好的使所編寫的程式碼在各操作環境更好的執行,我們往往需要在.py檔案中新增標頭檔案標註相關資訊。例如: 開啟PyCharm程式,根據選單欄中按照如下進入設定: Fil

c++ 獲取檔案版本

連結器->輸入->附加依賴項 新增Version.lib,msdn上記錄的是新增mincore.lib,這個是錯的。 標頭檔案:Winver.h GetCurrentVersion() { wchar_t versionCurrent[25]; wchar_t versio

怎麼取檔案版本 WindowsAPI之GetFileVersionInfo函式和VerQueryValue函式

VS_FIXEDFILEINFO結構包含了檔案的版本資訊: typedef struct tagVS_FIXEDFILEINFO { DWORD dwSignature; //包含的值是0xFEEF04BD DWORD dwStrucVersion; //該結構

C++ 獲取檔案版本的程式碼

// Test.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <Windows.h> #include <tchar.h> #include <string> #include

修改ipa檔案版本

對於開發者來說,給使用者提供ipa檔案,使用者可以要你修改下版本號,選擇是升級還是維持目前版本。遇到這種情況我們可以重新打包,不過僅僅是修改版本號就重新打包,似乎又心有不甘。那麼問題來了,有沒有辦法直接在ipa檔案中修改版本號呢?下面分析一下: 1. ipa版本號就在包中的

Qt Creator自動使用svn原始碼版本編譯

    有時我們想在編譯工程時,使用 svn 的原始碼版本號來作為 build 的一個子版本號;或者只是為了識別某個釋出版本,與原始碼對應起來。    在 Linux 下面有很多的解決方案,使用 svn 工具和一些 shell 命令再加上 -D 選項就可以達到上述目的。   

在阿里雲上部署Django應用後,頁面403錯誤,始終無法載入靜態檔案的解決方案

設定好了 nignx uwsgi 還有一大堆亂七八糟的東西之後, 費勁九牛二虎之力,好不容易登上了自己寫的網站,結果卻發現,靜態檔案全都沒有加載出來… mdzz!!! 改來改去也改不好,萬般無奈,又在 bing 上搜索了一下,發現了另一個和我一樣蠢得同學

手機插上電腦,看不到新增檔案的解決方案

把android手機插上電腦,有的時候會看不到你想看到的檔案,例如:new File產生的檔案,某些軟體下載同步的檔案。 這讓人很惱火,在網上搜索了一下,有幾個行之有效的方案: 1,重啟手機----筆者測試通過 2,如果是外接SD卡,在“設定”->"儲存"裡,選擇解除

前端開發靜態檔案自動新增版本解決方案

前端開發中不可避免的會遇到快取問題,那麼如何使給這些靜態自動給新增版本號使修改後的內容立即生效呢?下面講下我找到的兩種方法: 一、通過獲取檔案最後修改時間 原理:通過伺服器端語言讀取檔案最後一次修改修改時間,然後將獲取的時間作為版本號。 以php為例: <?p

前端靜態資源版本更新與快取之——通過gulp 在原html檔案上自動化新增js、css版本

原理 修改js和css檔案 通過對js,css檔案內容進行hash運算,生成一個檔案的唯一hash字串(如果檔案修改則hash號會發生變化) 替換html中的js,css檔名,生成一個帶版本號的檔名 方案 現在網上的方案都是生成一個新的dist目錄,

使用gulp為專案中的檔案自動新增版本之實踐思路

需要用到的Gulp外掛:1、gulp-rev2、gulp-rev-format3、gulp-rev-replace要實現html中增加版本號的效果:<link rel="stylesheet" href="/Public/css/lib/base.css?v=14780

使用gulp對引用的檔案新增版本

cnpm install —-save-dev gulp cnpm install --save-dev gulp del cnpm install gulp-uglify gulp-uglify gulp-minify-css gulp-rev gulp-re

使用gulp進行自動在js檔案後加版本,使在更新的時候不必手動清理快取

原理 如果不是第一次訪問這個網頁,瀏覽器會留下js或css的快取,這對開發人員釋出新版本系統的時候會起到不利影響, 總會叫使用者去清理快取.解決方案是在js或css檔案後面加版本號,如: <script src="src/components/$m

gulp自動化壓縮合並、加版本解決方案

nal efi fun 完成 文件添加 pda ndb fault index 雖然網上有很多的 gulp 構建文章,但是很多都已經隨著 gulp 插件的更新無法運行了。因此,我寫了這個比較簡單的構建方案。 如果還不熟悉 gulp 的插件,可以閱讀上一篇文章:精通gu