Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Enjin templat Go "templ" adalah mudah (ia juga berfungsi dengan TinyGo)

Enjin templat Go "templ" adalah mudah (ia juga berfungsi dengan TinyGo)

Barbara Streisand
Barbara Streisandasal
2024-10-30 20:31:301003semak imbas

Sinopsis

Saya mahu menjalankan aplikasi dalam Go yang mengembalikan HTML biasa,
Saya memutuskan untuk menggunakan Cloudflare Workers, yang boleh menukarnya kepada Wasm dan menggunakannya.

Saya mengesyorkan templat syumai/workers untuk menggunakan aplikasi Go ke Cloudflare Workers.

syumai/workers: Pergi pakej untuk menjalankan pelayan HTTP pada Cloudflare Workers.

Pergi teks/templat

Mula-mula, mari kita bina menggunakan teks/templat dengan cara yang mudah.

❯ 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

Hampir 8 MB.

https://developers.cloudflare.com/workers/platform/limits/#account-plan-limits

Pekerja Cloudflare mempunyai had saiz pekerja bergantung pada pelan.

Slot percuma ialah 1MB, dan slot berbayar ($5~) ialah 10MB.

Walaupun dengan had akhir berdasarkan saiz selepas pemampatan, ia akan menjadi sukar untuk dimasukkan ke dalam kuota percuma bermula pada 8MB.

Teks/templat TinyGo

Jadi saya memutuskan untuk beralih kepada TinyGo, yang sepatutnya untuk WebAssembly (Wasm).

Selepas dibina, saiznya adalah kira-kira 0.75 MB, yang nampaknya sesuai dengan bingkai percuma.

❯ 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

Aduh!

Tetapi di sinilah tragedi berlaku.

Apabila saya cuba mengakses aplikasi terbina, saya mendapat ralat.

[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()

Kaedah MethodByName, yang dipanggil apabila pembolehubah templat dihantar dalam templat.ExecuteTemplate(), masih belum. Nampaknya tidak dilaksanakan.

Memandangkan TinyGo ialah subset daripada yang asal, terdapat banyak ciri yang tidak disokong,
Saya mendapati bahawa teks/templat sedang memanggil kaedah yang tidak disokong.

https://github.com/tinygo-org/tinygo/blob/1154212c15e6e97048e122068730dab5a1a9427f/src/reflect/type.go#L1086-L1088

Sekarang, saya ingin bersikap tenang dan berkata p-r untuk TinyGo, tetapi kali ini saya akan mencari alternatif yang cepat.

TEMPL

Jadi saya sedang mencari enjin templat lain untuk menggantikan teks/templat dan terjumpa templ.

Go a-h / templ

Bahasa untuk menulis antara muka pengguna HTML dalam Go.

Go

Bahasa templat HTML untuk Go yang mempunyai alatan pembangun yang hebat.

Go

Dokumentasi

Lihat dokumentasi pengguna di https://templ.guide

Go Go Go Go

Tugas

bina

Bina versi tempatan.

❯ 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
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

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
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

pasang-snapshot

Bina dan pasang versi semasa.

❯ 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
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

bina-snapshot

Gunakan goreleaser untuk membina binari baris arahan menggunakan 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
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

menjana

Jalankan templ generate menggunakan versi tempatan.

❯ 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
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

ujian

Jalankan ujian 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
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

pendek ujian

Jalankan ujian 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
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

kulit ujian

Lari…


Lihat di GitHub


Ciri-ciri

Berikut ialah ringkasan TEMPL.

DSL sendiri

Tidak sukar untuk menulis atur cara yang unik, tetapi ia boleh ditulis seperti 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

Ia kelihatan seperti gaya penulisan yang sangat dikenali.

❯ 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

Apabila anda menggunakannya, anda memanggil fungsi Go yang dijana daripada DSL oleh templ generate berdasarkan komponen demi komponen.

[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

Fungsi komponen yang dijana mewarisi jenis argumen yang ditakrifkan dalam templat, jadi ia boleh dipanggil dengan selamat.
Tidak seperti sesetengah ExecuteTemplate, ini selamat.

Sambungan VSCode

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

Sorotan Sintaks dan pelengkapan LSP akan sangat berguna.

TinyGo templ

Hanya untuk memastikan, saya menyemak dan mendapati ia hanya bergantung pada TypeOf reflect, yang sudah dilaksanakan dalam TinyGo.

https://github.com/tinygo-org/tinygo/blob/1154212c15e6e97048e122068730dab5a1a9427f/src/reflect/type.go#L494-L500

Sekarang mari cuba gunakan templ.
Binaan itu nampaknya mempunyai ruang yang mencukupi.

gomod2nix

Berikut ialah aplikasi sebenar.

goworkers-demo.ergofriend.workers.dev

Apabila diakses, HTML boleh dikembalikan tanpa ralat.

<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

Saiz penggunaan terakhir juga ialah 187.91 KiB, jadi terdapat banyak ruang untuk mengembangkan aplikasi.

Pengesahan ini ditinggalkan dalam repositori ini.
ergofriend/goworkers-demo


Artikel ini adalah terjemahan daripada bahasa Jepun.
https://ergofriend.hatenablog.com/entry/2024/08/08/230603

Atas ialah kandungan terperinci Enjin templat Go "templ" adalah mudah (ia juga berfungsi dengan TinyGo). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn