Add initial 11ty website structure
This commit is contained in:
+158
@@ -0,0 +1,158 @@
|
||||
import debugUtil from "debug";
|
||||
|
||||
const debug = debugUtil("Eleventy:Bundle");
|
||||
|
||||
/* This class defers any `bundleGet` calls to a post-build transform step,
|
||||
* to allow `getBundle` to be called before all of the `css` additions have been processed
|
||||
*/
|
||||
class OutOfOrderRender {
|
||||
static SPLIT_REGEX = /(\/\*__EleventyBundle:[^:]*:[^:]*:[^:]*:EleventyBundle__\*\/)/;
|
||||
static SEPARATOR = ":";
|
||||
|
||||
constructor(content) {
|
||||
this.content = content;
|
||||
this.managers = {};
|
||||
}
|
||||
|
||||
// type if `get` (return string) or `file` (bundle writes to file, returns file url)
|
||||
static getAssetKey(type, name, bucket) {
|
||||
if(Array.isArray(bucket)) {
|
||||
bucket = bucket.join(",");
|
||||
} else if(typeof bucket === "string") {
|
||||
} else {
|
||||
bucket = "";
|
||||
}
|
||||
return `/*__EleventyBundle:${type}:${name}:${bucket || "default"}:EleventyBundle__*/`
|
||||
}
|
||||
|
||||
static parseAssetKey(str) {
|
||||
if(str.startsWith("/*__EleventyBundle:")) {
|
||||
let [prefix, type, name, bucket, suffix] = str.split(OutOfOrderRender.SEPARATOR);
|
||||
return { type, name, bucket };
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
setAssetManager(name, assetManager) {
|
||||
this.managers[name] = assetManager;
|
||||
}
|
||||
|
||||
setOutputDirectory(dir) {
|
||||
this.outputDirectory = dir;
|
||||
}
|
||||
|
||||
normalizeMatch(match) {
|
||||
let ret = OutOfOrderRender.parseAssetKey(match)
|
||||
return ret || match;
|
||||
}
|
||||
|
||||
findAll() {
|
||||
let matches = this.content.split(OutOfOrderRender.SPLIT_REGEX);
|
||||
let ret = [];
|
||||
for(let match of matches) {
|
||||
ret.push(this.normalizeMatch(match));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
setWriteToFileSystem(isWrite) {
|
||||
this.writeToFileSystem = isWrite;
|
||||
}
|
||||
|
||||
getAllBucketsForPage(pageData) {
|
||||
let availableBucketsForPage = new Set();
|
||||
for(let name in this.managers) {
|
||||
for(let bucket of this.managers[name].getBucketsForPage(pageData)) {
|
||||
availableBucketsForPage.add(`${name}::${bucket}`);
|
||||
}
|
||||
}
|
||||
return availableBucketsForPage;
|
||||
}
|
||||
|
||||
getManager(name) {
|
||||
if(!this.managers[name]) {
|
||||
throw new Error(`No asset manager found for ${name}. Known names: ${Object.keys(this.managers)}`);
|
||||
}
|
||||
return this.managers[name];
|
||||
}
|
||||
|
||||
async replaceAll(pageData, stage = 0) {
|
||||
let matches = this.findAll();
|
||||
let availableBucketsForPage = this.getAllBucketsForPage(pageData);
|
||||
let usedBucketsOnPage = new Set();
|
||||
let bucketsOutputStringCount = {};
|
||||
let bucketsFileCount = {};
|
||||
|
||||
for(let match of matches) {
|
||||
if(typeof match === "string") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// type is `file` or `get`
|
||||
let {type, name, bucket} = match;
|
||||
let key = `${name}::${bucket}`;
|
||||
if(!usedBucketsOnPage.has(key)) {
|
||||
usedBucketsOnPage.add(key);
|
||||
}
|
||||
|
||||
if(type === "get") {
|
||||
if(!bucketsOutputStringCount[key]) {
|
||||
bucketsOutputStringCount[key] = 0;
|
||||
}
|
||||
bucketsOutputStringCount[key]++;
|
||||
} else if(type === "file") {
|
||||
if(!bucketsFileCount[key]) {
|
||||
bucketsFileCount[key] = 0;
|
||||
}
|
||||
bucketsFileCount[key]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Hoist code in non-default buckets that are output multiple times
|
||||
// Only hoist if 2+ `get` OR 1+ `get` and 1+ `file`
|
||||
for(let bucketInfo in bucketsOutputStringCount) {
|
||||
let stringOutputCount = bucketsOutputStringCount[bucketInfo];
|
||||
if(stringOutputCount > 1 || stringOutputCount === 1 && bucketsFileCount[bucketInfo] > 0) {
|
||||
let [name, bucketName] = bucketInfo.split("::");
|
||||
this.getManager(name).hoistBucket(pageData, bucketName);
|
||||
}
|
||||
}
|
||||
|
||||
let content = await Promise.all(matches.map(match => {
|
||||
if(typeof match === "string") {
|
||||
return match;
|
||||
}
|
||||
|
||||
let {type, name, bucket} = match;
|
||||
let manager = this.getManager(name);
|
||||
|
||||
// Quit early if in stage 0, run delayed replacements if in stage 1+
|
||||
if(typeof manager.isDelayed === "function" && manager.isDelayed() && stage === 0) {
|
||||
return OutOfOrderRender.getAssetKey(type, name, bucket);
|
||||
}
|
||||
|
||||
if(type === "get") {
|
||||
// returns promise
|
||||
return manager.getForPage(pageData, bucket);
|
||||
} else if(type === "file") {
|
||||
// returns promise
|
||||
return manager.writeBundle(pageData, bucket, {
|
||||
output: this.outputDirectory,
|
||||
write: this.writeToFileSystem,
|
||||
});
|
||||
}
|
||||
return "";
|
||||
}));
|
||||
|
||||
for(let bucketInfo of availableBucketsForPage) {
|
||||
if(!usedBucketsOnPage.has(bucketInfo)) {
|
||||
let [name, bucketName] = bucketInfo.split("::");
|
||||
debug(`WARNING! \`${pageData.inputPath}\` has unbundled \`${name}\` assets (in the '${bucketName}' bucket) that were not written to or used on the page. You might want to add a call to \`getBundle('${name}', '${bucketName}')\` to your content! Learn more: https://github.com/11ty/eleventy-plugin-bundle#asset-bucketing`);
|
||||
}
|
||||
}
|
||||
|
||||
return content.join("");
|
||||
}
|
||||
}
|
||||
|
||||
export { OutOfOrderRender };
|
||||
Reference in New Issue
Block a user