概要
我想在 Go 中运行一个返回纯 HTML 的应用程序,
我决定使用 Cloudflare Workers,它可以将其转换为 Wasm 并部署它。
我推荐 sumai/workers 的模板,用于将 Go 应用程序部署到 Cloudflare Workers。
sumai/workers:Go 包以在 Cloudflare Workers 上运行 HTTP 服务器。
转到文本/模板
首先,让我们以简单的方式使用文本/模板进行构建。
❯ 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
差不多 8 MB。
https://developers.cloudflare.com/workers/platform/limits/#account-plan-limits
Cloudflare Workers 根据计划有工作人员大小限制。
免费插槽为1MB,付费插槽($5~)为10MB。
即使有基于压缩后大小的最终限制,也很难满足从 8MB 开始的免费配额。
TinyGo 文本/模板
所以我决定切换到 TinyGo,它应该是为 WebAssembly (Wasm) 设计的。
构建后,大小约为 0.75 MB,似乎适合免费框架。
❯ 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
哎呀!
但这就是悲剧发生的地方。
当我尝试访问构建的应用程序时,出现错误。
[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()
在 template.ExecuteTemplate() 中传递模板变量时调用的方法 MethodByName 尚未实现。
由于 TinyGo 是原始版本的子集,因此有许多不支持的功能,
我发现文本/模板正在调用不受支持的方法。
https://github.com/tinygo-org/tinygo/blob/1154212c15e6e97048e122068730dab5a1a9427f/src/reflect/type.go#L1086-L1088
现在,我想冷静地为 TinyGo 说声好话,但这一次我要寻找一个快速的替代方案。
TEMPL
所以我正在寻找另一个模板引擎来替换文本/模板,并遇到了templ。
啊
/
寺庙
一种用 Go 编写 HTML 用户界面的语言。
Go 的 HTML 模板语言,具有出色的开发人员工具。
文档
请参阅 https://templ.guide 上的用户文档
任务
构建
构建本地版本。
❯ 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
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
安装快照
构建并安装当前版本。
❯ 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
构建快照
使用 goreleaser 使用 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
生成
使用本地版本运行 templ generated。
❯ 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 测试。
❯ 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 测试。
❯ 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
测试封面
跑…
特征
这是 TEMPL 的摘要。
自己的DSL
编写一个独特的程序并不难,但是可以像 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
看起来很熟悉的写作风格。
❯ 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
使用它时,您可以逐个组件地调用由 templ generated 从 DSL 生成的 Go 函数。
[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
生成的组件的函数继承了模板中定义的参数类型,因此可以安全地调用。
与某些 ExecuteTemplate 不同,这是安全的。
VSCode 扩展
https://marketplace.visualstudio.com/items?itemName=a-h.templ
语法突出显示和 LSP 补全将非常有用。
TinyGo 寺庙
为了确定,我查了一下,发现它只依赖于reflect的TypeOf,它已经在TinyGo中实现了。
https://github.com/tinygo-org/tinygo/blob/1154212c15e6e97048e122068730dab5a1a9427f/src/reflect/type.go#L494-L500
现在让我们尝试使用 templ。
该建筑似乎有足够的空间。
gomod2nix
这是实际应用。
goworkers-demo.ergofriend.workers.dev
访问时可以正常返回HTML。
<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
最终部署的大小也是187.91 KiB,因此有足够的空间来扩展应用程序。
此验证保留在此存储库中。
ergofriend/goworkers-demo
本文是日文翻译。
https://ergofriend.hatenablog.com/entry/2024/08/08/230603
以上是Go 的模板引擎'templ”很方便(它也适用于 TinyGo)的详细内容。更多信息请关注PHP中文网其他相关文章!

Go的"strings"包提供了丰富的功能,使字符串操作高效且简单。1)使用strings.Contains()检查子串。2)strings.Split()可用于解析数据,但需谨慎使用以避免性能问题。3)strings.Join()适用于格式化字符串,但对小数据集,循环使用 =更有效。4)对于大字符串,使用strings.Builder构建字符串更高效。

Go语言使用"strings"包进行字符串操作。1)拼接字符串使用strings.Join函数。2)查找子串使用strings.Contains函数。3)替换字符串使用strings.Replace函数,这些函数高效且易用,适用于各种字符串处理任务。

资助bytespackageingoisesential foreffited byteSemanipulation,uperingFunctionsLikeContains,index,andReplaceForsearchingangingAndModifyingBinaryData.itenHancesperformanceNandCoderAceAnibility,MakeitiTavitalToolToolToolToolToolToolToolToolToolForhandLingBinaryData,networkProtocols,networkProtocoLss,networkProtocols,andetFilei

Go语言使用"encoding/binary"包进行二进制编码与解码。1)该包提供binary.Write和binary.Read函数,用于数据的写入和读取。2)需要注意选择正确的字节序(如BigEndian或LittleEndian)。3)数据对齐和错误处理也是关键,确保数据的正确性和性能。

1)usebybytes.joinforconcatenatinges,2)bytes.bufferforincrementalWriter,3)bytes.indexorbytes.indexorbytes.indexbyteforsearching bytes.bytes.readereforrednerncretinging.isnchunk.ss.ind.inc.softes.4)

theencoding/binarypackageingoiseforporptimizingBinaryBinaryOperationsDuetoitssupportforendiannessessandefficityDatahandling.toenhancePerformance:1)usebinary.nativeendiandiandiandiandiandiandiandian nessideendian toavoid avoidByteByteswapping.2)

Go的bytes包主要用于高效处理字节切片。1)使用bytes.Buffer可以高效进行字符串拼接,避免不必要的内存分配。2)bytes.Equal函数用于快速比较字节切片。3)bytes.Index、bytes.Split和bytes.ReplaceAll函数可用于搜索和操作字节切片,但需注意性能问题。

字节包提供了多种功能来高效处理字节切片。1)使用bytes.Contains检查字节序列。2)用bytes.Split分割字节切片。3)通过bytes.Replace替换字节序列。4)用bytes.Join连接多个字节切片。5)利用bytes.Buffer构建数据。6)结合bytes.Map进行错误处理和数据验证。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

禅工作室 13.0.1
功能强大的PHP集成开发环境

SublimeText3 英文版
推荐:为Win版本,支持代码提示!