Discourse 主题组件现已支持 Wasm 🎊

WebAssembly (Wasm) 是一项在所有现代浏览器中都支持的技术,它允许开发者发布可移植的二进制程序。

这意味着开发者可以使用几乎任何编程语言来定位 Web。

在 Discourse 的上下文中,这为发布一套相当丰富的扩展打开了大门,而这些扩展在过去只能由插件创建者使用。

例如:

  • 图像水印/调整大小/裁剪
  • 使用 graphviz 或 svgbob 生成图表
  • 编程沙箱(例如:嵌入 Ruby 运行时的帖子)
  • 以及更多

过去,由于 Discourse 的 Content Security Policy,Wasm 的访问被关闭,除非安装了本地上传且没有 CDN。

在客户端添加了新的接口,以支持在主题中发布 JavaScript 资源,这些资源可以通过本地域无条件访问。

这使得主题开发者能够干净地托管 Wasm,流程是:

组件 → 本地 Web Worker → CDN 上托管的 Wasm

Discourse svgbob 是新模式的端到端示例,关键的 2 个更改是:

  1. 所有 .js 资源也可以在本地服务器的 CDN 之外访问:
{
...
  "assets": {
    "worker": "assets/will-be-avilable-on-local.js"
  }
}
  1. 本地资源的 URL 可以通过 settings.theme_uploads_local 访问

因此,在上面的示例中:

settings.theme_uploads_local.worker; // 本地资源
settings.theme_uploads.worker; // CDN 资源
36 个赞

这与 wasm 无关,但我发现了这段代码中另一个有趣的地方,它是新的吗?

在您的示例中,loadScript 不再需要了?(我认为导入是多余的吗?):

而是当发现 worker 不存在时,才即时加载 worker 脚本?

使用从 asset 引用构建的 URL。

这是一个很好的模式,非常有帮助!

但是,我有一个关于 worker 的问题。

如果我使用第三方 worker 脚本,并且该脚本包含 importScripts() 语句(https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts)来将其他脚本包含到 worker 的全局作用域中,我该如何将这些脚本包含在主题组件中进行导入?

我可能想问的是:如何在 Discourse 主题组件中从 URL 请求脚本?

2 个赞

在此场景中,我使用了主 JS 脚本中的 postMessage 来传递要导入的 URL。这会在 worker 上的消息处理程序中接收,该处理程序可以 importScript 接收到的 URL。

2 个赞

谢谢你,拉斐尔!你有什么开源示例可以参考吗?

2 个赞

我在核心中使用了相同的模式

6 个赞

我正在使用 theme creator 来创建一个新的主题组件,该组件应该使用 wasm。作为起点,我尝试上传 svgbob 作为主题组件。但是,不允许我这样做,因为它包含一个 wasm 文件。

这是主题创建者有意为之的限制吗?还是我不能直接安装 svgbob?

2 个赞

我怀疑我们只是在主题创建者那里遇到了文件类型限制,需要解除。

3 个赞

我已经将 themecreator 重置为使用默认的“theme authorized extensions”,其中包括 WASM。所以现在应该可以了,@Heinenen

(不确定为什么它会处于非默认设置……也许过去缺少了某个常用扩展名 :man_shrugging:

2 个赞

是的,非常棒,我可以确认现在可以正常工作了。谢谢!

3 个赞

好的,看来我得稍微往回退一点,我认为它还没有完美运行。
我再次尝试上传 svgbob,这次成功了。

现在我也尝试上传了我自己的 wasm 文件,该文件来自 MDN,我收到了错误:
发生错误:您向请求提供了无效参数:字符串包含空字节

在我的开发容器中,这不是问题,我可以毫无问题地上传同一个文件。

2 个赞

从网站上运行二进制文件不应该是一种需要谨慎选择的安全风险吗?这可能是它不是默认设置的原因。你怎么看,@Roman

1 个赞

主题默认允许。只是 discourse.theme-creator.io 上的站点设置已被更改。(这是一个常规的 discourse 站点,有一个插件允许任何人上传和共享主题)。

WASM 仍由浏览器进行沙盒化处理,因此安全隐患等同于 .js 文件。

4 个赞