Initial add backend stuff
This commit is contained in:
91
bundler/css.go
Normal file
91
bundler/css.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package bundler
|
||||
|
||||
// CSS pipeline: compiles the Tailwind entry stylesheet (frontend/css/style.css)
|
||||
// with the native Go Tailwind v4 engine (tailwind.go — twCompile/scanSources, no
|
||||
// goja), feeding it the utility-class candidates scanned from source files, then
|
||||
// minifies via tdewolff/minify. style.css is the single entry/config for both
|
||||
// bundles — they differ only in which source files are scanned for candidates.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/tdewolff/minify/v2"
|
||||
mincss "github.com/tdewolff/minify/v2/css"
|
||||
)
|
||||
|
||||
// Tailwind source patterns - configured here rather than in CSS so each bundle
|
||||
// scans only the files it actually needs. The scanner filters by the suffix of
|
||||
// each pattern, so separate entries are needed for .js and .ts source files.
|
||||
var twSourcesSPA = []string{
|
||||
"../src/**/*.js",
|
||||
"../src/**/*.ts",
|
||||
"../src/**/*.jsx",
|
||||
"../src/**/*.tsx",
|
||||
"../../internal/handlers/templates/**/*.html",
|
||||
}
|
||||
var twSourcesPublic = []string{
|
||||
"../../internal/handlers/templates/**/*.html",
|
||||
// Public pages authored as Solid components in .tsx (SSR'd via goja).
|
||||
"../src/pages/public/**/*.tsx",
|
||||
"../src/pages/public/**/*.jsx",
|
||||
"../src/pages/public/**/*.ts",
|
||||
"../src/pages/public/**/*.js",
|
||||
// Shared UI component library. If a public page renders any ui/ component
|
||||
// (data tables, tabs, icons, etc.), its classes must be in this bundle too,
|
||||
// so scan the whole library rather than just the env badge / layout.
|
||||
"../src/ui/**/*.ts",
|
||||
"../src/ui/**/*.js",
|
||||
}
|
||||
|
||||
// styleEntry is the Tailwind entry/config, relative to frontendDir. Both the SPA
|
||||
// and public bundles compile it; include.css (a former one-line passthrough) is gone.
|
||||
const styleEntry = "css/style.css"
|
||||
|
||||
var m *minify.M
|
||||
|
||||
func init() {
|
||||
m = minify.New()
|
||||
m.AddFunc("text/css", mincss.Minify)
|
||||
}
|
||||
|
||||
func bundleSPACSS() (bundleStats, error) {
|
||||
return compileCSSBundle("SPA", twSourcesSPA, "bundle.min.css")
|
||||
}
|
||||
|
||||
func bundlePublicCSS() (bundleStats, error) {
|
||||
return compileCSSBundle("public", twSourcesPublic, "public.bundle.min.css")
|
||||
}
|
||||
|
||||
// compileCSSBundle scans twSources for candidates, compiles style.css with the
|
||||
// official Tailwind compiler, minifies, and writes outName to wwwroot. It prints
|
||||
// a timing line for the Tailwind step so the compile can be profiled.
|
||||
func compileCSSBundle(label string, twSources []string, outName string) (bundleStats, error) {
|
||||
entryPath := filepath.Join(frontendDir, styleEntry)
|
||||
src, err := os.ReadFile(entryPath)
|
||||
if err != nil {
|
||||
return bundleStats{}, fmt.Errorf("reading %s: %w", styleEntry, err)
|
||||
}
|
||||
cssDir := filepath.Dir(entryPath)
|
||||
|
||||
candidates := scanSources(cssDir, twSources)
|
||||
|
||||
compiled, count, err := twCompile(string(src), cssDir, candidates)
|
||||
if err != nil {
|
||||
return bundleStats{}, fmt.Errorf("tailwind compile (%s): %w", label, err)
|
||||
}
|
||||
fmt.Printf(" Tailwind (%s): %d candidates, %d utilities compiled\n",
|
||||
label, len(candidates), count)
|
||||
|
||||
minified, err := m.String("text/css", compiled)
|
||||
if err != nil {
|
||||
return bundleStats{}, fmt.Errorf("minifying %s CSS: %w", label, err)
|
||||
}
|
||||
|
||||
outPath := filepath.Join(outputDir, outName)
|
||||
if err := os.WriteFile(outPath, []byte(minified), 0644); err != nil {
|
||||
return bundleStats{}, err
|
||||
}
|
||||
return bundleStats{files: len(candidates), bytes: len(minified)}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user