Heim > Artikel > Backend-Entwicklung > Gos Template-Engine „templ“ ist praktisch (funktioniert auch mit TinyGo)
Ich wollte eine Anwendung in Go ausführen, die einfaches HTML zurückgibt,
Ich habe mich für Cloudflare Workers entschieden, die es in Wasm konvertieren und bereitstellen können.
Ich empfehle die Vorlage von syumai/workers für die Bereitstellung von Go-Anwendungen für Cloudflare Workers.
syumai/workers: Go-Paket zum Ausführen eines HTTP-Servers auf Cloudflare Workers.
Lassen Sie uns zunächst auf unkomplizierte Weise mit Text/Vorlage erstellen.
❯ ls -lh . /build total 15656 -rwxr-xr-x 1 ergofriend staff 7.6M 8 8 20:12 app.wasm -rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:12 shim.mjs -rw-r--r-- 1 ergofriend staff 16K 8 8 20:12 wasm_exec.js -rw-r--r-- 1 ergofriend staff 160B 8 8 20:12 worker.mjs
Es waren fast 8 MB.
https://developers.cloudflare.com/workers/platform/limits/#account-plan-limits
Cloudflare Workers hat je nach Plan Beschränkungen für die Worker-Größe.
Der kostenlose Slot ist 1 MB groß und der kostenpflichtige Slot ($5~) ist 10 MB groß.
Selbst mit der endgültigen Beschränkung basierend auf der Größe nach der Komprimierung wird es schwierig sein, in das kostenlose Kontingent ab 8 MB zu passen.
Also habe ich beschlossen, zu TinyGo zu wechseln, das für WebAssembly (Wasm) gedacht ist.
Nach dem Erstellen beträgt die Größe etwa 0,75 MB, was in den freien Rahmen zu passen scheint.
❯ ls -lh . /build total 1160 -rwxr-xr-x 1 ergofriend staff 556K 8 8 20:23 app.wasm -rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:23 shim.mjs -rw-r--r-- 1 ergofriend staff 15K 8 8 20:23 wasm_exec.js -rw-r--r-- 1 ergofriend staff 160B 8 8 20:23 worker.mjs
Aber hier kommt es zur Tragödie.
Wenn ich versuche, auf die erstellte Anwendung zuzugreifen, erhalte ich eine Fehlermeldung.
[wrangler:inf] GET / 200 OK (35ms) ✘ [ERROR] Uncaught (in response) RuntimeError: unreachable at main.runtime._panic (wasm://wasm/main-0022bc46:wasm-function[35]:0x2b4a) at main.(*text/template.state).evalField (wasm://wasm/main-0022bc46:wasm-function[540]:0x6c5f4) at main.(*text/template.state).evalFieldChain (wasm://wasm/main-0022bc46:wasm-function[531]:0x697fe) at main.(*text/template.state).evalFieldNode (wasm://wasm/main-0022bc46:wasm-function[530]:0x6959a) at main.(*text/template.state).evalPipeline (wasm://wasm/main-0022bc46:wasm-function[535]:0x6a1d2) at main.(*text/template.state).walk (wasm://wasm/main-0022bc46:wasm-function[569]:0x72cdd) at main.(*text/template.state).walk (wasm://wasm/main-0022bc46:wasm-function[569]:0x730b0) at main.main (wasm://wasm/main-0022bc46:wasm-function[261]:0x2ac52) at main.(net/http.HandlerFunc).ServeHTTP (wasm://wasm/main-0022bc46:wasm-function[463]:0x5973a) at main.interface:{ServeHTTP:func:{named:net/http.ResponseWriter,pointer:named:net/http.Request}{}}.ServeHTTP$invoke (wasm://wasm/main-0022bc46:wasm-function[459]:0x56f72) panic: unimplemented: (reflect.Value).MethodByName()
Die Methode MethodByName, die aufgerufen wird, wenn eine Vorlagenvariable in template.ExecuteTemplate() übergeben wird, ist noch nicht vorhanden. Sie scheint nicht implementiert zu sein.
Da TinyGo eine Teilmenge des Originals ist, gibt es viele nicht unterstützte Funktionen
Ich habe festgestellt, dass Text/Vorlage nicht unterstützte Methoden aufruft.
https://github.com/tinygo-org/tinygo/blob/1154212c15e6e97048e122068730dab5a1a9427f/src/reflect/type.go#L1086-L1088
Jetzt würde ich gerne cool sein und P-R für TinyGo sagen, aber dieses Mal werde ich nach einer schnellen Alternative suchen.
Also suchte ich nach einer anderen Template-Engine als Ersatz für Text/Vorlage und stieß auf templ.
Siehe Benutzerdokumentation unter https://templ.guide
Erstellen Sie eine lokale Version.
❯ ls -lh . /build
total 15656
-rwxr-xr-x 1 ergofriend staff 7.6M 8 8 20:12 app.wasm
-rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:12 shim.mjs
-rw-r--r-- 1 ergofriend staff 16K 8 8 20:12 wasm_exec.js
-rw-r--r-- 1 ergofriend staff 160B 8 8 20:12 worker.mjs
❯ ls -lh . /build
total 15656
-rwxr-xr-x 1 ergofriend staff 7.6M 8 8 20:12 app.wasm
-rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:12 shim.mjs
-rw-r--r-- 1 ergofriend staff 16K 8 8 20:12 wasm_exec.js
-rw-r--r-- 1 ergofriend staff 160B 8 8 20:12 worker.mjs
Erstellen und installieren Sie die aktuelle Version.
❯ ls -lh . /build
total 1160
-rwxr-xr-x 1 ergofriend staff 556K 8 8 20:23 app.wasm
-rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:23 shim.mjs
-rw-r--r-- 1 ergofriend staff 15K 8 8 20:23 wasm_exec.js
-rw-r--r-- 1 ergofriend staff 160B 8 8 20:23 worker.mjs
Verwenden Sie goreleaser, um die Befehlszeilen-Binärdatei mit goreleaser zu erstellen.
❯ ls -lh . /build
total 15656
-rwxr-xr-x 1 ergofriend staff 7.6M 8 8 20:12 app.wasm
-rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:12 shim.mjs
-rw-r--r-- 1 ergofriend staff 16K 8 8 20:12 wasm_exec.js
-rw-r--r-- 1 ergofriend staff 160B 8 8 20:12 worker.mjs
Templ-Generierung mit lokaler Version ausführen.
❯ ls -lh . /build
total 1160
-rwxr-xr-x 1 ergofriend staff 556K 8 8 20:23 app.wasm
-rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:23 shim.mjs
-rw-r--r-- 1 ergofriend staff 15K 8 8 20:23 wasm_exec.js
-rw-r--r-- 1 ergofriend staff 160B 8 8 20:23 worker.mjs
Go-Tests durchführen.
❯ ls -lh . /build
total 15656
-rwxr-xr-x 1 ergofriend staff 7.6M 8 8 20:12 app.wasm
-rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:12 shim.mjs
-rw-r--r-- 1 ergofriend staff 16K 8 8 20:12 wasm_exec.js
-rw-r--r-- 1 ergofriend staff 160B 8 8 20:12 worker.mjs
Go-Tests durchführen.
❯ ls -lh . /build
total 1160
-rwxr-xr-x 1 ergofriend staff 556K 8 8 20:23 app.wasm
-rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:23 shim.mjs
-rw-r--r-- 1 ergofriend staff 15K 8 8 20:23 wasm_exec.js
-rw-r--r-- 1 ergofriend staff 160B 8 8 20:23 worker.mjs
Lauf…
Hier ist eine Zusammenfassung von TEMPL.
Es ist nicht schwer, ein einzigartiges Programm zu schreiben, aber es kann wie templ ≈ Go JSX geschrieben werden.
❯ ls -lh . /build total 15656 -rwxr-xr-x 1 ergofriend staff 7.6M 8 8 20:12 app.wasm -rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:12 shim.mjs -rw-r--r-- 1 ergofriend staff 16K 8 8 20:12 wasm_exec.js -rw-r--r-- 1 ergofriend staff 160B 8 8 20:12 worker.mjs
Es sieht aus wie ein sehr vertrauter Schreibstil.
❯ ls -lh . /build total 1160 -rwxr-xr-x 1 ergofriend staff 556K 8 8 20:23 app.wasm -rw-r--r-- 1 ergofriend staff 1.2K 8 8 20:23 shim.mjs -rw-r--r-- 1 ergofriend staff 15K 8 8 20:23 wasm_exec.js -rw-r--r-- 1 ergofriend staff 160B 8 8 20:23 worker.mjs
Wenn Sie es verwenden, rufen Sie Go-Funktionen auf, die aus dem DSL von templ generiert werden, und zwar auf einer Komponenten-für-Komponenten-Basis.
[wrangler:inf] GET / 200 OK (35ms) ✘ [ERROR] Uncaught (in response) RuntimeError: unreachable at main.runtime._panic (wasm://wasm/main-0022bc46:wasm-function[35]:0x2b4a) at main.(*text/template.state).evalField (wasm://wasm/main-0022bc46:wasm-function[540]:0x6c5f4) at main.(*text/template.state).evalFieldChain (wasm://wasm/main-0022bc46:wasm-function[531]:0x697fe) at main.(*text/template.state).evalFieldNode (wasm://wasm/main-0022bc46:wasm-function[530]:0x6959a) at main.(*text/template.state).evalPipeline (wasm://wasm/main-0022bc46:wasm-function[535]:0x6a1d2) at main.(*text/template.state).walk (wasm://wasm/main-0022bc46:wasm-function[569]:0x72cdd) at main.(*text/template.state).walk (wasm://wasm/main-0022bc46:wasm-function[569]:0x730b0) at main.main (wasm://wasm/main-0022bc46:wasm-function[261]:0x2ac52) at main.(net/http.HandlerFunc).ServeHTTP (wasm://wasm/main-0022bc46:wasm-function[463]:0x5973a) at main.interface:{ServeHTTP:func:{named:net/http.ResponseWriter,pointer:named:net/http.Request}{}}.ServeHTTP$invoke (wasm://wasm/main-0022bc46:wasm-function[459]:0x56f72) panic: unimplemented: (reflect.Value).MethodByName()
go run ./get-version > .version cd cmd/templ go build
Die Funktion der generierten Komponente erbt die in der Vorlage definierten Argumenttypen, sodass sie sicher aufgerufen werden kann.
Im Gegensatz zu einigen ExecuteTemplates ist dies sicher.
https://marketplace.visualstudio.com/items?itemName=a-h.templ
Syntax-Highlight und LSP-Vervollständigung werden sehr nützlich sein.
Zur Sicherheit habe ich nachgesehen und festgestellt, dass es nur vom TypeOf von Reflect abhängt, das bereits in TinyGo implementiert ist.
https://github.com/tinygo-org/tinygo/blob/1154212c15e6e97048e122068730dab5a1a9427f/src/reflect/type.go#L494-L500
Nun versuchen wir es mit templ.
Der Bau schien genug Platz zu haben.
gomod2nix
Hier ist die eigentliche Anwendung.
goworkers-demo.ergofriend.workers.dev
Beim Zugriff kann der HTML-Code ohne Fehler zurückgegeben werden.
<span class="pl-c"># Remove templ from the non-standard ~/bin/templ path</span> <span class="pl-c"># that this command previously used.</span> rm -f ~/bin/templ <span class="pl-c"># Clear LSP logs.</span> rm -f cmd/templ/lspcmd/*.txt <span class="pl-c"># Update version.</span> go run ./get-version > .version <span class="pl-c"># Install to $GOPATH/bin or $HOME/go/bin</span> cd cmd/templ && go install
Die endgültige bereitgestellte Größe beträgt ebenfalls 187,91 KiB, sodass genügend Platz zum Erweitern der Anwendung vorhanden ist.
Diese Überprüfung verbleibt in diesem Repository.
ergofriend/goworkers-demo
Dieser Artikel ist eine Übersetzung aus dem Japanischen.
https://ergofriend.hatenablog.com/entry/2024/08/08/230603
Das obige ist der detaillierte Inhalt vonGos Template-Engine „templ“ ist praktisch (funktioniert auch mit TinyGo). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!