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`;
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))
);
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}/`));
});
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")
);
Finally, let's set up our package.json
in the way that our pipeline will run after build is complete.
"scripts": {
...
"postbuild": "gulp optimize",
},
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!
Top comments (1)
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