Vendor Tailwind via the standalone CLI; drop the Play CDN
Tailwind is now compiled from static/css/input.css into a committed static/css/tailwind.css by the standalone CLI, fetched on demand into bin/ (gitignored) so no Node toolchain is required. layout.templ loads the local stylesheet instead of cdn.tailwindcss.com. Adds a Makefile with generate/css/build/run/test/clean targets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,6 +2,9 @@
|
|||||||
veola-bin
|
veola-bin
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
|
# Fetched-on-demand tooling (Tailwind standalone CLI)
|
||||||
|
/bin/
|
||||||
|
|
||||||
# Local config (use config.toml.example as template)
|
# Local config (use config.toml.example as template)
|
||||||
config.toml
|
config.toml
|
||||||
|
|
||||||
|
|||||||
43
Makefile
Normal file
43
Makefile
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Veola build.
|
||||||
|
#
|
||||||
|
# Requires the `templ` CLI (go install github.com/a-h/templ/cmd/templ@latest).
|
||||||
|
# The Tailwind standalone CLI is fetched on demand into bin/ (gitignored) — no
|
||||||
|
# node toolchain required. static/css/tailwind.css is a committed build
|
||||||
|
# artifact so a plain `go build` deploy still has styles; run `make css`
|
||||||
|
# (or `make build`) after touching templates or static/css/input.css.
|
||||||
|
|
||||||
|
TAILWIND_VERSION := v3.4.17
|
||||||
|
TAILWIND_BIN := bin/tailwindcss
|
||||||
|
# linux-x64 only; change the asset name for other platforms.
|
||||||
|
TAILWIND_URL := https://github.com/tailwindlabs/tailwindcss/releases/download/$(TAILWIND_VERSION)/tailwindcss-linux-x64
|
||||||
|
TEMPL := $(shell go env GOPATH)/bin/templ
|
||||||
|
|
||||||
|
.PHONY: all generate css build run test clean
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
$(TAILWIND_BIN):
|
||||||
|
mkdir -p bin
|
||||||
|
curl -sL --fail $(TAILWIND_URL) -o $(TAILWIND_BIN)
|
||||||
|
chmod +x $(TAILWIND_BIN)
|
||||||
|
|
||||||
|
# Compile Tailwind utilities (scanned from the .templ sources) into
|
||||||
|
# static/css/tailwind.css. The hand-written component layer is app.css.
|
||||||
|
css: $(TAILWIND_BIN)
|
||||||
|
$(TAILWIND_BIN) -c tailwind.config.js -i static/css/input.css -o static/css/tailwind.css --minify
|
||||||
|
|
||||||
|
# Regenerate templ Go from the .templ sources.
|
||||||
|
generate:
|
||||||
|
$(TEMPL) generate
|
||||||
|
|
||||||
|
build: generate css
|
||||||
|
go build -o veola-bin .
|
||||||
|
|
||||||
|
run: build
|
||||||
|
./veola-bin -config config.toml
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test ./...
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f veola-bin
|
||||||
6
static/css/input.css
Normal file
6
static/css/input.css
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/* Tailwind entry point. Compiled by the standalone CLI into tailwind.css:
|
||||||
|
see the Makefile `css` target. The hand-written Veola component layer
|
||||||
|
lives in app.css and is loaded separately, so editing it needs no rebuild. */
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
2
static/css/tailwind.css
Normal file
2
static/css/tailwind.css
Normal file
File diff suppressed because one or more lines are too long
13
tailwind.config.js
Normal file
13
tailwind.config.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
// Scans the .templ sources for utility classes. Custom v-* component classes
|
||||||
|
// live in static/css/app.css, not here, so they need no safelisting. If a
|
||||||
|
// utility class is ever built dynamically in Go rather than written as a
|
||||||
|
// literal in a template, add it to `safelist` below.
|
||||||
|
module.exports = {
|
||||||
|
content: ["./templates/**/*.templ"],
|
||||||
|
safelist: [],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
@@ -18,10 +18,10 @@ templ head(title string) {
|
|||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<title>{ title } · Veola</title>
|
<title>{ title } · Veola</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com"/>
|
<link rel="preconnect" href="https://fonts.googleapis.com"/>
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"/>
|
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"/>
|
||||||
|
<link rel="stylesheet" href="/static/css/tailwind.css"/>
|
||||||
<link rel="stylesheet" href="/static/css/app.css"/>
|
<link rel="stylesheet" href="/static/css/app.css"/>
|
||||||
<script src="/static/vendor/htmx.min.js" defer></script>
|
<script src="/static/vendor/htmx.min.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func head(title string) templ.Component {
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " · Veola</title><script src=\"https://cdn.tailwindcss.com\"></script><link rel=\"preconnect\" href=\"https://fonts.googleapis.com\"><link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin><link href=\"https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap\" rel=\"stylesheet\"><link rel=\"stylesheet\" href=\"/static/css/app.css\"><script src=\"/static/vendor/htmx.min.js\" defer></script></head>")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " · Veola</title><link rel=\"preconnect\" href=\"https://fonts.googleapis.com\"><link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin><link href=\"https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap\" rel=\"stylesheet\"><link rel=\"stylesheet\" href=\"/static/css/tailwind.css\"><link rel=\"stylesheet\" href=\"/static/css/app.css\"><script src=\"/static/vendor/htmx.min.js\" defer></script></head>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user