DEV Community

Piotr Sobuś
Piotr Sobuś

Posted on

3 2

Angular & Gulp: custom assets hashing mechanism

In this post you will learn how to create a flexible, fully customizable and easily maintainable cache busting mechanism using gulp.js for Angular applications. We'll compose a 2 step pipeline that hashes all files in the assets directory after application build is performed.

First, let's install all the required libraries.

npm install -D gulp gulp-rev gulp-rev-replace gulp-rev-delete-original

Alright, let's create our pipeline. Create a new file in the root directory and name it gulpfile.js. Good, now import all the dependencies inside the file.

const gulp = require("gulp");
const rev = require("gulp-rev");
const revreplace = require("gulp-rev-replace");
const revdel = require("gulp-rev-delete-original");

const { name } = require("./package.json");
const assets = `dist/${name}/assets`;
Enter fullscreen mode Exit fullscreen mode

Let's create a first task that will traverse the assets folder and append unique hashes to the file names.

gulp.task("hash:revision-media", () =>
  gulp
    .src(`${assets}/**/*.*`)
    .pipe(rev())
    .pipe(revdel())
    .pipe(gulp.dest(assets))
    .pipe(rev.manifest())
    .pipe(gulp.dest(assets))
);
Enter fullscreen mode Exit fullscreen mode

I will briefly describe each step:

(1) locates all matching files and reads them into memory to pass through the stream

Having inserted this pattern, gulp will match any file with any extension in any directory. If you want to target a concrete extension or multiple extensions, use a glob pattern syntax {x1,x2,..,xn}, e.g: *.{jpg,jpeg,png}

(2) hashes a file, e.g: mylovelydog.png -> mylovelydong-df1cr0g.png
(3) removes old, unused fingerprinted files
(4) writes hashed assets to build directory
(5) maps the original paths to the revisioned paths and places the directory in a manifest file
(6) writes the manifest to build directory

Now, we need to find all occurrences in our bundled output files and update them by replacing the original paths with the hashed ones using our manifest that holds all the mappings.

gulp.task("hash:replace-hashed-media-imports", () => {
  const manifest = gulp.src(`${assets}/rev-manifest.json`);

  return gulp
    .src(`dist/${name}/*.{html,css,js}`)
    .pipe(revreplace({ manifest }))
    .pipe(gulp.dest(`dist/${name}/`));
});
Enter fullscreen mode Exit fullscreen mode

Almost there! Now, we will combine these two tasks into a single task.

gulp.task(
  "optimize",
  gulp.series("hash:revision-media", "hash:replace-hashed-media-imports")
);
Enter fullscreen mode Exit fullscreen mode

Finally, let's set up our package.json in the way that our pipeline will run after build is complete.

"scripts": {
    ...
    "postbuild": "gulp optimize",
},
Enter fullscreen mode Exit fullscreen mode

Done. I hope this post will help you building your own pipeline. If you have any questions, feel free to ask them in the comments!

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (1)

Collapse
 
siriusv21 profile image
SiriusV21

Not working, the manifest file is containing paths without dist/${name}/ in prefix and maybe thats why its is not changing the refernces in the output build

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay