character-ref/eleventy.config.js

123 lines
3.5 KiB
JavaScript

import { env } from 'node:process';
import eleventyPluginNavigation from '@11ty/eleventy-navigation';
import eleventyPluginWebc from '@11ty/eleventy-plugin-webc';
import Image, { eleventyImagePlugin } from '@11ty/eleventy-img';
import htmlminifier from 'html-minifier-terser';
import markdownIt from 'markdown-it';
const MARKDOWNIT_OPTIONS = { html: true, linkify: true, typographer: true };
const IMAGE_BASE_WIDTHS = [500, 750, 1000];
const IMAGE_COMPUTED_WIDTHS = new Set(IMAGE_BASE_WIDTHS.flatMap((w) => [w * 1, w * 2, w * 3]));
const IMAGE_ATTR_SIZES = [
{ minw: '120em', size: '1000px' },
{ minw: '64em', size: '750px' },
{ minw: '40em', size: '700px' },
{ minw: '35em', size: '500px' },
{ minw: null, size: 'calc(100vw - 3rem)' }
];
const getAttrSizes = ({ minw, size }) => (minw ? `(min-width: ${minw}) ${size}` : size);
const IMAGE_TRANSFORM_OPTS = {
widths: [...IMAGE_COMPUTED_WIDTHS, 'auto'],
formats: ['avif', 'webp', 'auto'],
sharpJpegOptions: { mozjpeg: true, optimiseScans: true, quality: 95 },
sharpPngOptions: { compressionLevel: 9 },
urlPath: '/img/',
outputDir: './public/img/',
defaultAttributes: {
loading: 'lazy',
decoding: 'async',
sizes: IMAGE_ATTR_SIZES.map(getAttrSizes).join(', ')
}
};
const BASE = env.ELEVENTY_PRODUCTION
? 'https://ref-beta.sebin-nyshkim.net'
: 'http://localhost:8080';
// source: https://notes.jays.net/blog/11ty/
async function getImage(type, src, key) {
let widths, formats;
switch (type) {
case 'og':
widths = [1200];
formats = ['webp'];
break;
case 'favicon':
widths = [200];
formats = ['png'];
break;
}
const opts = {
...IMAGE_TRANSFORM_OPTS,
widths,
formats
};
const stats = await Image(src, opts);
const [format] = formats;
if (key === 'url') {
return BASE + stats[format][0][key];
}
return stats[format][0][key];
}
export default async function (eleventyConfig) {
eleventyConfig.addWatchTarget('./src/css/');
eleventyConfig.addPassthroughCopy('./src/fonts/');
eleventyConfig.addCollection('sebin', (collection) =>
collection.getFilteredByGlob('./src/sebin/*.md')
);
eleventyConfig.addCollection('viktor', (collection) =>
collection.getFilteredByGlob('./src/viktor/*.md')
);
eleventyConfig.addCollection('jarek', (collection) =>
collection.getFilteredByGlob('./src/jarek/*.md')
);
eleventyConfig.addGlobalData('base', BASE);
eleventyConfig.addTransform('minhtml', function (content) {
if ((this.page.outputPath || '').endsWith('.html')) {
return htmlminifier.minify(content, {
removeEmptyElements: true,
collapseWhitespace: true,
ignoreCustomFragments: [
/<(use|path)[^>]*>(?:(?!<\/(use|path)>)[\s\S])*?<\/(use|path)>/,
/<div[^>]*class="color-box"[^>]*>(?:(?!<\/div>)[\s\S])*?<\/div>/,
/<nav[^>]*class="slider-nav"[^>]*>.*?<\/nav>/
]
});
}
return content;
});
eleventyConfig.addFilter('getImage', getImage);
eleventyConfig.addPlugin(eleventyPluginWebc, {
components: ['src/components/**/*.webc', 'npm:@11ty/eleventy-img/*.webc'],
useTransform: false
});
eleventyConfig.addPlugin(eleventyPluginNavigation);
eleventyConfig.addPlugin(eleventyImagePlugin, IMAGE_TRANSFORM_OPTS);
eleventyConfig.setLibrary('md', markdownIt(MARKDOWNIT_OPTIONS));
}
export const config = {
dir: {
input: 'src',
output: 'public',
layouts: 'layouts',
includes: 'includes'
},
markdownTemplateEngine: 'webc'
};