Skip to content

Instantly share code, notes, and snippets.

@tobystokes
Last active April 3, 2022 23:47
Show Gist options
  • Save tobystokes/b4b8bb743ec4c57317f6ef043093ff95 to your computer and use it in GitHub Desktop.
Save tobystokes/b4b8bb743ec4c57317f6ef043093ff95 to your computer and use it in GitHub Desktop.
eleventy-img caching
const imageShortcode = require("./image");
module.exports = function(eleventyConfig) {
eleventyConfig.addNunjucksShortcode("image", imageShortcode);
// ... + other eleventyConfig
};
const Image = require("@11ty/eleventy-img");
const path = require("path");
const fs = require("fs");
module.exports = function(src, alt, widths, sizes, classattr) {
// src input same as 'normal' site-relative path for convenience, so add base path:
src = src.startsWith("./src") ? src : "./src" + src;
let ext = src.substr(src.lastIndexOf(".") + 1);
let currentFormat = ext == "png" ? "png" : "jpeg";
let srcset = [320, 640, 1024, 1536, 2048];
if (widths) {
widthsArray = widths.split(",");
srcset = widthsArray.map(n => Number(n));
}
let options = {
urlPath: "/images/transform/",
outputDir: "./src/images/transform/",
widths: srcset,
formats: ["avif", "webp", currentFormat],
filenameFormat: function(id, src, width, format, options) {
// id: hash of the original image
// src: original image path
// width: current width in px
// format: current file format
// options: set of options passed to the Image call
const extension = path.extname(src);
const name = path.basename(src, extension);
return `${name}-${id}-${width}w.${format}`;
},
sharpJpegOptions: {
quality: 80, // default
progressive: true
},
sharpAvifOptions: {
quality: 80
}
};
const stats = Image.statsSync(src, options);
/** Creating a flat array of all the output paths from the stats object. */
const outputPaths = Object.keys(stats).reduce((acc, key) => {
return [
...acc,
...stats[key].map(resource => {
return resource.outputPath;
})
];
}, []);
/** Checking if all output files exists. */
let hasImageBeenOptimized = true;
for (const outputPath of outputPaths) {
let fullPath = path.resolve(__dirname, "..", outputPath);
/** Edit the output file path resolving, depending of this file */
if (!fs.existsSync(fullPath)) {
console.log("No image exists at :", fullPath);
hasImageBeenOptimized = false;
}
}
// generate images, only if they don't exist
if (!hasImageBeenOptimized) {
Image(src, options);
}
let imageAttributes = {
alt,
sizes,
class: classattr ? classattr : false,
loading: "lazy",
decoding: "async",
whitespaceMode: "inline"
};
// get metadata even the images are not fully generated
metadata = Image.statsSync(src, options);
return Image.generateHTML(metadata, imageAttributes);
};
{% image "/path/to/images/image.jpg", "alt text", "320,640,1024" %}
@inetbiz
Copy link

inetbiz commented Apr 3, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment