about summary refs log tree commit diff stats
path: root/cmd/build
diff options
context:
space:
mode:
authorAlan Pearce2024-04-16 18:10:53 +0200
committerAlan Pearce2024-04-16 18:10:53 +0200
commit53fcf3029db48d2e42129c0a2aa4d09b59205900 (patch)
treea81bbb717f6fd503cccf6230303ce5357cf664f6 /cmd/build
parentee0d8aed15902b6b76a14e2612c5ec661b320dc3 (diff)
downloadwebsite-53fcf3029db48d2e42129c0a2aa4d09b59205900.tar.lz
website-53fcf3029db48d2e42129c0a2aa4d09b59205900.tar.zst
website-53fcf3029db48d2e42129c0a2aa4d09b59205900.zip
Purge CSS using npm:purgecss
Diffstat (limited to 'cmd/build')
-rw-r--r--cmd/build/main.go37
1 files changed, 34 insertions, 3 deletions
diff --git a/cmd/build/main.go b/cmd/build/main.go
index 6a2f375..68bba43 100644
--- a/cmd/build/main.go
+++ b/cmd/build/main.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"bytes"
+	"encoding/json"
 	"encoding/xml"
 	"fmt"
 	"io/fs"
@@ -9,6 +10,7 @@ import (
 	"log/slog"
 	"net/url"
 	"os"
+	"os/exec"
 	"path"
 	"path/filepath"
 	"slices"
@@ -120,15 +122,44 @@ func readPosts(root string, inputDir string, outputDir string) ([]Post, Tags, er
 	return posts, tags, nil
 }
 
+type purgeCSSOutput struct {
+	CSS  string `json:"css"`
+	File string
+}
+
+var purgedCSS map[string]string
+
+func purgeCSS(htmlFilename string, cssFilename string) (string, error) {
+	if purgedCSS == nil {
+		purgedCSS = make(map[string]string)
+	} else if purgedCSS[htmlFilename] == "" {
+		bytes, err := exec.Command("bun", "./node_modules/.bin/purgecss", "--css", cssFilename, "--content", htmlFilename).Output()
+		if err != nil {
+			return "", errors.WithMessage(err, "failed running `purgecss` command")
+		}
+		var out []purgeCSSOutput
+		err = json.Unmarshal(bytes, &out)
+		if err != nil {
+			return "", errors.WithMessage(err, "failed decoding `purgecss` output")
+		}
+		purgedCSS[htmlFilename] = out[0].CSS
+	}
+	return purgedCSS[htmlFilename], nil
+}
+
 func layout(filename string, config Config, pageTitle string) (*goquery.Document, error) {
 	html, err := os.Open(filename)
 	if err != nil {
 		return nil, err
 	}
 	defer html.Close()
-	css, err := os.ReadFile("templates/style.css")
+	css, err := purgeCSS(filename, "templates/style.css")
 	if err != nil {
-		return nil, err
+		bytes, err := os.ReadFile("templates/style.css")
+		if err != nil {
+			return nil, err
+		}
+		css = string(bytes)
 	}
 	doc, err := goquery.NewDocumentFromReader(html)
 	if err != nil {
@@ -138,7 +169,7 @@ func layout(filename string, config Config, pageTitle string) (*goquery.Document
 	doc.Find("head > link[rel=alternate]").SetAttr("title", config.Title)
 	doc.Find(".title").SetText(config.Title)
 	doc.Find("title").Add(".p-name").SetText(pageTitle)
-	doc.Find("head > style").SetHtml(string(css))
+	doc.Find("head > style").SetHtml("\n" + string(css))
 	nav := doc.Find("nav")
 	navLink := doc.Find("nav a")
 	nav.Empty()