* cache asset images more aggressively * more careful about which gets the manual surrogate key * fix rendered-content-link-checker script too * feedbacked
53 lines
1.8 KiB
JavaScript
53 lines
1.8 KiB
JavaScript
import fs from 'fs'
|
|
|
|
import { visit } from 'unist-util-visit'
|
|
|
|
// Matches any <img> tags with an href that starts with `/assets/` or '/public/'
|
|
const matcher = (node) =>
|
|
node.type === 'element' &&
|
|
node.tagName === 'img' &&
|
|
node.properties &&
|
|
node.properties.src &&
|
|
(node.properties.src.startsWith('/assets/') || node.properties.src.startsWith('/public/'))
|
|
|
|
// Content authors write images like ` {
|
|
return (tree) => {
|
|
visit(tree, matcher, (node) => {
|
|
const newSrc = getNewSrc(node)
|
|
if (newSrc) {
|
|
node.properties.src = newSrc
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
function getNewSrc(node) {
|
|
const { src } = node.properties
|
|
if (!src.startsWith('/')) return
|
|
|
|
try {
|
|
const filePath = src.slice(1)
|
|
const stats = fs.statSync(filePath)
|
|
// The size is not perfect but it's good enough. The size is
|
|
// very fast to pick up without needing to do a deep hashing of the
|
|
// image's content. It's perfectly possible that someone edits an
|
|
// image and it's size doesn't change. Although very unlikely.
|
|
// The slightest change to the image is more likely to either increase
|
|
// or decrease the image size by at least 1 byte.
|
|
// Also, because of this limitation, we're not confident to cache the
|
|
// image more than say 24h. But in the unlikely event that someone does
|
|
// edit an image and the size doesn't change, there's always the
|
|
// escape hatch that you can soft-purge all manual CDN surrogate keys.
|
|
if (!stats.size) return
|
|
const hash = `${stats.size}`
|
|
const split = src.split('/')
|
|
split.splice(2, 0, `cb-${hash}`)
|
|
return split.join('/')
|
|
} catch (err) {
|
|
console.warn(`Error trying to get a hash for ${src}`, err)
|
|
}
|
|
}
|