通过gulp自动构建项目静态资源的版本号

通过gulp自动构建项目前端静态资源的版本号,解决浏览器缓存导致更新不及时的问题。

问题描述

项目上线后,正常的改动升级不可避免,后端的改动还好说。服务发布完成就行了,但是前端页面因为有浏览器缓存导致js、css、图片等资源不会立即更新,这就导致项目升级后,客户端看到的可能还是旧的资源。需要手动清理浏览器缓存后再刷新才能更新到最新版本。 这就需要通过资源文件版本号来实现客户端同步的问题。

例如:
html页面中的js引用如下:

1
<script type="text/javascript" src="js/common/task.js"></script>

更改后的js引用如下:

1
<script type="text/javascript" src="js/common/task.js?v=56365ee35d"></script>

这样如果浏览器发现src引用的有更改,则会重新从服务器端请求该文件,这样可以实现同步了。

如果只有一个html页面的话还好修改,但是一般现在的项目中html会有多个,js、css、图片也会有很多,所以手动管理就会变的很耗时间,这时候就需要一个自动化维护的手段来实现,现在nodejs很火,基于nodejs实现的gulp就是一个流式自动化构建工具。

原理

1、生成静态资源的文件hash码,保存到指定的文件。
2、如果文件发生变化,则文件的hash码也会跟着变化。
3、检查html文件中的js文件,如果文件的hash不变,则不替换,如果不同则替换。

实现方案

创建自动化构建的项目

1、新建项目名称buildpro
2、在buildpro文件夹下,创建node_modules文件及项目文件。

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
D:\home\lehoon\develop\buildpro>npm instll module_name
npm WARN saveError ENOENT: no such file or directory, open 'D:\home\lehoon\develop\buildpro\package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.

npm WARN enoent ENOENT: no such file or directory, open 'D:\home\lehoon\develop\buildpro\package.json'
npm WARN buildpro No description
npm WARN buildpro No repository field.
npm WARN buildpro No README data
npm WARN buildpro No license field.

+ module_name@1.0.0
added 43 packages in 5.119s

D:\home\lehoon\develop\buildpro>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (buildpro)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\home\lehoon\develop\buildpro\package.json:

{
"name": "buildpro",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"module_name": "^1.0.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}


Is this ok? (yes) yes

安装gulp、配置gulp

1、安装gulp及插件

1
2
3
4
npm install --save-dev gulp@3.9.1
npm install --save-dev gulp-rev@7.1.2
npm install --save-dev gulp-rev-collector@1.1.1
npm install --save-dev run-sequence@1.2.2

2、配置规则
修改node_modules\gulp_rev\index.js文件

1
2
把 manifest[originalFile] = revisionedFile 修改成
manifest[originalFile] =originalFile + '?v=' +file.revHash;

修改node_modules\gulp_rev_collector\index.js文件

1
2
3
4
5
if ( !_.isString(json[key]) ||path.basename(json[key]).replace(newRegExp( opts.revSuffix ),'' ) !== path.basename(key) ) {  
修改成
if (!_.isString(json[key]) ||path.basename(json[key]).split('?')[0] !== path.basename(key)) {

通过修改regexp: newRegExp('([\/\\\\\'"])' +pattern, 'g'), 修改成 regexp: new RegExp( '([\/\\\\\'"])' + pattern + '(\\?v=\\w{10})?', 'g' ),

编写gulp任务文件

1、gulp默认找gulpfile.js执行,所以gulp的任务规则都放在项目根目录下的gulpfile.js中
2、gulp的规则文件如下:

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
var gulp = require('gulp');
var runSequence = require('run-sequence');
var rev = require('gulp-rev');
var revCollector = require('gulp-rev-collector');

//要处理的项目工程目录
var programPath = 'D:/workspace/lshop';
var cssSrc=programPath + '/css/**/*.css';
var jsSrc=programPath + '/js/**/*.js';

//css文件生成hash编码,并保存到文件
gulp.task('revCss', function() {
console.log('=========' + cssSrc);
return gulp.src(cssSrc)
.pipe(rev())
.pipe(rev.manifest())
.pipe(gulp.dest('rev/css'));
});

//计算js文件的hash码并保存到文件
gulp.task('revJs', function() {
console.log('=========' + jsSrc);
return gulp.src(jsSrc)
.pipe(rev())
.pipe(rev.manifest())
.pipe(gulp.dest('rev/js'));
});

//替换html中的js版本号
gulp.task('revHtml', function() {
return gulp.src(['rev/**/*.json', programPath+'/*html'])
.pipe(revCollector())
.pipe(gulp.dest(programPath));
});


gulp.task('dev', function(done) {
condition = false;
runSequence(['revCss'],['revJs'], ['revHtml'], done);
});


gulp.task('default', ['dev']);

3、然后切换到控制台下运行gulp命令即可。

文章目录
  1. 1. 问题描述
  2. 2. 原理
  3. 3. 实现方案
    1. 3.1. 创建自动化构建的项目
    2. 3.2. 安装gulp、配置gulp
    3. 3.3. 编写gulp任务文件