npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gulp-rev-all2

v3.0.2

Published

Static asset revisioning by appending content hash to filenames: unicorn.css => unicorn.098f6bcd.css, also re-writes references in each file to new reved name. Better absolute path support.

Downloads

110

Readme

gulp-rev-all NPM version Run tests Dependency Status

Static asset revisioning with dependency considerations, appends content hash to each filename (eg. unicorn.css => unicorn.098f6bcd.css), re-writes references.

Purpose

By using the HTTP server response header expires combined with filename revisioning, static assets can be made cacheable for extended periods of time. Returning visitors will have the assets cached for super fast load times.

Additionally, content distribution networks like CloudFront let you cache static assets in Edge Locations for extended periods of time.

Why fork... again?

smysnk forked this from gulp-rev to add reference processing and rewriting functionality.

It is the philosophy of gulp-rev that concerns should be seperated between revisioning the files and re-writing references to those files. gulp-rev-all does not agree with this, we believe you need to analyze each revisioned files' references, to calculate a final hash for caching purposes.

I forked it from him because I wanted to add support for stripping root paths.

Probably this should be a PR on the original or something? Hm.

Consider the following example:

You have a bunch of static assets (css, js, images) in /public, and a bunch of template files in /views. You want to modify the template files so they point to the revisioned static assets, but the public folder is the root of your server, so none of the absolute paths in your template files begin with /public, they're just /img or /js or whatever.

By adding the option stripRootPrefixes: [/^\/?public/] (Array of RegExp), this fork converts an absolute path of /public/img/icon.png to /img/icon.png so it matches correctly.

Another tiny change: if you set includeFilesInManifest: '*', then it'll include all files in the manifest regardless of extension.

Install

Add this line to your package.json, probably under devDependencies, then run npm install:

"gulp-rev-all2": "gulp-rev-all2"

Or yarn:

yarn add --dev gulp-rev-all

Usage

var gulp = require("gulp");
var RevAll = require("gulp-rev-all2");

gulp.task("default", function () {
  gulp.src("dist/**").pipe(RevAll.revision()).pipe(gulp.dest("cdn"));
});
var gulp = require("gulp");
var RevAll = require("gulp-rev-all2");
var awspublish = require("gulp-awspublish");
var cloudfront = require("gulp-cloudfront");

var aws = {
  params: {
    Bucket: "bucket-name",
  },
  accessKeyId: "AKIAI3Z7CUAFHG53DMJA",
  secretAccessKey: "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",
  distributionId: "E1SYAKGEMSK3OD",
  region: "us-standard",
};

var publisher = awspublish.create(aws);
var headers = { "Cache-Control": "max-age=315360000, no-transform, public" };

gulp.task("default", function () {
  gulp
    .src("dist/**")
    .pipe(RevAll.revision())
    .pipe(awspublish.gzip())
    .pipe(publisher.publish(headers))
    .pipe(publisher.cache())
    .pipe(awspublish.reporter())
    .pipe(cloudfront(aws));
});

Methods

.revision({ options })

Returns a transform function that can be used to pipe files through so that they may be revisioned, also corrects refererences to said files.

.manifestFile()

Returns a transform function that will filter out any existing files going through the pipe and will emit a new manifest file. Must be called after .revision().

var gulp = require("gulp");
var RevAll = require("gulp-rev-all2");

gulp.task("default", function () {
  return gulp
    .src(["assets/**"])
    .pipe(gulp.dest("build/assets"))
    .pipe(RevAll.revision())
    .pipe(gulp.dest("build/assets"))
    .pipe(RevAll.manifestFile())
    .pipe(gulp.dest("build/assets"));
});

An asset manifest, mapping the original paths to the revisioned paths, will be written to build/assets/rev-manifest.json:

{
  "css/unicorn.css": "css/unicorn.098f6bcd.css",
  "js/unicorn.js": "js/unicorn.273c2cin.js"
}

.versionFile()

Returns a transform function that will filter out any existing files going through the pipe and will emit a new version file. Must be called after .revision().

var gulp = require("gulp");
var RevAll = require("gulp-rev-all2");

gulp.task("default", function () {
  return gulp
    .src(["assets/**"])
    .pipe(gulp.dest("build/assets"))
    .pipe(RevAll.revision())
    .pipe(gulp.dest("build/assets"))
    .pipe(RevAll.versionFile())
    .pipe(gulp.dest("build/assets"));
});

The version file will contain the build date and a combined hash of all the revisioned files, will be written to build/assets/rev-version.json.

{
  "hash": "c969a1154f2a5c0689d8ec4b0eafd584",
  "timestamp": "2014-10-11T12:13:48.466Z"
}

Options

gulp.src("dist/**").pipe(RevAll.revision({ options }));

fileNameVersion

Type: String Default: rev-version.json Set the filename of the file created by revAll.versionFile()

fileNameManifest

Set the filename of the file created by revAll.manifestFile() Type: String Default: rev-manifest.json

includeFilesInManifest

Add only specific file types to the manifest file Type: Array of strings Default: ['.css', '.js']

If you set it to just the string '*' it will include all files.

dontGlobal

Don't rename, search or update refrences in files matching these rules Type: Array of (Regex and/or String) Default: [ /^\/favicon.ico$/ ]

dontRenameFile

Don't rename files matching these rules Type: Array of (Regex and/or String) Default: []

dontUpdateReference

Don't update references matching these rules Type: Array of (Regex and/or String) Default: []

dontSearchFile

Don't search for references in files matching these rules Type: Array of (Regex and/or String) Default: []

In some cases, you may not want to rev your *.html files:

gulp.task("default", function () {
  gulp
    .src("dist/**")
    .pipe(RevAll.revision({ dontRenameFile: [/^\/favicon.ico$/g, ".html"] }))
    .pipe(gulp.dest("cdn"));
});

Every html file except the root /index.html file:

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

  gulp
    .src('dist/**')
    .pipe(RevAll.revision({ dontRenameFile: [/^\/favicon.ico$/g, /^\/index.html/g] })))
    .pipe(gulp.dest('cdn'))

});

hashLength

Change the length of the hash appended to the end of each revisioned file (use transformFilename for more complicated scenarios). Type: hashLength Default: 8

gulp.task("default", function () {
  gulp
    .src("dist/**")
    .pipe(RevAll.revision({ hashLength: 4 }))
    .pipe(gulp.dest("cdn"));
});

prefix

Prefixes absolute references with a string (use transformPath for more complicated scenarios). Useful for adding a full url path to files. Type: prefix Default: none

gulp.task("default", function () {
  gulp
    .src("dist/**")
    .pipe(RevAll.revision({ prefix: "http://1234.cloudfront.net/" }))
    .pipe(gulp.dest("cdn"));
});

transformPath

Specify a function to transform the reference path. Useful in instances where the local file structure does not reflect what the remote file structure will be. Type: function (rev, source, path) Default: none

The function takes three arguments:

  • rev - revisioned reference path
  • source - original reference path
  • path - path to the file
gulp.task("default", function () {
  gulp
    .src("dist/**")
    .pipe(
      RevAll.revision({
        transformPath: function (rev, source, path) {
          // on the remote server, image files are served from `/images`
          return rev.replace("/img", "/images");
        },
      })
    )
    .pipe(gulp.dest("cdn"));
});

transformFilename

If the default naming convention does not suite your needs, you can specify a custom filename transform. Type: function (file, hash) Default: none

The function takes one argument:

  • file - file to be revisioned
  • hash - calculated hash of the file
gulp.task("default", function () {
  gulp
    .src("dist/**")
    .pipe(
      RevAll.revision({
        transformFilename: function (file, hash) {
          var ext = path.extname(file.path);
          return hash.substr(0, 5) + "." + path.basename(file.path, ext) + ext; // 3410c.filename.ext
        },
      })
    )
    .pipe(gulp.dest("cdn"));
});

debug

If you set this options to true, verbose logging will be emitted to console. Type: Boolean Default: false

Annotater & Replacer

In some cases, false-positives may occur. Strings that are similar to a file reference may be incorrectly replaced.

In the example below, the 2nd instance of 'xyz' is not reference to the file xyz.js:

require('xyz');

angular.controller('myController', ['xyz', function(xyz) {
   ...
}]);

It will still however be replaced resulting in file corruption:

require('xyz.123');

angular.controller('myController', ['xyz.123', function(xyz) {
   ...
}]);

This behaviour can be avoided by passing custom annotator and replacer functions in as options.

Annotator

The annotator function is called with the original file content and path. Annotator function should return a list of objects that contain fragments of the file content in order. You may split the file up into as many fragments as necessary and attach any other metadata to the fragments. The file will be reassembled in order.

The default annotator returns one fragment with no annotations:

options.annotator = function (contents, path) {
  var fragments = [{ contents: contents }];
  return fragments;
};

Replacer

The replacer function's job is to replace references to revisioned files. The paremeters are as follows:

fragment: a file fragment as created in the annotator function. replaceRegExp: parameter is a regular expression that can be used to match the part of the fragement to be replaced. The regular expression has 4 capture groups. $1 & $4 are what precedes and follows the reference. $2 is the file path without the extension, and $3 is the file extension. newReference: what gulp-rev-all wants to replace the file path without the extension ($2) with. referencedFile: contains additional properties of the file reference thats being replaced. See the 'Additional Properties' section for more information.

The default replacer function is as follows:

options.replacer = function (
  fragment,
  replaceRegExp,
  newReference,
  referencedFile
) {
  fragment.contents = fragment.contents.replace(
    replaceRegExp,
    "$1" + newReference + "$3$4"
  );
};

You can overide the default annotator and replacer to change the behaviour of gulp-rev-all and deal with problematic edge cases.

Additional Properties

file.revPathOriginal

The original full path of the file, before revisioning.

file.revFilenameOriginal

The original filename less the file extension, before revisioning.

file.revFilenameExtOriginal

The original file extension, before revisioning.

file.revHashOriginal

The original hash of the asset before any calculations by gulp-rev-all.

file.revHash

The hash of the asset as calculated by gulp-rev-all, you can use this for customizing the file renaming, or for building different manifest formats.

Tips

Make sure to set the files to never expire for this to have an effect.

License

MIT © Joshua Bellamy-Henn