76 lines
1.9 KiB
JavaScript
76 lines
1.9 KiB
JavaScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import debugUtil from "debug";
|
|
|
|
import { createHash } from "@11ty/eleventy-utils";
|
|
|
|
const debug = debugUtil("Eleventy:Bundle");
|
|
|
|
const hashCache = {};
|
|
const directoryExistsCache = {};
|
|
const writingCache = new Set();
|
|
|
|
class BundleFileOutput {
|
|
constructor(outputDirectory, bundleDirectory) {
|
|
this.outputDirectory = outputDirectory;
|
|
this.bundleDirectory = bundleDirectory || "";
|
|
this.hashLength = 10;
|
|
this.fileExtension = undefined;
|
|
}
|
|
|
|
setFileExtension(ext) {
|
|
this.fileExtension = ext;
|
|
}
|
|
|
|
async getFilenameHash(content) {
|
|
if(hashCache[content]) {
|
|
return hashCache[content];
|
|
}
|
|
|
|
let base64hash = await createHash(content);
|
|
let filenameHash = base64hash.substring(0, this.hashLength);
|
|
hashCache[content] = filenameHash;
|
|
return filenameHash;
|
|
}
|
|
|
|
getFilename(filename, extension) {
|
|
return filename + (extension && !extension.startsWith(".") ? `.${extension}` : "");
|
|
}
|
|
|
|
modifyPathToUrl(dir, filename) {
|
|
return "/" + path.join(dir, filename).split(path.sep).join("/");
|
|
}
|
|
|
|
async writeBundle(content, type, writeToFileSystem) {
|
|
// do not write a bundle, do not return a file name is content is empty
|
|
if(!content) {
|
|
return;
|
|
}
|
|
|
|
let dir = path.join(this.outputDirectory, this.bundleDirectory);
|
|
let filenameHash = await this.getFilenameHash(content);
|
|
let filename = this.getFilename(filenameHash, this.fileExtension || type);
|
|
|
|
if(writeToFileSystem) {
|
|
let fullPath = path.join(dir, filename);
|
|
|
|
// no duplicate writes, this may be improved with a fs exists check, but it would only save the first write
|
|
if(!writingCache.has(fullPath)) {
|
|
writingCache.add(fullPath);
|
|
|
|
if(!directoryExistsCache[dir]) {
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
directoryExistsCache[dir] = true;
|
|
}
|
|
|
|
debug("Writing bundle %o", fullPath);
|
|
fs.writeFileSync(fullPath, content);
|
|
}
|
|
}
|
|
|
|
return this.modifyPathToUrl(this.bundleDirectory, filename);
|
|
}
|
|
}
|
|
|
|
export { BundleFileOutput };
|