From 6f93624b4b08b8aed34a1a5d543773fe0355cf4e Mon Sep 17 00:00:00 2001 From: g_it Date: Sun, 15 Mar 2026 00:48:10 +0100 Subject: [PATCH] Going for max minify for css, js, and html. --- Dockerfile | 1 + minify.py | 73 ++++++++++++++++++++++++++++++++++++++---------- requirements.txt | 2 -- 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7639ac2..4a59cde 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ FROM python:3.13-slim AS builder WORKDIR /app COPY . . +RUN apt-get update && apt-get install -y nodejs npm && npm install -g terser clean-css-cli RUN pip install --no-cache-dir -r ./requirements.txt RUN zensical build RUN rm ./deploy/sitemap.xml diff --git a/minify.py b/minify.py index fce7588..99e1a90 100755 --- a/minify.py +++ b/minify.py @@ -2,30 +2,75 @@ """Minify CSS, JS, and HTML files in the deploy directory in-place.""" import re +import subprocess import sys from pathlib import Path -import rcssmin -import rjsmin - DEPLOY_DIR = Path("./deploy") -def minify_html_content(content): - content = re.sub(r"", "", content, flags=re.DOTALL) # remove comments - content = re.sub(r">\s+<", "><", content) # collapse whitespace between tags - content = re.sub(r"\s{2,}", " ", content) # collapse remaining whitespace - return content.strip() +def minify_css(content): + result = subprocess.run( + ["cleancss"], + input=content, + capture_output=True, + text=True, + ) + if result.returncode != 0: + print(f" cleancss error: {result.stderr}", file=sys.stderr) + return content + return result.stdout + + +def minify_js(content): + result = subprocess.run( + ["terser", "--compress", "--mangle"], + input=content, + capture_output=True, + text=True, + ) + if result.returncode != 0: + print(f" terser error: {result.stderr}", file=sys.stderr) + return content + return result.stdout + + +def minify_html(content): + # Extract and preserve
 and  blocks before minifying
+    preserved = {}
+
+    def preserve(match):
+        key = f"\x00PRESERVE{len(preserved)}\x00"
+        preserved[key] = match.group(0)
+        return key
+
+    content = re.sub(r"", preserve, content, flags=re.IGNORECASE)
+    content = re.sub(r"", preserve, content, flags=re.IGNORECASE)
+
+    # Minify everything else
+    content = re.sub(r"", "", content, flags=re.DOTALL)
+    content = " ".join(line.strip() for line in content.splitlines())
+    content = re.sub(r">\s+<", "><", content)
+    content = re.sub(r"\s{2,}", " ", content)
+    content = content.strip()
+
+    # Restore preserved blocks untouched
+    for key, value in preserved.items():
+        content = content.replace(key, value)
+
+    return content
+
+
+HANDLERS = {
+    ".css": minify_css,
+    ".js": minify_js,
+    ".html": minify_html,
+}
 
 
 def minify_files():
-    handlers = {
-        ".css": lambda c: rcssmin.cssmin(c),
-        ".js": lambda c: rjsmin.jsmin(c, keep_bang_comments=False),
-        ".html": minify_html_content,
-    }
     for file in DEPLOY_DIR.rglob("*"):
-        handler = handlers.get(file.suffix)
+        handler = HANDLERS.get(file.suffix)
         if not handler:
             continue
         content = file.read_text(encoding="utf-8")
diff --git a/requirements.txt b/requirements.txt
index aba80f0..351c3ca 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -22,8 +22,6 @@ pymdown-extensions==10.21
 python-dateutil==2.9.0.post0
 PyYAML==6.0.3
 pyyaml_env_tag==1.1
-rcssmin==1.2.2
-rjsmin==1.2.4
 six==1.17.0
 watchdog==6.0.0
 zensical==0.0.27