0
0
website/.eleventy.js

152 lines
4.7 KiB
JavaScript

// Import the necessary libraries and plugins using ESM syntax
import fs from "node:fs/promises";
import { DateTime } from "luxon";
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
import { minify } from "html-minifier-terser";
import PurgeCss from "eleventy-plugin-purgecss";
import CleanCSS from "clean-css";
import markdownIt from "markdown-it";
import markdownItAttrs from "markdown-it-attrs";
import markdownItAnchor from "markdown-it-anchor";
import markdownItBracketedSpans from "markdown-it-bracketed-spans";
export default function (eleventyConfig) {
//
// Configure Eleventy to not use .gitignore files
eleventyConfig.setUseGitIgnore(false);
// Set the directories for input, includes, data, and output
eleventyConfig.dir = {
input: "src",
includes: "_includes",
data: "_data",
output: "site",
};
// Set Markdown options
const mdOptions = {
html: true, // Allow HTML tags in Markdown files
breaks: true, // Convert line breaks to HTML <br> tags
linkify: true, // Automatically convert URLs into links
};
const markdownItAnchorOptions = {
level: 2, // minimum level header -- anchors will only be applied to h2 level headers and below but not h1
permalink: true,
};
// Create a Markdown library with custom plugins
const markdownLib = markdownIt(mdOptions)
.use(markdownItAnchor, markdownItAnchorOptions)
.use(markdownItAttrs)
.use(markdownItBracketedSpans) // Enable bracketed spans
.disable("code");
// Set the Markdown library to use with Eleventy
eleventyConfig.setLibrary("md", markdownLib);
// Define the template formats that Eleventy will process
eleventyConfig.setTemplateFormats([
"md",
"webmanifest",
"xml",
"ico",
"avif",
"webp",
"webm",
"svg",
"png",
"jpg",
"jpeg",
"txt",
"woff",
"woff2",
"css",
"pdf",
]);
// Register a filter to output a human-readable post date
eleventyConfig.addFilter("readablePostDate", (dateObj) => {
return DateTime.fromJSDate(dateObj, {
zone: "Asia/Singapore",
})
.setLocale("en-GB")
.toLocaleString({ day: "numeric", month: "short", year: "numeric" });
});
// Register a filter to output post date in ISO format
eleventyConfig.addFilter("postDate", (dateObj) => {
return DateTime.fromJSDate(dateObj, {
zone: "Asia/Singapore",
})
.setLocale("en-GB")
.toISODate();
});
// Add an image transform plugin with custom configuration
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
extensions: "html", // Process only HTML files
formats: ["jpg", "webp"],
widths: ["auto", 400, 800, 1600],
defaultAttributes: {
loading: "eager",
sizes: "auto",
decoding: "async",
},
});
// Add a transform to minify HTML content
eleventyConfig.addTransform("minifyHTML", (content, outputPath) => {
// Only minify HTML files
if (outputPath?.endsWith(".html")) {
return minify(content, {
collapseWhitespace: true, // Collapses whitespace between tags
removeComments: true, // Removes HTML comments
minifyCSS: true, // Minifies inline CSS
minifyJS: true, // Minifies inline JavaScript
removeAttributeQuotes: true, // Removes quotes around attributes when possible
removeOptionalTags: false, // Removes optional HTML tags (<html>, <head>, <body>)
collapseBooleanAttributes: true, // Converts boolean attributes to HTML5 style
removeEmptyAttributes: true, // Removes empty attributes
minifyURLs: true, // Minifies URLs in attributes
html5: true, // Enables HTML5 parsing
});
}
return content; // Return the original content if not HTML
});
// CleanCSS
eleventyConfig.on("afterBuild", async () => {
const inputFiles = ["src/css/reset.css", "src/css/index.css"];
for (const inputFile of inputFiles) {
try {
const input = await fs.readFile(inputFile, "utf8");
const output = new CleanCSS().minify(input);
const outputFilePath = `site/css/${inputFile.split("/").pop()}`; // Adjust output path as necessary
await fs.writeFile(outputFilePath, output.styles);
console.log(
`eleventy-plugin-cleancss: Successfully minified ${inputFile} to ${outputFilePath}`,
);
} catch (err) {
console.error(
`eleventy-plugin-cleancss: Error minifying ${inputFile}: ${err}`,
);
}
}
});
// Purge unused CSS
eleventyConfig.addPlugin(PurgeCss, {
config: "./purgecss.config.cjs",
});
// Return effective configuration for Eleventy
return {
dir: {
input: "src",
includes: "_includes",
output: "site",
},
};
}