feat: minify html + js

This commit is contained in:
Cory Dransfeldt 2024-08-28 19:55:49 -07:00
parent d1b6b8cbea
commit ee53cbdb26
No known key found for this signature in database
6 changed files with 320 additions and 8 deletions

View file

@ -3,8 +3,9 @@ import tablerIcons from '@cdransf/eleventy-plugin-tabler-icons'
import markdownIt from 'markdown-it'
import markdownItAnchor from 'markdown-it-anchor'
import markdownItFootnote from 'markdown-it-footnote'
import htmlmin from 'html-minifier-terser'
import filters from './config/filters/index.js'
import { copyErrorPages } from './config/events/index.js'
import { copyErrorPages, minifyJsComponents } from './config/events/index.js'
import { processContent, albumReleasesCalendar } from './config/collections/index.js'
import { cssConfig } from './config/plugins/css-config.js'
import { DateTime } from 'luxon'
@ -92,6 +93,32 @@ export default async function (eleventyConfig) {
// events
eleventyConfig.on('afterBuild', copyErrorPages)
eleventyConfig.on('afterBuild', minifyJsComponents)
// transforms
if (process.env.ELEVENTY_PRODUCTION) {
eleventyConfig.addTransform('html-minify', (content, path) => {
if (path && path.endsWith('.html')) {
return htmlmin.minify(content, {
collapseBooleanAttributes: true,
collapseWhitespace: true,
decodeEntities: true,
includeAutoGeneratedTags: false,
minifyCSS: true,
minifyJS: true,
minifyURLs: true,
noNewlinesBeforeTagClose: true,
quoteCharacter: '"',
removeComments: true,
sortAttributes: true,
sortClassName: true,
useShortDoctype: true,
processScripts: ['application/ld+json'], // minify JSON-LD scripts
})
}
return content
})
}
return {
passthroughFileCopy: true,

View file

@ -1,5 +1,6 @@
import fs from 'fs'
import path from 'path'
import { minify } from 'terser'
const errorPages = ['404', '500', '1000', 'broken', 'error', 'js-challenge', 'not-allowed', 'rate-limit']
@ -28,3 +29,26 @@ export const copyErrorPages = () => {
})
})
}
export const minifyJsComponents = async () => {
const scriptsDir = '_site/assets/scripts'
const minifyJsFilesInDir = async (dir) => {
const files = fs.readdirSync(dir)
for (const fileName of files) {
const filePath = path.join(dir, fileName)
const stat = fs.statSync(filePath)
if (stat.isDirectory()) {
await minifyJsFilesInDir(filePath)
} else if (fileName.endsWith('.js')) {
const minified = await minify(fs.readFileSync(filePath, 'utf8'))
fs.writeFileSync(filePath, minified.code)
} else {
console.log(`⚠ No .js file to minify in ${filePath}`)
}
}
}
await minifyJsFilesInDir(scriptsDir)
}

View file

