cache.update & cache.forget do not remove deleted files from the cache.
First off, this package has reduced our concatenated JS file build by an order of magnitude. Thank you for publishing it! I think I discovered an issue with it.
Our watch task, I added something like this (which I lifted almost verbatim from this archived blog post):
gulp.watch('src/**/*.js', scriptsFunction)
.on('change', cache.update('js'));
This, however, did not work. When I deleted a file from the filesystem, it simply did not get removed from the cache. I could still use the features on my app that were powered by the code in the file I had deleted. I did a little digging and found a few of issues:
- Chokidar (the library Gulp’s
watchmethod uses under the hood), does not fire thechangeevent when a file is deleted. Instead it fires theunlinkevent. gulp-memory-cache’supdateandforgetmethods invoke’s the cache’sremovemethod, which simply removes the entry for that file from its internalcacheobject, referencing it by the file path. However, the cache object uses an absolute path as the reference key for a given file, while theevent.pathsupplied by Chokidar is relative to the CWD. In other words, simply supplyingevent.pathdoesn’t work becausesrc/js/my-file.jsdoesn’t match/Users/username/path/to/project/src/js/my-file.js. Additionally, the callback for this event does not receive anEventobject, but rather two parameters:filePathandstats.
Armed with this information, I was able to get files to be correctly deleted from the cache using the following:
// Earlier in the file, import the `path` module:
const path = require('path');
// Then, in our `watch` call:
gulp.watch('src/**/*.js', scriptsFunction)
.on('unlink', (filePath) => {
cache.forget('js', path.resolve(filePath));
});
This reliably removes files from the cache and our concatenated JS no longer includes files that were deleted from the file system. 🎉
I propose the following updates to this library:
- Either remove or modify the
updatemethod:
- Remove the
updatemethod, since its only purpose (as far as I can tell) is to remove files when achangeevent is fired. - Modify the
updatemethod not to checkevent.type, but instead presume it is being passed as the callback to theunlinkevent and expect the parameters passed in by Chokidar for theunlinkevent (filePathandstats).
- Update the
forgetmethod to resolve the supplied path into an absolute path, since we know that files stored in the cache are keyed by their absolute paths. - Update the documentation on how to effectively remove files from the cache on watch.
I’m happy to submit a PR to tackle these if contributions are welcome.
@troch Bumping this issue.