编写具有 Web Assembly 依赖项的 Typescript 库?

Writing a Typescript Library with a Web Assembly Dependency?

我正计划编写一个用于分发的打字稿库,这将取决于 cephes

为了在浏览器中使用 web 程序集,我们必须像这样编译它:

const cephes = require('cephes'); // Browser
await cephes.compiled;

我不确定如何为包装 cephes 的 Typescript 库实现这一点。

例如,库将提供可以像这样导入的 NormalDistribution:

import { NormalDistrbution } from 'cephesdistributions';

如果我们进行 tree shaking,那么 NormalDistribution 可能是包中唯一包含的导入。因此,我们是否需要在 cephesdistributions 提供的所有模块中包含 await cephes.compiled

我认为你应该尽可能直截了当。由于您的消费者无法真正绕过 await,我建议您将其留给您的消费者 await cephes.compiled

如果您要捆绑 cephes,您可能希望从您的图书馆中 re-export cephes.compiled 以便您的消费者可以直接使用您的图书馆:

const cephes = require('cephes');

export const compiled = cephes.compiled;

export class NormalDistribution {
  public mean: number;
  public sd: number;

  constructor(mean = 0, sd = 1) {
    this.mean = mean;
    this.sd = 1;
  }

  cdf(x: number): number {
    // If this gets called before someone has `await`:ed `compiled`
    // there will be trouble.
    return cephes.ndtr(x);
  }
}

这意味着您导出的 类 的类型将立即可用,即使过早调用它们会崩溃。由于您的消费者与您一样依赖 cephes.compiled 的解析,因此您可以考虑在适当的地方存储编译状态和 "guarding"。例如,

const cephes = require('cephes');

let isCompiled = false;
export function assertIsCompiled() {
  if (isCompiled) {
    return;
  }

  throw new Error('You must wait for `cephesdistributions.compiled` to resolve');
}

export const compiled = cephes.compiled.then(() => { isCompiled = true });

export class NormalDistribution {
  public mean: number;
  public sd: number;

  constructor(mean = 0, sd = 1) {
    assertIsCompiled();

    this.mean = mean;
    this.sd = 1;
  }

  cdf(x: number): number {
    return cephes.ndtr(x);
  }
}