2

labor:首个开源 web container 实现

 3 years ago
source link: https://zhuanlan.zhihu.com/p/374943737
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

labor:首个开源 web container 实现

✅跪在床上娇喘,❎隔着网线叫唤

啊啊啊啊啊!惊天地,泣鬼神!小爷我!终于特么搞定了!

四天前,stackblitz 在谷歌大会提出了一个新的 idea,那就是 web container

stackblitz/webcontainer-core

然后马上,大家纷纷研究,这玩意到底是怎么实现的?

当天我就有了一个大概的思路,马上写了一个小 demo,但是发现有破绽

后来才发现,之前把重点放在 js 侧是错误的,什么文件系统,TCP 协议栈,这些东西都和 js 没有任何关系

接下来我来介绍一下主要思路

code => service worker(js runtime) => go wasm API

首先可以肯定的是,我们的 node 代码,必须得有个 js runtime 的,这个 runtime 就是 service worker,然后最终调用的 API 则是 go wasm 实现的

const res = readFileSync('a.js')

这段代码,一定要在 worker 中执行

new Function('readFile', `const res = readFileSync('a.js')`)(readFile)

是的,你没看错,readFile 是 go 注入过来的

js.Global().Set("readFile", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
    readFile(args[0].String())
    return nil
}))

啊这,就是这么简单……

stackblitz 有所不同的是,它用的不是 go,而是直接用的 node 的实现,也就是 cpp 的实现

我可能不可能去编译 cpp 的代码的,所以我会把这些标准库 API 用 go 实现一遍

之所以使用 go 写,一方面是我比较熟悉,另一方面是因为 docker 也用的 go

但值得一提的是,go 变异成 wasm 后 GC 是不会共享堆内存的,不存在当初 deno 的困扰

但也牺牲了性能……tinygo 也许还能扳回一局

双 worker 同构

很多人不理解为什么我对 web container 这么重视,它看上去花里胡哨的,似乎没什么前途

但如果和其他技术结合看,就不一样了

我年初想在公司搞 trip worker,类似于 cloudflare worker,就是在 server 端造一个 js runtime,因为我觉得这是 serverless 的绝美形态

但是你想过没有,cloudflare worker 你怎么本地调试呢?

labor 就是答案

这种开发环境走 service worker 进行开发调试,生产环境走 trip worker 的组合,真的不能更美好了

所以当我看到 web container 的时候,我就知道这是我想要的,尽管所有人都在围观

好在终于有了思路了!

trip worker 也是一个 js runtime,它总体架构和 deno 比较像,我会用 rust 实现,但好在标准不多,go 和 rust 实现两套也没什么压力

总结

写这么多,但其实还差得远,目前只是跑通了 http 而已,欢迎大家有兴趣一起交流实现

也欢迎 pr 和 star 鸭!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK