gulp:自动为请求添加版本号以防止浏览器缓存

Posted

技术标签:

【中文标题】gulp:自动为请求添加版本号以防止浏览器缓存【英文标题】:gulp: Automatically add version number to request for preventing browser cache 【发布时间】:2015-04-18 20:34:59 【问题描述】:

我通过在服务器上使用 gulp 构建源文件来部署我的项目。为防止缓存问题,最佳做法是在请求 url 中添加唯一编号,请参阅:Preventing browser caching on web application upgrades;

在 npm 存储库中,我找不到自动向请求添加版本号的工具。我在问是否有人以前发明过这样的工具。

可能的实现如下:

我在src/ 文件夹中有一个文件 index.html,带有以下脚本标签

 <script src="js/app.js<!-- %nocache% -->"></script>

在构建过程中它被复制到dist/文件夹,并且注释被替换为自动增量号

 <script src="js/app.js?t=1234"></script>

【问题讨论】:

你如何用版本号替换评论? @vini,Gulp 有注入任务,可以在 index.html 中搜索硬编码的&lt;!-- inject:something --&gt;,然后注入所需的字符串。这与散列 js 文件的版本相结合非常有用。 (对于每个组件,我们都包含它自己的 javascript 引用)&lt;!-- inject:js --&gt; &lt;script src="js/client/components/dashboard.js?v=~fileHash~"&gt;&lt;/script&gt; &lt;script src="js/client/components/signup.js?v=~fileHash~"&gt;&lt;/script&gt; 这允许客户端缓存尽可能多的 JS,并且只有在哈希更改(文件更新)时才强制重新加载 【参考方案1】:

我致力于编写一个正则表达式,它与 gulp-replace 一起使用效果很好。

请在下面找到代码。以下是用于视图文件 codeigniter 框架的图像和 css 的快速代码。但它应该适用于正确指定源文件夹的所有类型的文件。

您可以根据自己的用途自定义代码。

您可以完全调用任务,一次使用 gulp 默认或单个任务。

'use strict';

var gulp = require('gulp');
var replace = require('gulp-replace');

function makeid() 
  return (Math.random() + 1).toString(36).substring(7);




gulp.task('versioningCss', () => 
  return gulp.src('application/modules/**/views/*.php')
    .pipe(replace(/(.*)\.css\?(_v=.+&)*(.*)/g, '$1.css?_v='+makeid()+'&$3'))
    .pipe(replace(/(.*)\.css\"(.*)/g, '$1.css?_v='+makeid()+'"$2'))
    .pipe(replace(/(.*)\.css\'(.*)/g, '$1.css?_v='+makeid()+'\'$2'))
    .pipe(gulp.dest('application/modules'));
);

gulp.task('versioningJs', () => 
  return gulp.src('application/modules/**/views/*.php')
    .pipe(replace(/(.*)\.js\?(_v=.+&)*(.*)/g, '$1.js?_v='+makeid()+'&$3'))
    .pipe(replace(/(.*)\.js\"(.*)/g, '$1.js?_v='+makeid()+'"$2'))
    .pipe(replace(/(.*)\.js\'(.*)/g, '$1.js?_v='+makeid()+'\'$2'))
    .pipe(gulp.dest('application/modules'));
);

gulp.task('versioningImage', () => 
  return gulp.src('application/modules/**/views/*.php')
    .pipe(replace(/(.*)\.(png|jpg|jpeg|gif)\?(_v=.+&)*(.*)/g, '$1.$2?_v='+makeid()+'&$4'))
    .pipe(replace(/(.*)\.(png|jpg|jpeg|gif)\"(.*)/g, '$1.$2?_v='+makeid()+'"$3'))
    .pipe(replace(/(.*)\.(png|jpg|jpeg|gif)\'(.*)/g, '$1.$2?_v='+makeid()+'\'$3'));
);

gulp.task('default', [ 'versioningCss', 'versioningJs', 'versioningImage']);

【讨论】:

很高兴这样做,但我建议您在将代码发送到生产环境之前要小心并进行一次测试。这不包含详尽的正则表达式!【参考方案2】:

你可以使用

&lt;script type="text/javascript" src="js/app.js?seq=&lt;%=DateTime.Now.Ticks%&gt;"&gt;&lt;/script&gt;

&lt;script type="text/javascript" src="js/app.js?seq=&lt;%=DateTime.Now.ToString("yyyyMMddHHmm") %&gt;"&gt;&lt;/script&gt;

【讨论】:

不知道部署过程,并且总是每分钟使缓存失效 这是不明智的。这将使所有浏览器缓存失效,而浏览器缓存对性能非常重要。【参考方案3】:

您可以为此使用gulp-version-number。它可以通过将参数附加到 URL 来将版本号添加到 HTML 文档中的链接脚本、样式表和其他文件。例如:

<link rel="stylesheet" href="main.css">

变成:

<link rel="stylesheet" href="main.css?v=474dee2efac59e2dcac7bf6c37365ed0">

您甚至不必指定占位符,就像您在示例实现中展示的那样。而且是可配置的。

示例用法:

const $ = gulpLoadPlugins();
const versionConfig = 
  'value': '%MDS%',
  'append': 
    'key': 'v',
    'to': ['css', 'js'],
  ,
;

gulp.task('html', () => 
  return gulp.src('src/**/*.html')
    .pipe($.htmlmin(collapseWhitespace: true))
    .pipe($.versionNumber(versionConfig))
    .pipe(gulp.dest('docroot'));
);

【讨论】:

你是如何在有版本号的html中使用这些js和css文件的? @vini 这已经是我回答的一部分;请参阅 main.css 的示例。您只需像往常一样包含 css/js。 我在构建后立即应用此任务,它就像一个魅力。 这不适用于 php 文件,会与 php 结束标签 "?>" 混淆,例如-----> 【参考方案4】:

您可以使用gulp-rev 模块。这将在文件中附加一个版本号,版本是文件内容的哈希值,因此只有在文件更改时才会更改。

然后您输出一个清单文件,其中包含文件之间的映射,例如Scripts.jsScripts-8wrefhn.js.

然后在返回页面内容时使用辅助函数来映射正确的值。

我已经使用了上述过程。但是还有另一个模块gulp-rev-all,它是 gulp-rev 的一个分叉扩展,它可以做更多的事情,例如自动更新页面中的文件引用。

这里的文档:

gulp-rev:https://github.com/sindresorhus/gulp-rev gulp-rev-all:https://www.npmjs.com/package/gulp-rev-all

【讨论】:

【参考方案5】:

看起来您可能有很多选择。

https://www.npmjs.com/package/gulp-cachebust https://www.npmjs.com/package/gulp-buster

希望这会有所帮助。

【讨论】:

我查看了 gulp-cachebust 但似乎这实际上会在文件名中附加一个哈希,然后更改对该文件的引用以匹配新的哈希命名版本。如果任务作为服务器端构建脚本(在 git 之后)运行,这将很有效。但是,如果您将其作为预部署脚本运行以测试然后提交并上传到您的服务器,您将在您的 git 存储库中拥有脚本的每个散列版本。为什么这个 cachebust 会使用这种方法而不是 OP 建议的方法?

以上是关于gulp:自动为请求添加版本号以防止浏览器缓存的主要内容,如果未能解决你的问题,请参考以下文章

gulp 添加版本号 解决浏览器缓存问题

gulp自动化打包及静态文件自动添加版本号

使用gulp自动化打包合并前端静态资源(CSSJS文件压缩添加版本号)

gulp管理静态资源缓存

如何防止 Web 浏览器对缓存文件发出“If-Modified-Since”请求?

防止图像文件被添加到浏览器缓存