前端自动化工具gulp自动添加版本号的教程

之前,我介绍了学习安装并配置前端自动化工具Gulp,觉得gulp确实比grunt的配置简单很多,于是我决定再深入学习一下gulp,就去网上查了资料,发现gulp还可以自动添加版本号,这个功能就为我平时在更新css或js时老是在客户端存在缓存导致更新后的效果无法实时展现的苦恼。所以就赶紧去试了一下,果真可以,很高兴啊,真是为项目开发,为效果的快速展现提供了很多的便利。

实现原理:

1、修改js和css文件;

2、通过对js,css文件内容进行hash运算,生成一个文件的唯一hash字符串(如果文件修改则hash号会发生变化);

3、替换html中的js,css文件名,生成一个带版本号的文件名。

现在网上的方案都是生成一个新的dist目录,里面包含了要发布的html、js、css等文件。但是在实际的公司的项目中,会有情况不能生成新的HTML进行发布,需要在原来的HTML文件上进行js 、css版本的替换. 这里分享下我在实际项目中通过改动插件然后在原目录结构下进行版本的控制方案。(在这里,我有点不太明白原作者的意思,因为你既然修改了js或css,那么html中引入这些文件的版本号必然会发生变化,也就是html也跟着变化了,如果你不对新的html进行发布,那线上的html中的版本号还是老的版本号,就没有起到更新缓存的作用,那我们辛辛苦苦的配置gulp来添加这个版本号干嘛?)

原html文件代码

<link rel="stylesheet"href="../css/default.css">

<script src="../js/app.js"></script>

预期效果:在原目录结构下html文件代码

<link rel="stylesheet"href="../css/default.css?v=5a636d79c4">

<script src="../js/app.js?v=3a0d844594"></script>

background:url("../images/none.png?v=8f204d4")

实现方法:

1、安装gulp和gulp插件

npminstall--save-dev gulp

npminstall--save-dev gulp-rev

npminstall--save-dev gulp-rev-collector

npminstall--save-dev gulp-asset-rev

npminstall--save-dev run-sequence

2、编写gulpfile.js

//引入gulp和gulp插件

vargulp = require('gulp'),

  assetRev = require('gulp-asset-rev'),

  runSequence = require('run-sequence'),

  rev = require('gulp-rev'),

  revCollector = require('gulp-rev-collector');

 

//定义css、js源文件路径

varcssSrc ='css/*.css',

  jsSrc ='js/*.js';

 

//为css中引入的图片/字体等添加hash编码

gulp.task('assetRev',function(){

  returngulp.src(cssSrc) //该任务针对的文件

   .pipe(assetRev())//该任务调用的模块

   .pipe(gulp.dest('src/css'));//编译后的路径

});

 

//CSS生成文件hash编码并生成 rev-manifest.json文件名对照映射

gulp.task('revCss',function(){

  returngulp.src(cssSrc)

    .pipe(rev())

    .pipe(rev.manifest())

    .pipe(gulp.dest('rev/css'));

});

 

 

//js生成文件hash编码并生成 rev-manifest.json文件名对照映射

gulp.task('revJs',function(){

  returngulp.src(jsSrc)

    .pipe(rev())

    .pipe(rev.manifest())

    .pipe(gulp.dest('rev/js'));

});

 

 

//Html替换css、js文件版本

gulp.task('revHtml',function() {

  returngulp.src(['rev/**/*.json','View/*.html'])

    .pipe(revCollector())

    .pipe(gulp.dest('View'));

});

 

 

//开发构建

gulp.task('default',function(done) {

  condition =false;

  runSequence(   //需要说明的是,用gulp.run也可以实现以上所有任务的执行,只是gulp.run是最大限度的并行执行这些任务,而在添加版本号时需要串行执行(顺序执行)这些任务,故使用了runSequence.

    ['assetRev'],

    ['revCss'],

    ['revJs'],

    ['revHtml'],

    done);

});

执行gulp命令后的效果

//rev目录下生成了manifest.json对应文件

{

 "default.css":"default-803a7fe4ae.css"

}

 

 

<link rel="stylesheet"href="../css/default-803a7fe4ae.css">

<script src="../js/app-3a0d844594.js"></script>

很显然这不是我们需要的效果

3、更改gulp-rev和gulp-rev-collector

打开node_modules\gulp-rev\index.js

第144行 manifest[originalFile] = revisionedFile;

更新为: manifest[originalFile] = originalFile + '?v=' + file.revHash;

打开nodemodules\gulp-rev\nodemodules\rev-path\index.js

10行 return filename + '-' + hash + ext;

更新为: return filename + ext;

打开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) ) {

打开node_modules\gulp-assets-rev\index.js

78行 var verStr = (options.verConnecter || "-") + md5;

更新为:var verStr = (options.verConnecter || "") + md5;

80行 src = src.replace(verStr, '').replace(/(\.[^\.]+)$/, verStr + "$1");

更新为:src=src+"?v="+verStr;

再执行gulp命令,得到的结果如下(效果正确):

<link rel="stylesheet"href="../css/default.css?v=803a7fe4ae">

<script src="../js/app.js?v=3a0d844594"></script>

background:url("../images/none.png?v=8f204d4")

但是假如我们更改了css和js后,再执行gulp命令,得到的结果会如下:

<link rel="stylesheet"href="../css/default.css?v=33379df310?v=803a7fe4ae">

<script src="../js/app.js?v=3a0d844594?v=3a0d844594"></script>

有没有发现,会在版本号后面再添加一个版本号,因为gulp只替换了原来文件名,这样又不符合预期效果了,所以我们想到,还需要修改插件的替换正则表达式。

4、继续更改gulp-rev-collector

打开node_modules\gulp-rev-collector\index.js

第107行 regexp: new RegExp( '([\/\\\\\'"])' + pattern, 'g' ),

更新为: regexp: new RegExp( '([\/\\\\\'"])' + pattern+'(\\?v=\\w{10})?', 'g' ),

现在你不管执行多少遍gulp命令,得到的html效果都是

<link rel="stylesheet"href="../css/default.css?v=5a636d79c4">

<script src="../js/app.js?v=3a0d844594"></script>

以下是本人自己写的一个既可以编译less,又可以压缩、重命名css和js,同时可以压缩html并自动添加版本号的gulp.js配置文件,当然也是参考了原作者的方法:

//引入gulp和gulp插件

vargulp = require('gulp'),

  less = require('gulp-less'),

  assetRev = require('gulp-asset-rev'),

  minifyCss = require('gulp-minify-css'),

  uglify = require('gulp-uglify'),

  htmlmin = require('gulp-htmlmin'),

  rename = require('gulp-rename'),

  imagemin = require('gulp-imagemin'),

  runSequence = require('run-sequence'),

  rev = require('gulp-rev'),

  revCollector = require('gulp-rev-collector');

 

//定义css、js源文件路径

varcssSrc ='css/*.css',

  cssMinSrc ='dist/css/*.css',

  jsSrc ='js/*.js',

  jsMinSrc ='dist/js/*.js',

  lessSrc ='less/*.less',

  imgMinSrc ='dist/images/*.{png,jpg,gif,ico}',

  htmlSrc ='*.html';

 

//编译less 定义一个less任务(自定义任务名称)

gulp.task('less',function(){

  returngulp.src(lessSrc) //该任务针对的文件

   .pipe(less())//该任务调用的模块

   .pipe(gulp.dest('css'));//编译后的路径

});

 

//为css中引入的图片/字体等添加hash编码

gulp.task('assetRev',function(){

  returngulp.src(cssSrc) //该任务针对的文件

   .pipe(assetRev())//该任务调用的模块

   .pipe(gulp.dest('src'));//编译后的路径

});

 

//压缩css

gulp.task('cssMin',function() {

  returngulp.src(cssSrc)  //压缩的文件

    .pipe(rename({suffix:'.min'})) 

    .pipe(minifyCss())//执行压缩

    .pipe(gulp.dest('dist/css')); //输出文件夹

});

 

//CSS生成文件hash编码并生成 rev-manifest.json文件名对照映射

gulp.task('revCss',function(){

  returngulp.src(cssMinSrc)

    .pipe(rev())//文件名加MD5后缀

    .pipe(rev.manifest()) //必须有这个方法 生成一个rev-manifest.json

    .pipe(gulp.dest('dist/css')); //将rev-manifest.json 保存到 dist/css 目录内

});

 

//压缩js

gulp.task('uglify',function(){

  returngulp.src(jsSrc)

   .pipe(rename({suffix:'.min'}))

   .pipe(uglify())

   .pipe(gulp.dest('dist/js'));

});

 

//js生成文件hash编码并生成 rev-manifest.json文件名对照映射

gulp.task('revJs',function(){

  returngulp.src(jsMinSrc)

    .pipe(rev())

    .pipe(rev.manifest())

    .pipe(gulp.dest('dist/js'));

});

 

//压缩html

gulp.task('htmlMin',function(){

  varoptions = {

    collapseWhitespace:true, //从字面意思应该可以看出来,清除空格,压缩html,这一条比较重要,作用比较大,引起的改变压缩量也特别大。

    collapseBooleanAttributes:true, //省略布尔属性的值,比如:<input checked="checked"/>,那么设置这个属性后,就会变成 <input checked/>。

    removeComments:true, //清除html中注释的部分,我们应该减少html页面中的注释。

    removeEmptyAttributes:true, //清除所有的空属性。

    removeScriptTypeAttributes:true, //清除所有script标签中的type="text/javascript"属性。

    removeStyleLinkTypeAttributes:true, //清楚所有Link标签上的type属性。

    minifyJS:true, //压缩html中的javascript代码。

    minifyCSS:true //压缩html中的css代码。

  };

  returngulp.src(htmlSrc)

   .pipe(htmlmin(options))

   .pipe(gulp.dest('dist/html'));

});

 

//Html替换css、js文件版本

gulp.task('revHtml',function() {

  returngulp.src(['dist/**/*.json','dist/html/*.html'])

    .pipe(revCollector())

    .pipe(gulp.dest('dist/html'));

});

 

//压缩image

gulp.task('imageMin',function() {

  gulp.src('images/*.{png,jpg,gif,ico}')

    .pipe(imagemin())

    .pipe(gulp.dest('dist/images'));

});

 

gulp.task('revImage',function(){

  returngulp.src(imgMinSrc)

    .pipe(rev())

    .pipe(rev.manifest()) //必须有这个方法

    .pipe(gulp.dest('dist/images'));

});

 

gulp.task('default',function(done) {

  //condition = false;

  runSequence( //此处不能用gulp.run这个最大限度并行(异步)执行的方法,要用到runSequence这个串行方法(顺序执行)才可以在运行gulp后顺序执行这些任务并在html中加入版本号

    'less',

    'assetRev',

    'cssMin',

    'revCss',

    'uglify',

    'revJs',

    'imageMin',

    'revImage',

    'htmlMin',

    'revHtml',   

    done);

});

目前,不知为何必须要运行两次gulp才可以给html中引入的图片添加版本号,所以还在摸索中,也请大神给指点指点,谢谢!

原文链接:http://www.cnblogs.com/tnnyang/p/6023475.html

时间: 2024-10-26 05:33:50

前端自动化工具gulp自动添加版本号的教程的相关文章

详解前端自动化工具gulp自动添加版本号_javascript技巧

之前,我介绍了学习安装并配置前端自动化工具Gulp,觉得gulp确实比grunt的配置简单很多,于是我决定再深入学习一下gulp,就去网上查了资料,发现gulp还可以自动添加版本号,这个功能就为我平时在更新css或js时老是在客户端存在缓存导致更新后的效果无法实时展现的苦恼.所以就赶紧去试了一下,果真可以,很高兴啊,真是为项目开发,为效果的快速展现提供了很多的便利. 实现原理: 1.修改js和css文件: 2.通过对js,css文件内容进行hash运算,生成一个文件的唯一hash字符串(如果文件

前端构建工具gulp使用

前端自动化流程工具,用来合并文件,压缩等. Gulp官网 http://gulpjs.com/ Gulp中文网 http://www.gulpjs.com.cn/ Gulp中文文档 https://github.com/lisposter/gulp-docs-zh-cn Gulp插件网 http://gulpjs.com/plugins/ Awesome Gulp https://github.com/alferov/awesome-gulp StuQ-Gulp实战和原理解析 http://i5

Gulp构建前端自动化工作流

## Gulp构建前端自动化工作流 ### Gulp构建前端自动化工作流之:常用插件介绍及使用 在对Gulp有了一个初步的了解之后,我们开始构建一个较为完整的Gulp开发环境. 本文主要分为6个段落: * 1\. 构建项目目录结构(Directory Structure Build)* 2\. 插件介绍及使用方法(Tasks and dependencies)* 3\. 扩展优化(Extend & Optimize Task)* 4\. 其他插件介绍(Other plug-ins)* 5\. 匹

Web前端构建工具版本号管理方案思考

Web前端构 建工具版本号管理方案思考 时间:2014-08-21 23:55 来源:财付通设计中心 作者:小网 前端构建工具满天飞的情景下,笔者也忍不住去捣鼓了一下,真正体验一下NODEJS带来的魅力,经过一段时间规划设计,终于将平台工具捣鼓出来了.在 里面也体验了express, socket.io, grunt等node插件服务,使用很流畅,并且很好的完了我的基本需求(JS\CSS\IMAGE的压缩和自动部署功能). 虽然基本功能完成, 但是还有一个让人容易 忽略而又重要的问题来了,就是资

Web前端自动化入门总结

周末失眠,周一无力写代码,只能听着一首:逆流成河,顺便把最近刚入门的前端自动化写一下入门总结. 因为从事的开发重点是java后端,后端这几年随着maven,gradle等构建工具的使用也把以前jar管理解放了,记得刚毕业那会公司的方案是公司自己维护一个libs文件夹,把需要的jar放进去,然后ant写脚本打包.这种方式的缺点要自己记住jar的版本等等,然后更新比较繁琐,还有把jar提交到svn等版本管理工具,大小很大,共享麻烦. 说到前端自动化,现在应该是比较普及了,到github上面搜索一下w

基于Node.js的JavaScript项目构建工具gulp的使用教程_javascript技巧

npm install gulp --save-dev 什么是gulp?gulp是新一代的前端项目构建工具,你可以使用gulp及其插件对你的项目代码(less,sass)进行编译,还可以压缩你的js和css代码,甚至压缩你的图片,gulp仅有少量的API,所以非常容易学习. gulp 使用 stream 方式处理内容.Node催生了一批自动化工具,像Bower,Yeoman,Grunt等. gulp和grunt的异同点易于使用:采用代码优于配置策略,Gulp让简单的事情继续简单,复杂的任务变得可

Ansible :一个配置管理和IT自动化工具

Ansible :一个配置管理和IT自动化工具 今天我来谈谈 ansible,一个由 Python 编写的强大的配置管理解决方案.尽管市面上已经有很多可供选择的配置管理解决方案,但他们各有优劣,而 ansible 的特点就在于它的简洁.让 ansible 在主流的配置管理系统中与众不同的一点便是,它并不需要你在想要配置的每个节点上安装自己的组件.同时提供的一个优点在于,如果需要的话,你可以在不止一个地方控制你的整个基础架构.最后一点是它的正确性,或许这里有些争议,但是我认为在大多数时候这仍然可以

Grunt安装配置教程:前端自动化工作流

文章简介:Grunt 打造前端自动化工作流. Grunt这货是啥? 最近很火的前端自动化小工具,基于任务的命令行构建工具 http://gruntjs.com Grunt能帮我们干啥? 在开始介绍前,先向大家描述下面的场景: [场景1:项目开始前] 先建立一个 projA 的文件夹 再建 html css js images (建5个或以上文件夹,花费1分钟) 拷贝 CSS库(Yui Reset bootstrap)JS库(Requiet.js Seajs jQuery jQuery插件 ) 进

自动化工具后起之秀Ansible的部署实践

本文讲的是自动化工具后起之秀Ansible的部署实践,从早期手动加脚本的部署方式,到后来自动化工具(chef, puppet, saltstack, ansible等)的出现,再到如今DevOps的盛行,企业应用部署正式进入平台部署阶段,CD(持续部署)已经成为企业对应用部署的标准需求,运维的交付也不再是以周或天为单位,而是以分钟为单位. 本文主要介绍自动化工具Ansible,及其在普元DevOps平台中的应用部署和日常应用部署中的实践. 本文目录: 一.如何选择合适的自动化工具? 二.Ansi