Maison  >  Article  >  développement back-end  >  Le moteur de modèles de Go « templ » est pratique (il fonctionne également avec TinyGo)

Le moteur de modèles de Go « templ » est pratique (il fonctionne également avec TinyGo)

Barbara Streisand
Barbara Streisandoriginal
2024-10-30 20:31:30999parcourir

Synopsis

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.

Aller au texte/modèle

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.

Texte/modèle TinyGo

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

Oups !

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.

MODÈLE

Je cherchais donc un autre moteur de modèle pour remplacer le texte/modèle et je suis tombé sur templ.

Go a-h / modèle

Un langage pour écrire des interfaces utilisateur HTML dans Go.

Go

Un langage de création de modèles HTML pour Go doté d'excellents outils de développement.

Go

Documentation

Voir la documentation utilisateur sur https://templ.guide

Go Go Go Go

Tâches

construire

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
Entrez en mode plein écran Quitter le mode plein écran

nix-update-gomod2nix

❯ 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
Entrez en mode plein écran Quitter le mode plein écran

instantané d'installation

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
Entrez en mode plein écran Quitter le mode plein écran

instantané de construction

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
Entrez en mode plein écran Quitter le mode plein écran

générer

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
Entrez en mode plein écran Quitter le mode plein écran

tester

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
Entrez en mode plein écran Quitter le mode plein écran

test-court

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
Entrez en mode plein écran Quitter le mode plein écran

test-couverture

Courir…


Voir sur GitHub


Caractéristiques

Voici un résumé de TEMPL.

Posséder un DSL

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.

Extensions VSCode

https://marketplace.visualstudio.com/items?itemName=a-h.templ

La surbrillance de la syntaxe et la complétion LSP seront très utiles.

Modèle TinyGo

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn