volpe/lib/cache-busting/plugin.js

68 lines
No EOL
2 KiB
JavaScript

const fs = require("fs");
const crypto = require("crypto");
const path = require("path");
const fileHashCache = {};
const getFileHash = (file, dir = "css") => {
const cacheKey = `${dir}/${file}`;
if (fileHashCache[cacheKey]) return fileHashCache[cacheKey];
const filePath = path.join(__dirname, '..', '..', dir, file);
try {
const content = fs.readFileSync(filePath, "utf-8");
const hash = crypto.createHash("md5").update(content).digest("hex").slice(0, 8);
fileHashCache[cacheKey] = hash;
return hash;
} catch (e) {
console.warn(`Could not hash file: ${file} in ${dir}`);
return null;
}
};
const copyHashedFiles = (sourceDir, outputDir) => {
if (!fs.existsSync(sourceDir)) return;
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
const dirName = path.basename(sourceDir);
const files = fs.readdirSync(sourceDir);
for (const file of files) {
const hash = getFileHash(file, dirName);
const ext = path.extname(file);
const base = path.basename(file, ext);
const hashedName = `${base}${hash == null ? '' : `.${hash}`}${ext}`;
fs.copyFileSync(
path.join(sourceDir, file),
path.join(outputDir, hashedName)
);
}
};
const cacheBustingPlugin = (eleventyConfig, { rootDir }) => {
eleventyConfig.addFilter("fileHash", (file, dir = "css") => {
const hash = getFileHash(file, dir);
const ext = path.extname(file);
const base = path.basename(file, ext);
return `/${dir}/${base}.${hash}${ext}`;
});
eleventyConfig.on("eleventy.before", async () => {
// Copy CSS files with hashes
const cssDir = path.join(rootDir, "css");
const outputCssDir = path.join(rootDir, "_site", "css");
copyHashedFiles(cssDir, outputCssDir);
// Copy assets files with hashes
const assetsDir = path.join(rootDir, "assets");
const outputAssetsDir = path.join(rootDir, "_site", "assets");
copyHashedFiles(assetsDir, outputAssetsDir);
});
};
module.exports = {
cacheBustingPlugin,
getFileHash,
};