代码改变世界

Gulp解决发布线上文件(CSS和JS)缓存问题

2015-11-20 23:28  龙恩0707  阅读(5712)  评论(11编辑  收藏  举报

Gulp解决发布线上文件(CSS和JS)缓存问题

    本文的缘由:目前经常线上发布文件后要不断的刷新页面及过很长时间,页面上的CSS和JS文件才能生效,特别对于目前做微信商城的时候,微信内置的浏览器缓存非常的严重,之前我们经常是在文件后面加上时间戳的方式来解决线上发布后的缓存问题,但是在微信浏览器内并不生效;因此我们需要改变文件名的方式来解决缓存的问题,因此使用后缀名加上MD5一连串的字符串来解决缓存的问题;

我们先可以考虑这么一个功能,我在页面上引用css文件如下:

./css/xx.css  

./js/xx.js

我现在想通过使用MD5重新命名css文件,在页面上自动变为如下文件

./css/xx-34f3902a35.css

一:首先我们需要安装gulp插件;安装教程如下:

http://www.cnblogs.com/tugenhua0707/p/4069769.html 

下面我们需要来看看我整个目录结构如下:

如上目录,在src文件夹是存放所有css文件和JS文件的,gulp.html按道理是根目录下的,但是在打包之前,我是把他们放在src文件夹下,作为源文件,根目录下可以先把他删掉或者放在那边也没有关系;也就是说 把所有的html文件备份一份放在src文件夹下作为源文件;

下面是gulp.html的源代码如下:

二:安装插件

  1. 在项目根目录下 运行npm init 后 执行一些操作会在根目录下生存一个 package.json文件夹;
  2. 进入项目的根目录后,执行命令安装如下插件:

npm install –save-dev gulp gulp-concat gulp-minify-css  gulp-rev  gulp-rev-collector 

现在我的package.json 变成如下:

{
  "name": "rev",
  "version": "1.0.0",
  "description": "\"test package\"",
  "main": "index.js",
  "scripts": {
    "test": "\"a common\""
  },
  "keywords": [
    "rev"
  ],
  "author": "tugenhua",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.0",
    "gulp-concat": "^2.6.0",
    "gulp-jshint": "^2.0.0",
    "gulp-less": "^3.0.5",
    "gulp-minify-css": "^1.2.1",
    "gulp-rename": "^1.2.2",
    "gulp-rev": "^6.0.1",
    "gulp-rev-collector": "^1.0.2",
    "gulp-uglify": "^1.5.1",
    "jshint": "^2.8.0"
  }
}

如上;如果不想安装的话,可以直接在项目的根目录下新建一个package.json文件;直接把上面的package.json代码复制进行即可;最关键的是 devDependencies 依赖项,其他的可以自己根据自己的需要更改即可~ 然后进入项目的根目录下 执行命令 npm install 即可在根目录下生存 node_modules模块插件;

三:在项目的根目录下新建 Gulpfile.js文件配置

所有配置代码如下:

var gulp = require('gulp');
var concat = require('gulp-concat');                    //- 多个文件合并为一个;
var minifyCss = require('gulp-minify-css');               //- 压缩CSS为一行;
var rev = require('gulp-rev');                          //- 对文件名加MD5后缀
var revCollector = require('gulp-rev-collector');           //- 路径替换

gulp.task('concat', function() {                        //- 创建一个名为 concat 的 task   gulp.src(['./src/css/*.css'])                            
//- 需要处理的css文件,放到一个字符串数组里
//.pipe(concat('wrap.min.css'))               //- 合并后的文件名
    .pipe(minifyCss())                         //- 压缩处理成一行
    .pipe(rev())                              //- 文件名加MD5后缀
    .pipe(gulp.dest('./dist/css'))                //- 输出文件本地
    .pipe(rev.manifest())                     //- 生成一个rev-manifest.json
    .pipe(gulp.dest('./rev'));                  //- 将 rev-manifest.json 保存到 rev 目录内
});

gulp.task('rev', function() {
    gulp.src(['./rev/*.json', './src/*.html'])                    
    //- 读取 rev-manifest.json 文件以及需要进行css名替换的文件
.pipe(revCollector()) //- 执行文件内css名的替换
.pipe(gulp.dest('./')); //- 替换后的文件输出的目录 }); gulp.task('default', ['concat', 'rev']);

如上配置,配置完成后,进入根目录执行命令如下:

先执行 gulp concat 这个任务 生成一个rev-mainfest.json文件;

然后再运行rev这个任务,把html文件中的css文件替换掉,执行完后,项目的目录结构变成如下:

对比之前的结构 已经在根目录下生成rev这个文件,该文件下 有一个rev-manifest.json文件,我们可以看看该文件的代码如下:

{
  "gulp.css": "gulp-34f3902a35.css"
}

把gulp.css 文件名 需要改成该生存后有MD5的后缀名的文件;

然后再调用rev这个任务,先读取src下面的所有html的源文件,需要把gulp.css替换成我们生成后的文件,我们现在再来看看生成的根目录下的gulp.html源码变为如下:

可以看到已经替换成带有MD5后缀名的文件了;

注意:为什么一刚开始的时候,我们需要把项目根目录下的所有html文件需要备份一份到src目录下呢? 那是因为每次进行打包的时候,MD5的一连串的字符串会跟着改的,我们需要一个对比的源文件,我们需要把gulp.css 替换成 生成带有MD5一连串的css文件;不管MD5字符串如何更改,我们只需要把gulp.css后缀加上生成的MD5字符串即可~ 那如果我们不备份的话,使用你们的大脑试想下,每次打包一下,根目录下源文件会覆盖一下;并且rev文件夹下 的 rev-manifest.json 代码会变成如下:

{

  "gulp.css": "gulp-57f9aab029.css",

  "gulp-57f9aab029.css": "gulp-57f9aab02922222.css",

  "gulp-57f9aab02922222.css": "gulp-57f9aab0292222aaaaaaa.css",

  ........

}

每次打包一下,他都会找到页面上的源文件(冒号左侧代表现在的源文件,冒号右边的代表需要替换的新文件的名字);如此循环下来;如果我们备份一下的html文件的话,那么rev-manifest.json永远就是一个替换文件;如下这样的:

{

  "gulp.css": "gulp-57f9aab029.css"

}

因为它永远找到的是 源文件上的gulp.css 然后替换成生成新的带有MD5后缀名的文件名;当然如果你觉得不备份的话,在manifest.json生存多少个建值对的都没有关系的话,你也可以不备份,看个人需要;如上只是演示css文件了,当然JS文件也是一样的配置;

github上demo:https://github.com/tugenhua0707/gulp-rev-collector