在 Svelte 中导入 emscripten 生成的模块

Import emscripten generated module in Svelte

我正在尝试制作一个包含 canvas 的 Svelte 组件,它将在内部显示 emscripten 编译的 webgl 应用程序。 在传统的 html 中,它需要以下设置:

<script>
  var canv = document.getElementById('canvas');
  var Module = { canvas: canv };
</script>
<script src="index.js"></src>

我最接近它的是这些:

<script>
  let canv;
  let Module = { canvas: canv };
</script>

<svelte:head>
  <script src="index.js"></src>
</svelte:head>

<canvas bind:this={canv}></canvas>

确实加载了模块,但 index.js 初始化失败并出现一些错误:

exception thrown: TypeError: eventHandler.target is null,registerOrRemoveHandler

这基本上是 index.js 看不到 Module - 如果我根本不初始化 Module,这个错误仍然相同。

我知道我可以使用 MODULARIZE 编译器选项(我还没有研究它)但是因为它是一个 webgl 应用程序,我更愿意让它 运行像传统 html 一样加载,这样我就可以专注于 C++,而无需自己设置管道。

正确的做法是什么?

这里发生了几件事。

首先,一个组件相当于一个JavaScript模块,这意味着在组件内部声明的任何变量都是该组件的本地变量。如果您需要 Module 在全球范围内可用,您应该将其设置为 window:

window.Module = { canvas: canv };

其次,任何时候使用 bind:this,您都需要等待组件实际安装。组件 <script> 中的代码在创建任何 DOM 之前运行(因为它通常 决定 创建什么 DOM)。

在这种情况下,请尝试使用 onMount:

<script>
  import { onMount } from 'svelte';

  let canv;

  onMount(() => {
    window.Module = { canvas: canv };
  });
</script>

<svelte:head>
  <script src="index.js"></src>
</svelte:head>

<canvas bind:this={canv}></canvas>