plugin struct

Methods:

Name


Returns:
  • string

Show/Hide Method Body
{ return "bundler" }

Priority


Returns:
  • int

Show/Hide Method Body
{ return 10 }

PostBuild


Parameters:
  • raw json.RawMessage

Returns:
  • error

Show/Hide Method Body
{
	if utils.IsDebug() {
		log.Printf("bundler: skipped in debug mode")
		return nil
	}

	m := minify.New()
	m.AddFunc("text/javascript", js.Minify)
	m.AddFunc("text/css", css.Minify)
	m.AddFunc("text/html", html.Minify)

	buildDir := "build"
	if err := filepath.Walk(buildDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		ext := filepath.Ext(path)
		var media string
		switch ext {
		case ".js":
			media = "text/javascript"
		case ".css":
			if isTailwindCSS(path) {
				log.Printf("bundler: skipping tailwind css %s", path)
				return nil
			}
			media = "text/css"
		case ".html":
			media = "text/html"
		default:
			return nil
		}
		data, err := os.ReadFile(path)
		if err != nil {
			return err
		}
		out, err := m.Bytes(media, data)
		if err != nil {
			return err
		}
		if err := os.WriteFile(path, out, 0o644); err != nil {
			return err
		}
		return nil
	}); err != nil {
		return err
	}
	log.Printf("bundler: build complete")
	return nil
}

ShouldRebuild


Parameters:
  • path string

Returns:
  • bool

Show/Hide Method Body
{
	path = filepath.ToSlash(path)
	if strings.HasPrefix(path, "build/") {
		return false
	}
	return strings.HasSuffix(path, ".js") || strings.HasSuffix(path, ".css") || strings.HasSuffix(path, ".html")
}

init function

Show/Hide Function Body
{ plugins.Register(&plugin{}) }

isTailwindCSS function

Parameters:

  • path string

Returns:

  • bool
Show/Hide Function Body
{
	data, err := os.ReadFile(path)
	if err != nil {
		return false
	}
	src := string(data)
	return strings.Contains(src, "@tailwind") || strings.Contains(src, "tailwindcss")
}

TestShouldRebuild function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	p := &plugin{}
	if !p.ShouldRebuild("main.js") {
		t.Fatalf("expected js change to trigger rebuild")
	}
	if !p.ShouldRebuild("styles.css") {
		t.Fatalf("expected css change to trigger rebuild")
	}
	if !p.ShouldRebuild("index.html") {
		t.Fatalf("expected html change to trigger rebuild")
	}
	if p.ShouldRebuild(filepath.Join("build", "app.js")) {
		t.Fatalf("output directory should not trigger rebuild")
	}
	if p.ShouldRebuild("image.png") {
		t.Fatalf("unrelated files should not trigger rebuild")
	}
}

TestIsTailwindCSS function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	dir := t.TempDir()
	tw := filepath.Join(dir, "input.css")
	if err := os.WriteFile(tw, []byte("@import \"tailwindcss\";"), 0o644); err != nil {
		t.Fatalf("write tailwind file: %v", err)
	}
	if !isTailwindCSS(tw) {
		t.Fatalf("expected tailwind directives to be detected")
	}

	normal := filepath.Join(dir, "normal.css")
	if err := os.WriteFile(normal, []byte("body{}"), 0o644); err != nil {
		t.Fatalf("write normal file: %v", err)
	}
	if isTailwindCSS(normal) {
		t.Fatalf("unexpected tailwind detection in normal css")
	}
}

TestPostBuildMinifiesFiles function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	dir := t.TempDir()
	buildDir := filepath.Join(dir, "build", "static")
	if err := os.MkdirAll(buildDir, 0o755); err != nil {
		t.Fatalf("mkdir build: %v", err)
	}

	jsFile := filepath.Join(buildDir, "app.js")
	if err := os.WriteFile(jsFile, []byte("function add ( a , b ){ return a + b ; }"), 0o644); err != nil {
		t.Fatalf("write js: %v", err)
	}
	cssFile := filepath.Join(buildDir, "app.css")
	if err := os.WriteFile(cssFile, []byte("body { color: red; }"), 0o644); err != nil {
		t.Fatalf("write css: %v", err)
	}
	htmlFile := filepath.Join(buildDir, "index.html")
	html := "<html><head><title> hi </title></head><body> <h1> hi </h1> </body></html>"
	if err := os.WriteFile(htmlFile, []byte(html), 0o644); err != nil {
		t.Fatalf("write html: %v", err)
	}

	wd, _ := os.Getwd()
	defer os.Chdir(wd)
	if err := os.Chdir(dir); err != nil {
		t.Fatalf("chdir: %v", err)
	}

	utils.EnableDebug(false)

	p := &plugin{}
	if err := p.PostBuild(nil); err != nil {
		t.Fatalf("postbuild: %v", err)
	}

	outJS, _ := os.ReadFile(jsFile)
	if len(outJS) >= len("function add ( a , b ){ return a + b ; }") {
		t.Fatalf("js not minified: %s", outJS)
	}
	outCSS, _ := os.ReadFile(cssFile)
	if len(outCSS) >= len("body { color: red; }") {
		t.Fatalf("css not minified: %s", outCSS)
	}
	outHTML, _ := os.ReadFile(htmlFile)
	if len(outHTML) >= len(html) {
		t.Fatalf("html not minified: %s", outHTML)
	}
}

TestPostBuildSkippedInDebug function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	dir := t.TempDir()
	buildDir := filepath.Join(dir, "build", "static")
	if err := os.MkdirAll(buildDir, 0o755); err != nil {
		t.Fatalf("mkdir build: %v", err)
	}

	jsFile := filepath.Join(buildDir, "app.js")
	content := "function add ( a , b ){ return a + b ; }"
	if err := os.WriteFile(jsFile, []byte(content), 0o644); err != nil {
		t.Fatalf("write js: %v", err)
	}

	wd, _ := os.Getwd()
	defer os.Chdir(wd)
	if err := os.Chdir(dir); err != nil {
		t.Fatalf("chdir: %v", err)
	}

	utils.EnableDebug(true)
	defer utils.EnableDebug(false)

	p := &plugin{}
	if err := p.PostBuild(nil); err != nil {
		t.Fatalf("postbuild: %v", err)
	}

	out, _ := os.ReadFile(jsFile)
	if string(out) != content {
		t.Fatalf("file should remain unminified, got %s", out)
	}
}

encoding/json import

Import example:

import "encoding/json"

log import

Import example:

import "log"

os import

Import example:

import "os"

path/filepath import

Import example:

import "path/filepath"

strings import

Import example:

import "strings"

github.com/rfwlab/rfw/cmd/rfw/plugins import

Import example:

import "github.com/rfwlab/rfw/cmd/rfw/plugins"

github.com/rfwlab/rfw/cmd/rfw/utils import

Import example:

import "github.com/rfwlab/rfw/cmd/rfw/utils"

github.com/tdewolff/minify/v2 import

Import example:

import "github.com/tdewolff/minify/v2"

github.com/tdewolff/minify/v2/css import

Import example:

import "github.com/tdewolff/minify/v2/css"

github.com/tdewolff/minify/v2/html import

Import example:

import "github.com/tdewolff/minify/v2/html"

github.com/tdewolff/minify/v2/js import

Import example:

import "github.com/tdewolff/minify/v2/js"

os import

Import example:

import "os"

path/filepath import

Import example:

import "path/filepath"

testing import

Import example:

import "testing"

github.com/rfwlab/rfw/cmd/rfw/utils import

Import example:

import "github.com/rfwlab/rfw/cmd/rfw/utils"