-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#382 Cache busting, removing obsolete code for fonts #383
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Anneke Sinnema <[email protected]>
Signed-off-by: Anneke Sinnema <[email protected]>
@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: