gulp: Automatically add version number to request

2019-01-18 04:26发布

问题:

I deploy my project by building source files with gulp right on the server. To prevent caching issues, the best practice could be adding a unique number to request url, see: Preventing browser caching on web application upgrades;

In npm repositories, I couldn't find a tool for automatically adding version number to request. I'm asking if someone has invented such tool before.

Possible implementation could be the following:

I have a file index.html in src/ folder, with following script tag

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

During build it is copied to dist/ folder, and comment is replaced by autoincrement number

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

回答1:

You can use gulp-version-number for this. It can add version numbers to linked scripts, stylesheets, and other files in you HTML documents, by appending an argument to the URLs. For example:

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

becomes:

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

You don't even have to specify a placeholder, like you showed in your example implementation. And it's configurable.

Example usage:

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'));
});


回答2:

It looks like you may have quite a few options.

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

Hope this helps.



回答3:

You can use the gulp-rev module. This will append a version number to the files, the version is a hash of the file content, so it will only change if the file changes.

You then output a manifest file containing the mapping between the file e.g. Scripts.js to Scripts-8wrefhn.js.

Then use a helper function when returning the page content to map the correct values.

I have used the above process. However there's another module gulp-rev-all which is an forked extension of gulp-rev which does a little more, e.g. automatic updating of file references in pages.

Documentation here:

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


回答4:

I worked onto writing an regex, which in use along with [gulp-replace][1] works just fine.

Please find the code below. Following is a quick code for the image and css for views files codeigniter framework. But it should work fine for all the kinds of files given the source folder specified correctly.

You may customize the code as per your use.

You can call the tasks altogether, using gulp default or individual task at a time.

'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']);


回答5:

You can use

<script type="text/javascript" src="js/app.js?seq=<%=DateTime.Now.Ticks%>"></script>

or

<script type="text/javascript" src="js/app.js?seq=<%=DateTime.Now.ToString("yyyyMMddHHmm") %>"></script>