@ -24,6 +24,9 @@ export default {
formatNumber: (number) => number.toLocaleString('en-US'),
shuffleArray,
sanitizeMediaString,
sanitizeHtml: (html) => sanitizeHtml(html, {
textFilter: (text) => text.replace(/"/g, '')
}),
// navigation
isLinkActive: (category, page) => page.includes(category) && page.split('/').filter(a => a !== '').length <= 1,

261
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "coryd.dev",
"version": "24.2.0",
"version": "24.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "coryd.dev",
"version": "24.2.0",
"version": "24.3.0",
"license": "MIT",
"dependencies": {
"@cdransf/api-text": "^1.5.0",
@ -23,6 +23,8 @@
"autoprefixer": "^10.4.20",
"cssnano": "^7.0.5",
"dotenv-flow": "^4.1.0",
"html-entities": "^2.5.2",
"html-minifier-terser": "^7.2.0",
"ics": "^3.7.6",
"liquidjs": "10.16.4",
"luxon": "^3.5.0",
@ -36,7 +38,8 @@
"postcss-js": "^4.0.1",
"rimraf": "^6.0.1",
"sanitize-html": "^2.13.0",
"slugify": "^1.6.6"
"slugify": "^1.6.6",
"terser": "^5.31.6"
}
},
"node_modules/@11ty/dependency-tree": {
@ -403,6 +406,70 @@
"node": ">=12"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -938,6 +1005,13 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true,
"license": "MIT"
},
"node_modules/call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
@ -958,6 +1032,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/camel-case": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
"integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
"dev": true,
"license": "MIT",
"dependencies": {
"pascal-case": "^3.1.2",
"tslib": "^2.0.3"
}
},
"node_modules/camelcase-css": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
@ -1034,6 +1119,19 @@
"fsevents": "~2.3.2"
}
},
"node_modules/clean-css": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
"integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
"dev": true,
"license": "MIT",
"dependencies": {
"source-map": "~0.6.0"
},
"engines": {
"node": ">= 10.0"
}
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@ -1594,6 +1692,17 @@
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/dot-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
"dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/dotenv": {
"version": "16.4.5",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
@ -2233,6 +2342,45 @@
"node": ">= 0.4"
}
},
"node_modules/html-entities": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz",
"integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/mdevils"
},
{
"type": "patreon",
"url": "https://patreon.com/mdevils"
}
],
"license": "MIT"
},
"node_modules/html-minifier-terser": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
"integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
"dev": true,
"license": "MIT",
"dependencies": {
"camel-case": "^4.1.2",
"clean-css": "~5.3.2",
"commander": "^10.0.0",
"entities": "^4.4.0",
"param-case": "^3.0.4",
"relateurl": "^0.2.7",
"terser": "^5.15.1"
},
"bin": {
"html-minifier-terser": "cli.js"
},
"engines": {
"node": "^14.13.1 || >=16.0.0"
}
},
"node_modules/htmlparser2": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz",
@ -2615,6 +2763,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.0.3"
}
},
"node_modules/lru-cache": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz",
@ -2833,6 +2991,17 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true,
"license": "MIT",
"dependencies": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
},
"node_modules/node-releases": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
@ -2966,6 +3135,17 @@
"dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/param-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
"dev": true,
"license": "MIT",
"dependencies": {
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/parse-srcset": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
@ -2983,6 +3163,17 @@
"node": ">= 0.8"
}
},
"node_modules/pascal-case": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
"dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@ -3892,6 +4083,16 @@
"node": ">=8.10.0"
}
},
"node_modules/relateurl": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
"integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@ -4253,6 +4454,16 @@
"node": ">=8.0.0"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
@ -4263,6 +4474,17 @@
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@ -4473,6 +4695,32 @@
"node": ">= 10"
}
},
"node_modules/terser": {
"version": "5.31.6",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz",
"integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"engines": {
"node": ">=10"
}
},
"node_modules/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"license": "MIT"
},
"node_modules/thenby": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz",
@ -4524,6 +4772,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"dev": true,
"license": "0BSD"
},
"node_modules/type-fest": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",

View file

@ -1,6 +1,6 @@
{
"name": "coryd.dev",
"version": "24.2.0",
"version": "24.3.0",
"description": "The source for my personal site. Built using 11ty (and other tools).",
"type": "module",
"scripts": {
@ -39,6 +39,8 @@
"autoprefixer": "^10.4.20",
"cssnano": "^7.0.5",
"dotenv-flow": "^4.1.0",
"html-entities": "^2.5.2",
"html-minifier-terser": "^7.2.0",
"ics": "^3.7.6",
"liquidjs": "10.16.4",
"luxon": "^3.5.0",
@ -52,6 +54,7 @@
"postcss-js": "^4.0.1",
"rimraf": "^6.0.1",
"sanitize-html": "^2.13.0",
"slugify": "^1.6.6"
"slugify": "^1.6.6",
"terser": "^5.31.6"
}
}

View file

@ -88,8 +88,8 @@
<link rel="stylesheet" href="/assets/styles/index.css?v={% appVersion %}" type="text/css" />
<link rel="canonical" href="{{ fullUrl }}" />
<meta property="og:title" content="{{ pageTitle }}" />
<meta name="description" content="{{ pageDescription }}" />
<meta property="og:description" content="{{ pageDescription }}" />
<meta name="description" content="{{ pageDescription | sanitizeHtml }}" />
<meta property="og:description" content="{{ pageDescription | sanitizeHtml }}" />
<meta property="og:type" content="article" />
<meta property="og:url" content="{{ fullUrl }}" />
<meta property="og:image" content="{{ ogImage }}?class=w800" />