#382 Cache busting, removing obsolete code for fonts#383
#382 Cache busting, removing obsolete code for fonts#383
Conversation
Signed-off-by: Anneke Sinnema <mail@annekesinnema.nl>
Signed-off-by: Anneke Sinnema <mail@annekesinnema.nl>
|
@anneke There are 2 issues here. First one is the folder structure that needs to be handled, second one is that this filter checks the modified date of the file, but because it's only a file with imports, it won't get modified when other files get modified. So it has to loop through all the files en get the latest modified date. I'll see if I can work on solving these issues. |
|
@bnijenhuis maybe the cache busting is most relevant for local development anyway, and hopefully we'll be done with most of that soon? :) |
|
@anneke It's useful for live as well, because it forces a CSS reload if anything changed in the CSS. So I think it'll still be useful... |
|
It should exist for all files that we change often and it's kinda meh that eleventy doesn't support this out of the box. In our case, the So either: // A cache to store the hashed file names
const hashCache = {};
// A cache buster if a file changes
const prefixLength ="./src/site".length
eleventyConfig.on('eleventy.beforeWatch', async (changedFiles) => {
for(const file of changedFiles) {
const relativePath = file.slice(prefixLength)
delete hashCache[file]
}
});
// A filter to dynamically hash asset file contents
eleventyConfig.addFilter("digest", async (filePath) => {
// If we've already hashed this file, return the hash
if(hashCache[filePath]) {
return hashCache[filePath];
}
// Get the absolute path to the file inside of src/site
const absolutePath = path.join(__dirname, 'src/site', filePath);
// Digest the file
const fileBuffer = fs.readFileSync(absolutePath);
const hash = crypto.createHash('sha256').update(fileBuffer).digest('hex');
const relativePath = filePath.slice(0, path.basename(filePath).length * -1)
const digestFileName = `${relativePath}${hash}-${path.basename(filePath)}`;
// See if the digest file exists in the output folder _site
const digestFilePath = path.join(__dirname, '_site', digestFileName);
hashCache[filePath] = digestFileName;
if(!fs.existsSync(digestFilePath)) {
if(!fs.existsSync(path.dirname(digestFilePath))) {
fs.mkdirSync(path.dirname(digestFilePath), { recursive: true });
}
fs.copyFileSync(absolutePath, digestFilePath);
}
// Return the digest file name
return digestFileName;
})For the The upside of such a filter is that we can start including assets such as images that change often using For today I recommend |
|
@SleeplessByte (both) sound great. |
|
@bnijenhuis the code for the easy one would be something like: const path = require('node:path');
const { glob, stat } = require('node:fs/promises');
const entries = await glob('**/*.css')
const times = await Promise.all(entries.map((entry) => stat(entry).then((stats) => stats.mtime)))
const lastModifiedAt = Math.max(...times);
// Do something with that
eleventyConfig.on('eleventy.beforeWatch', async (changedFiles) => {
for(const file of changedFiles) {
if (path.extname(file) === '.css') {
// Do something with current time
}
}
});Are you able and willing to turn this into something working? |
|
@SleeplessByte I'll have a look at it, but I recommend losing the JS cache busting code... |
|
Yes removing that is fine anyway Bernard! |
|
@SleeplessByte Didn't quite get it to work yet. The |
|
Instead of the promises variants, there should be blocking ones too |
@bnijenhuis Used the script from https://bnijenhuis.nl/notes/cache-busting-in-eleventy/ but unfortunately I keep getting: