使用gulp實現靜態資源版本號替換

使用gulp實現靜態資源版本號替換https://blog.csdn.net/wangjun5159/article/details/75137254

靜態版本號替換的由來

一般,js寫在單獨的文件,而後頁面引用js文件,好比javascript

<script type='text/javascript' src="a.js"></script>
  • 1

在開發時或者上線後,你確定遇到過,明明修改了js,可是不起做用,由於瀏覽器緩存了舊js,只能狂摁ctrl+f5。爲了fix這個問題,一般會添加版本號。如css

<script type='text/javascript' src="a.js?2017080121231"></script>
  • 1

這會帶來兩個問題html

  • 修改了js文件,同時須要修改全部引用js文件的頁面
  • 現代程序爲了追求性能極致,一般將靜態文件,放在cdn,那麼在發佈程序時,就會存在頁面、js誰先發布的問題?答案是,在先後端發佈間隔內,不管先發布誰都會有問題。 
    • 先發布頁面,再發布腳本 
      頁面是新頁面,請求新js,但此時cdn上仍然是老腳本,因此錯誤
    • 先發布腳本,再發布頁面 
      頁面是老頁面,請求老js,但此時cdn上已是新腳本,因此錯誤

分析

  • 修改js文件後,修改引用此文件的全部頁面中的版本號 
    • 最笨的辦法,就是搜索整個工程,而後替換版本號,這是手動的,手動就意味着效率低下、出錯率高,因此,理想狀態下,修改完js後,自動替換版本號,那麼怎麼才能知道須要替換版本號呢?答案是,只要文件內容有變化,就生成新版本號。因此,咱們指望有這麼個工具,能自動實現這個功能。
  • 不管替換誰,都有錯誤,由於咱們是用的覆蓋式發佈,咱們須要增量式發佈 
    • 每次更改js文件,都生成一個新的帶版本的文件,好比原文件是a.js,修改後生成a-v1.js,再修改生成a-v2.js,頁面中都引用新文件,v一、v2就是第一步的版本號,這樣在發佈時,先發布腳本,再發布頁面,就正確了。

優化目標

知道了,靜態資源版本號的由來,咱們再確認一下優化目標,也能夠說是需求,前端

  • 根據內容自動添加版本號
  • 儘可能維持現有工程目錄,不作大幅更改
  • 開發時,自動添加版本號,服務器打包也能添加版本號
  • 能區分開發環境和生產環境,進行差別化處理,好比開發環境不壓縮便於調試,生產環境進行壓縮,減少size

grunt、webpack、gulp選型

目標肯定後,打算從grunt/webpack/gulp中,選取一種實現功能。java

  • grunt據網上說配置很複雜,IO操做多,用的人少,因此放棄了。
  • webpack嘗試後,發現功能很強大,將一切文件當作模塊,會對現有文件更改很大,將依賴的js、css都打包,變更很大,因此放棄。
  • gulp小巧玲瓏,用的正趁手,基於流,開發起來也簡單,因此選用了gulp。 
    • 首先安裝nodejs,如今的前端開發已經離不開nodejs了,建議你們也多接觸nodejs。而後安裝gulp,這個很簡單我才用了本地安裝,由於全局安裝老是找不到,遂放棄,在安裝gulp以前首先建立package.json,在作團隊協做時,會有幫助,其它成員就不用一個個安裝插件,根據package.json安裝一次就好了。package.json至關於maven的pom.xml

gulp具體步驟

建立nodejs配置文件package.json

建立package.json,這是nodejs的配置文件node

npm init -y
  • 1

大致目錄是這樣的webpack

{
  "name": "myapp", "version": "1.0.0", "description": "", "main": "gulpfile.js", "dependencies": {}, "devDependencies": { "gulp": "^3.9.1", "gulp-clean": "^0.3.2", "gulp-clean-css": "^3.9.0", "gulp-jshint": "^2.0.4", "gulp-rename": "^1.2.2", "gulp-rev": "^7.1.2", "gulp-rev-collector": "^1.2.2", "gulp-uglify": "^3.0.0", "gulp-watch": "^4.3.11", "jshint": "^2.9.5", "pump": "^1.0.2", "run-sequence": "^2.2.0" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

能夠看見有個devDependencies,每安裝一個插件,這裏就添加一個,回頭提交時,只提交這個文件就能夠,團隊其餘人執行npm install 就能夠下載package.json中全部的dependencies。爲了接下來能順利執行,全部的依賴已經配置在devDependencies。web

建立gulp的配置文件gulefile.js

gulpfile.js是gulp的配置文件,在裏邊能夠配置不少任務,每一個任務乾的活不同,每一個任務就是一個線程,若是任務之間有依賴,那麼須要指定執行順序。npm

根據設想,分爲src源文件目錄、dist目的文件目錄也就是編譯後後的目錄,rev就是revision修改版本意思,這裏存放着版本插件生成的json文件,裏邊的key值就是要替換文件的路徑json

D:\GULP_WORKSPACE\MYAPP
└─webapp
    |---gulpfile.js ├─dist ├─rev │ ├─css │ └─js └─src ├─css ├─js │ ├─a │ └─b │ └─a.js └─pages └─a.html
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

其它的就很少說了,就是經常使用的幾個插件,思路就是將源文件的js、css根據內容生成添加了版本號的文件,而後搜索html文件,將名字替換爲版本號名字,而後將其它文件copy到目的目錄,還能夠監聽文件變化,若是變化自動執行任務,相似intellij的編譯後觸發熱替換,配置以下

//引入gulp和gulp插件 var gulp = require('gulp'), runSequence = require('run-sequence'), rev = require('gulp-rev'), revCollector = require('gulp-rev-collector'), rename = require('gulp-rename'), uglify = require('gulp-uglify'), clean = require('gulp-clean'), pump = require('pump'), watch = require('gulp-watch'), jshint = require('gulp-jshint') cleanCSS = require('gulp-clean-css');; //定義css、js源文件路徑 var cssSrc = 'src/**/*.css', jsSrc = ['src/**/*.js','!gulpfile*.js']; //監控文件變化 gulp.task('watch', function () { gulp.watch([jsSrc,cssSrc], ['default']); }); //檢查js語法 gulp.task('jslint', function() { return gulp.src(jsSrc) .pipe(jshint()) .pipe(jshint.reporter('default')); }); //清空目標文件 gulp.task('cleanDst', function () { return gulp.src(['dist','rev'], {read: false}) .pipe(clean()); }); //CSS生成文件hash編碼並生成 rev-manifest.json文件名對照映射 gulp.task('revCss', function(){ return gulp.src(cssSrc) .pipe(rev()) // 壓縮css .pipe(cleanCSS({compatibility: 'ie8'})) .pipe(gulp.dest('dist')) .pipe(rev.manifest()) .pipe(gulp.dest('rev/css')); }); //js生成文件hash編碼並生成 rev-manifest.json文件名對照映射 gulp.task('revJs', function(){ return gulp.src(jsSrc) .pipe(rev()) //壓縮 .pipe(uglify()) .pipe(gulp.dest('dist')) //生成rev-manifest.json .pipe(rev.manifest()) .pipe(gulp.dest('rev/js')); }); //Html替換css、js文件版本 gulp.task('revHtml', function () { return gulp.src(['rev/**/*.json', 'src/**/*.html']) .pipe(revCollector({ replaceReved: true })) .pipe(gulp.dest('dist')); }); // 將非js、非css移動到目標目錄 gulp.task('mvNotDealAsset', function () { return gulp.src(['src/**/*','!src/**/*.css', '!src/**/*.js','!src/**/*.html']) .pipe(gulp.dest('dist')); }); //開發構建 gulp.task('dev', function (done) { condition = false; runSequence( ['jslint'], ['cleanDst'], ['revCss'], ['revJs'], ['revHtml'], ['mvNotDealAsset'], ['watch'], done); }); gulp.task('default', ['dev']);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

區分生產環境、開發環境

有時須要區分開發環境和正式環境,好比開發環境下,不須要壓縮、不要混淆,方便調試。而正式環境,須要壓縮、混淆、合併,減少文件大小。幸運的是,gulp提供了參數控制,

--env production --env development
  • 1
  • 2

好比這裏寫圖片描述

未完待續

還有一塊沒寫,就是gulp與intellij的結合,intellij中tomcat啓動時,自動執行gulp任務,並監聽文件變化,這樣的話,開發時就不用狂摁ctrl+f5了

效果

在html/jsp中爲引用的css、js根據內容信息摘要自動添加版本號,若是內容不變則維持原版本號。

<script type='text/javascript' src="a-1df23s4.js"></script>
相關文章
相關標籤/搜索