Maison > Article > développement back-end > Le moteur de modèles de Go « templ » est pratique (il fonctionne également avec TinyGo)
Je voulais exécuter une application dans Go qui renvoyait du HTML brut,
J'ai décidé d'utiliser Cloudflare Workers, qui peut le convertir en Wasm et le déployer.
Je recommande le modèle syumai/workers pour déployer des applications Go sur Cloudflare Workers.
syumai/workers : package Go pour exécuter un serveur HTTP sur Cloudflare Workers.
Tout d'abord, construisons en utilisant du texte/un modèle de manière simple.
❯ 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
C'était presque 8 Mo.
https://developers.cloudflare.com/workers/platform/limits/#account-plan-limits
Cloudflare Workers a des limites de taille de travailleur en fonction du plan.
L'emplacement gratuit est de 1 Mo et l'emplacement payant (5 $~) est de 10 Mo.
Même avec la limite finale basée sur la taille après compression, il sera difficile de respecter le quota gratuit à partir de 8 Mo.
J'ai donc décidé de passer à TinyGo, qui est censé être destiné à WebAssembly (Wasm).
Après construction, la taille est d'environ 0,75 Mo, ce qui semble rentrer dans le cadre libre.
❯ 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
Mais c'est ici que la tragédie frappe.
Lorsque j'essaie d'accéder à l'application construite, j'obtiens une erreur.
[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()
La méthode MethodByName, qui est appelée lorsqu'une variable de modèle est passée dans template.ExecuteTemplate(), n'est pas encore implémentée.
Étant donné que TinyGo est un sous-ensemble de l'original, de nombreuses fonctionnalités ne sont pas prises en charge,
J'ai découvert que le texte/modèle appelait des méthodes non prises en charge.
https://github.com/tinygo-org/tinygo/blob/1154212c15e6e97048e122068730dab5a1a9427f/src/reflect/type.go#L1086-L1088
Maintenant, j'aimerais être cool et dire p-r pour TinyGo, mais cette fois je vais chercher une alternative rapide.
Je cherchais donc un autre moteur de modèle pour remplacer le texte/modèle et je suis tombé sur templ.
Voir la documentation utilisateur sur https://templ.guide
Créez une version locale.
❯ 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
Construisez et installez la version actuelle.
❯ 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
Utilisez goreleaser pour créer le binaire de ligne de commande à l'aide de goreleaser.
❯ 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
Exécutez templ generate en utilisant la version locale.
❯ 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
Exécutez des tests Go.
❯ 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
Exécutez des tests Go.
❯ 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
Courir…
Voici un résumé de TEMPL.
Il n'est pas difficile d'écrire un programme unique, mais il peut être écrit comme templ ≈ Go JSX.
❯ 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
Cela ressemble à un style d'écriture très familier.
❯ 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
Lorsque vous l'utilisez, vous appelez les fonctions Go générées à partir du DSL par templ generate composant par composant.
[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
La fonction du composant généré hérite des types d'arguments définis dans le modèle, elle peut donc être appelée en toute sécurité.
Contrairement à certains ExecuteTemplate, ceci est sûr.
https://marketplace.visualstudio.com/items?itemName=a-h.templ
La surbrillance de la syntaxe et la complétion LSP seront très utiles.
Juste pour être sûr, j'ai vérifié et constaté que cela ne dépend que du TypeOf de Reflect, qui est déjà implémenté dans TinyGo.
https://github.com/tinygo-org/tinygo/blob/1154212c15e6e97048e122068730dab5a1a9427f/src/reflect/type.go#L494-L500
Essayons maintenant d'utiliser templ.
La construction semblait avoir suffisamment de place.
gomod2nix
Voici l'application réelle.
goworkers-demo.ergofriend.workers.dev
Lors de l'accès, le code HTML peut être renvoyé sans erreur.
<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
La taille finale déployée est également de 187,91 Ko, il y a donc beaucoup de place pour étendre l'application.
Cette vérification est laissée dans ce référentiel.
ergofriend/goworkers-démo
Cet article est une traduction du japonais.
https://ergofriend.hatenablog.com/entry/2024/08/08/230603
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!