import { minify } from "../deps/minify_html.ts"; import { merge } from "../core/utils/object.ts"; import { log } from "../core/utils/log.ts"; import { bytes, percentage } from "../core/utils/format.ts"; import type { Options as MinifyOptions } from "../deps/minify_html.ts"; import type Site from "../core/site.ts"; export interface Options { /** File extensions to minify */ extensions?: Array<".html" | ".css" | ".js">; /** Default options for minify-html library */ options?: MinifyOptions; } // Default options export const defaults: Options = { extensions: [".html"], options: { do_not_minify_doctype: true, ensure_spec_compliant_unquoted_attribute_values: true, keep_closing_tags: false, keep_html_and_head_opening_tags: false, keep_spaces_between_attributes: true, keep_comments: false, remove_bangs: false, remove_processing_instructions: false, }, }; /** * A plugin to minify HTML, CSS & JavaScript files * @see https://lume.land/plugins/minify_html/ */ export function minifyHTML(userOptions?: Options) { const options = merge(defaults, userOptions); const { extensions } = options; // Validate supported file extensions if (extensions.some((ext) => ![".html", ".css", ".js"].includes(ext))) { throw new Error( `Unsupported extensions configuration: ${ extensions.join(", ") }. Only ".html", ".css" and ".js" are supported by minify-html plugin.`, ); } options.options.minify_css ??= options.extensions?.includes(".css"); options.options.minify_js ??= options.extensions?.includes(".js"); return (site: Site) => { site.process(options.extensions, function processMinifyHTML(pages) { const item = site.debugBar?.buildItem( "[minify_html plugin] Minification completed", ); for (const page of pages) { try { const content = page.bytes; page.bytes = minify(content, options.options) as Uint8Array< ArrayBuffer >; if (item) { item.items ??= []; const old = content.length; const minified = page.bytes.length; item.items.push({ title: `[${percentage(old, minified)}] ${page.data.url}`, details: `${bytes(page.bytes.length)}`, }); } } catch (error) { log.error( `[minify-html plugin] Error minifying ${page.sourcePath}: ${error}`, ); } } }); }; } export default minifyHTML;