用 goja 承载业务回调,让业务逻辑变更不必重新编译发布 Go 程序。脚本用
ESM + TypeScript 写,Go 侧按名字把它们当普通对象实例化并调用方法。
主要组成:
- Engine 编译脚本、管配置,公开 API 不暴露任何 goja 类型
- Script 一份编译好的脚本 + 它的 VM 池,热更新时整体顶替
- Instance 独占一个 VM 的实例,状态留在 JS 侧
- Caller 自定义调用约定,把脚本函数适配成 Go 侧要的签名
- Scope 让同一个 ctx 下的多个脚本共享 Go 侧对象
- Extension 扩展接口:给脚本添全局对象,配套 TS 类型
- Overlay 多层 Loader 叠加,后面的盖前面的
几个关键取舍:
- 源码一律先过 esbuild 打包成 ESM,再改写成立即执行函数。goja 不认
import/export,而业务脚本要能拆文件、用 TypeScript。
- VM 池化复用,但每个 VM 单线程。goja 的 Runtime 不是 goroutine 安全的。
- Go 侧函数返回的 error 在脚本里表现为抛异常,不占返回值位置。
- 脚本能看见的全局只有白名单放行的那些,且注入是惰性的——没读到的
全局根本不会被转换。
17 lines
429 B
AMPL
17 lines
429 B
AMPL
module git.fsdpf.net/go/jscriptx
|
|
|
|
go 1.25.5
|
|
|
|
require (
|
|
github.com/dop251/goja v0.0.0-20260826204918-8f1c0696a37b
|
|
github.com/evanw/esbuild v0.28.2
|
|
)
|
|
|
|
require (
|
|
github.com/dlclark/regexp2/v2 v2.5.2 // indirect
|
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
|
|
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
|
|
golang.org/x/sys v0.46.0 // indirect
|
|
golang.org/x/text v0.39.0 // indirect
|
|
)
|