前端静态资源版本更新与缓存之——通过gulp 在原html文件上自动化添加js、css版本号
原理
修改js和css文件
通过对js,css文件内容进行hash运算,生成一个文件的唯一hash字符串(如果文件修改则hash号会发生变化)
替换html中的js,css文件名,生成一个带版本号的文件名
方案
现在网上的方案都是生成一个新的dist目录,里面包含了要发布的html,js,css等文件。但是在实际的公司的项目中,会有情况不能生成新的HTML进行发布,需要在原来的HTML文件上进行js ,css版本的替换. 这里分享下我在实际项目中通过改动插件然后在原目录结构下进行版本的控制方案。
原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>
1:安装gulp和gulp插件 执行:
npm install --save-dev gulp
npm install --save-dev gulp-rev
npm install --save-dev gulp-rev-collector
npm install --save-dev run-sequence
2:编写gulpfile.js
//引入gulp和gulp插件
var gulp = require('gulp'),
runSequence = require('run-sequence'),
rev = require('gulp-rev'),
revCollector = require('gulp-rev-collector');
//定义css、js源文件路径
var cssSrc = 'css/*.css',
jsSrc = 'js/*.js';
//CSS生成文件hash编码并生成 rev-manifest.json文件名对照映射
gulp.task('revCss', function(){
return gulp.src(cssSrc)
.pipe(rev())
.pipe(rev.manifest())
.pipe(gulp.dest('rev/css'));
});
//js生成文件hash编码并生成 rev-manifest.json文件名对照映射
gulp.task('revJs', function(){
return gulp.src(jsSrc)
.pipe(rev())
.pipe(rev.manifest())
.pipe(gulp.dest('rev/js'));
});
//Html替换css、js文件版本
gulp.task('revHtml', function () {
return gulp.src(['rev/**/*.json', 'View/*.html'])
.pipe(revCollector())
.pipe(gulp.dest('View'));
});
//开发构建
gulp.task('dev', function (done) {
condition = false;
runSequence(
['revCss'],
['revJs'],
['revHtml'],
done);
});
gulp.task('default', ['dev']);
执行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) ) {
再执行gulp命令,得到的结果如下(效果正确):
<link rel="stylesheet" href="../css/default.css?v=803a7fe4ae">
<script src="../js/app.js?v=3a0d844594"></script>
但是假如我们更改了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>
前端静态资源版本更新与缓存之——通过gulp 在原html文件上自动化添加js、css版本号的更多相关文章
- 前端静态资源版本更新与缓存之——gulp自动化添加版本号
公司项目每次发布后,偶尔会有缓存问题,然后看了下gulp,发现gulp还能给js,css自动化添加版本号,可解决缓存的问题,所以自动化实现静态资源的版本更新才是正道.通过网上的资料试过了两种办法: 1 ...
- 前端工程精粹(一):静态资源版本更新与缓存(附精简js的工具)
转自:http://www.infoq.com/cn/articles/front-end-engineering-and-performance-optimization-part1/ 每个参与过开 ...
- Nginx针对前端静态资源的缓存处理
当用户上报一个线上的bug后,开发者修改前端代码的bug上新后,用户反映问题依旧存在的问题...这种情况是不是曾经遇到过,这个问题跟浏览器的缓存机制有很大关系(强制缓存和协商缓存,这里我就不介绍具体的 ...
- 开发掉坑(二)前端静态资源 Uncaught SyntaxError: Unexpected token <
某天,有同学反馈后台管理系统出现静态资源无法加载的问题. 复现如下: 进入首页. 点击侧边栏某个子功能,静态资源可正常访问到. 等待10分钟左右,点击侧边栏其他子功能,无法访问到静态资源. 查看控制台 ...
- 静态资源打包:一个javescript 的src引用多个文件,一个link引用多个CSS文件
疑惑描述: 查看了淘宝网的首页源文件,看到这样的一个特殊的 <script src="http://a.tbcdn.cn/??s/kissy/1.1.6/kissy-min.js,p/ ...
- springmvc如何访问静态文件,例如jpg,js,css
你怎么DispatcherServlet拦截"*.do"这有一个后缀URL.就不存在訪问不到静态资源的问题. 假设你的DispatcherServlet拦截"/&qu ...
- springmvc如何访问到静态的文件,如jpg,js,css
如何你的DispatcherServlet拦截"*.do"这样的有后缀的URL,就不存在访问不到静态资源的问题. 如果你的DispatcherServlet拦截"/&qu ...
- 前端笔记之微信小程序(三)GET请求案例&文件上传和相册API&配置https
一.信息流小程序-GET请求案例 1.1服务端接口开发 一定要养成接口的意识,前端单打独斗出不来任何效果,必须有接口配合,写一个带有分页.关键词查询的接口: 分页接口:http://127.0.0.1 ...
- 如何访问到静态的文件,如jpg,js,css.
如果你的DispatcherServlet拦截"*.do"这样的有后缀的URL,就不存在访问不到静态资源的问题. 如果你的DispatcherServlet拦截"/&qu ...
随机推荐
- PHP 对目录下所有TXT进行遍历 并正则进行处理 preg_replace
<?php set_time_limit(); //遍历 指定目录下的所有 文件/ $pattern是要匹配的 文件规则 function file_list($dir,$pattern=&qu ...
- Maven仓库汇总
来源:http://tianya23.blog.51cto.com/1081650/386908 1.maven 仓库地址: 共有的仓库http://repo1.maven.org/maven2/ht ...
- 11 java 线程池 使用实例
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...
- Perl入门
Perl 是一门开源的脚本语言,由 Larry Wall 所创造,该语言以实用,快速开发为主要目标,与当前流行的面向对象结构化编程有些格格不入,但这并不妨碍 Perl 被广泛流传和使用,世界范围内围绕 ...
- Esper简介
1. CEP(Complex Event Processing, 复杂事件处理) 事件(Event)一般情况下指的是一个系统中正在发生的事,事件可能发生在系统的各个层面上,它可以是某个动作,例如客户下 ...
- mysql备份 小结 (三种方式的详细解读)
备份的本质就是将数据集另存一个副本,但是原数据会不停的发生变化,所以利用备份只能回复到数据变化之前的数据.那变化之后的呢?所以制定一个好的备份策略很重要 新建一个all.sqlvim all.sql在 ...
- ExtJs定时消息提示框,类似于QQ右下角提示,ExtJs如何定时向后台发出两个请求并刷新数据实例
原文出自:https://blog.csdn.net/seesun2012 思路: 1.加载页面,加载Ext.TaskManager.start()方法: 2.执行定时器方法: 3.获取地址向后台发送 ...
- facebook 登录开发记录
1.注册一个 facebook 的账号 2.进入 facebook 开发者的网站.(也可以在 facebook 登录后,点击自己的名字进入用户信息页面,在该页面的底部有个“更多”的链接,点击进去会看到 ...
- 注册表修改 Devenv 默认启动 Visual Studio 版本
本人机器上安装了多个版本Visual Studio.目前开发主要使用VS2015,,但每次使用运行->devenv 启动的都是 VS2013.所以不是很方便. 如果VS2013扩展包出问题要使用 ...
- git常用小操作。-- 自用
编辑 .gitignore bin-debug/ 忽略所有的叫bin-debug文件夹和他下面的文件 编辑 .git/config [core] repositoryformatversion = ...