CSS and Images cache busting
This commit is contained in:
parent
f85d4d562e
commit
97fd7b6081
14
lib/hash.ts
14
lib/hash.ts
|
@ -1,6 +1,18 @@
|
||||||
import { Transform } from "node:stream";
|
import { Transform } from "node:stream";
|
||||||
import { createHash } from "node:crypto";
|
import { createHash } from "node:crypto";
|
||||||
import File from "vinyl";
|
import File from "vinyl";
|
||||||
|
import { globSync } from "glob";
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
|
import { PRODUCTION } from "./environment.js";
|
||||||
|
|
||||||
|
export function readAssetManifest(): { [entry: string]: string } {
|
||||||
|
return Object.assign(
|
||||||
|
{},
|
||||||
|
...globSync("dist/_assets/*.manifest").map((path) =>
|
||||||
|
JSON.parse(readFileSync(path).toString()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function fileHash(buffer: Buffer) {
|
function fileHash(buffer: Buffer) {
|
||||||
const hash = createHash("sha256");
|
const hash = createHash("sha256");
|
||||||
|
@ -15,7 +27,7 @@ export default function (manifestName: string) {
|
||||||
readableObjectMode: true,
|
readableObjectMode: true,
|
||||||
writableObjectMode: true,
|
writableObjectMode: true,
|
||||||
transform(chunk: File, _, callback) {
|
transform(chunk: File, _, callback) {
|
||||||
const hash = fileHash(chunk.contents as Buffer);
|
const hash = PRODUCTION ? fileHash(chunk.contents as Buffer) : "00000000";
|
||||||
const newName = `${chunk.basename.substring(0, chunk.basename.length - chunk.extname.length)}.${hash.substring(0, 8)}${chunk.extname}`;
|
const newName = `${chunk.basename.substring(0, chunk.basename.length - chunk.extname.length)}.${hash.substring(0, 8)}${chunk.extname}`;
|
||||||
|
|
||||||
mappings[chunk.basename] = newName;
|
mappings[chunk.basename] = newName;
|
||||||
|
|
22
lib/postcss/hashes.ts
Normal file
22
lib/postcss/hashes.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import Postcss from "postcss";
|
||||||
|
import { readAssetManifest } from "../hash.js";
|
||||||
|
|
||||||
|
export default (opts: any = {}): Postcss.Plugin => {
|
||||||
|
return {
|
||||||
|
postcssPlugin: "postcss-hashes",
|
||||||
|
Once() {
|
||||||
|
opts._mappings = readAssetManifest();
|
||||||
|
},
|
||||||
|
Declaration(decl: Postcss.Declaration) {
|
||||||
|
decl.value = decl.value.replace(/url\("([^"]+)"\)/, (v, url) => {
|
||||||
|
if (opts._mappings.hasOwnProperty(url)) {
|
||||||
|
return v.replace(url, opts._mappings[url]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const postcss = true;
|
|
@ -7,4 +7,4 @@ import { svg } from "./tasks/svg.js";
|
||||||
import { watch } from "./tasks/watch.js";
|
import { watch } from "./tasks/watch.js";
|
||||||
|
|
||||||
export { articles, css, fonts, images, svg, watch };
|
export { articles, css, fonts, images, svg, watch };
|
||||||
export default series(fonts, css, images, svg, articles);
|
export default series(fonts, images, svg, css, articles);
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { PRODUCTION, DEFAULT_DATE } from "../environment.js";
|
||||||
import rehypeExternalLinks from "rehype-external-links";
|
import rehypeExternalLinks from "rehype-external-links";
|
||||||
import visit from "unist-util-visit";
|
import visit from "unist-util-visit";
|
||||||
import { src, dest } from "gulp";
|
import { src, dest } from "gulp";
|
||||||
import { globSync } from "glob";
|
import { readAssetManifest } from "../hash.js";
|
||||||
|
|
||||||
const Asciidoctor = asciidoctor();
|
const Asciidoctor = asciidoctor();
|
||||||
const EXTENSION_REGISTRY = Asciidoctor.Extensions.create();
|
const EXTENSION_REGISTRY = Asciidoctor.Extensions.create();
|
||||||
|
@ -41,15 +41,6 @@ const SITE_DEFAULT_META = {
|
||||||
"og:locale": "en_GB",
|
"og:locale": "en_GB",
|
||||||
};
|
};
|
||||||
|
|
||||||
function readAssetManifest(): { [entry: string]: string } {
|
|
||||||
return Object.assign(
|
|
||||||
{},
|
|
||||||
...globSync("dist/_assets/*.manifest").map((path) =>
|
|
||||||
JSON.parse(readFileSync(path).toString()),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractImages(gulp: Transform, file: File) {
|
function extractImages(gulp: Transform, file: File) {
|
||||||
return function () {
|
return function () {
|
||||||
return function (tree) {
|
return function (tree) {
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
import { src, dest } from "gulp";
|
import { src, dest } from "gulp";
|
||||||
|
import hashPaths from "../hash.js";
|
||||||
|
|
||||||
export const images = () => src("src/*.avif", { encoding: false }).pipe(dest("dist/_assets/"));
|
export const images = () =>
|
||||||
|
src("src/*.avif", { encoding: false })
|
||||||
|
.pipe(hashPaths("images.manifest"))
|
||||||
|
.pipe(dest("dist/_assets/"));
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
import importPlugin from "postcss-import";
|
import importPlugin from "postcss-import";
|
||||||
import nestingPlugin from "postcss-nesting";
|
import nestingPlugin from "postcss-nesting";
|
||||||
import cssnanoPlugin from "cssnano";
|
import cssnanoPlugin from "cssnano";
|
||||||
|
import hashesPlugin from "./lib/postcss/hashes.js";
|
||||||
|
|
||||||
/** @type {import('postcss-load-config').Config} */
|
/** @type {import('postcss-load-config').Config} */
|
||||||
export default {
|
export default {
|
||||||
plugins: [importPlugin(), nestingPlugin(), cssnanoPlugin({ preset: "default" })],
|
plugins: [
|
||||||
|
importPlugin(),
|
||||||
|
nestingPlugin(),
|
||||||
|
hashesPlugin(),
|
||||||
|
cssnanoPlugin({ preset: "default" }),
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user