概览
提供以 JavaScript 源文件和WebAssembly 组件作为输入的 Mozilla SpiderMankey 嵌入 WIT 世界协会, (中文(简体) ), 产出a 网络大会组件 具有相同接口的二进制.
说明:这是一个实验性项目,没有为稳定或支持提供保障,今后可能发生突破性变化.
示例
见端到端工作流程 创建联署材料组件并在Wasmtime或Node.js运行。 。 。 .
解释器
关于所涉概念的背景,见A/CN.9/WG.III/WP.III/WP.48 https://bytecodealliance.org/articles/making-javascript-run-fast-on-webassembly 互联网档案馆的存檔,存档日期2013-12-02。 。 。 .
这个项目的具体目标是提供一个全面的动态绑定系统来从JavaScript创建任意的WebAssembly组件. 也就是说,为由此产生的联合来文环境和世界信息传输组织提供充分的灵活性.
Wizer 启动前化
适应遵循标准 Wizer技术 在初始化前对源和绑定的运行时间进行快照.
抓取进程执行JS引擎初始化,全球并解析和编译出源代码. 目前我们还评估源的顶级,以便提供已执行的顶级ES模块的出口.
因此,在运行时间——只有字节码被执行,没有任何初始化成本. 这使得Wasm按要求处决JS的速度惊人快.
蜘蛛猴嵌入
作为带有奇特语的动态语言,JavaScript不能直接被编译为字节码,而不包含一个全面的ECMA-262光谱兼容运行时引擎. 因此,JavaScript的组件化涉及将JS运行时引擎嵌入组件本身.
SpiderMonkey在此被选为JS引擎,拥有一流的WASI构建支持,使用嵌入式的 星灵蒙克瓦斯姆引擎。嵌入总大小约为8MB.
组件模型的安全好处之一是除了组件之间的共享-无码边界之外,完全的代码隔离. 通过完全封装每个单个组件的嵌入引擎,这保持了每个组件的全面隔离.
由于更多组件被写入JavaScript中,并且存在多个JS组件在同一应用程序中通信的情景,因此这里的优化计划是在它们之间共享嵌入的SpiderMonkey引擎. 通过让引擎本身作为组件的共享库加载,可以不突破共享-无语义. 通过相同的 SpiderMankey 构建共享函数,而不是内存 .
因此,将这个最初的原型作为单一的灵活引擎基础,可以变成一个共享库,是这个项目的重点.
Weval AOT 汇编
韦瓦尔 超时(AOT)编译可以通过预编译JavaScript内置缓存来提高运行时的性能.
为了实现AOT汇编,设置 enableAot: true 选项或使用 --aot CLI旗.
AOT 汇编还可以配置以下选项:
| 选项 | 类型 | 示例 | 说明 |
|---|---|---|---|
aotMinStackSizeBytes | 数量 | 数目 | 二进制 |
自定义 weval aOT 二进制
使用自定义( 预下载) weval 二进制,设置 wevalBin 选项.
平台 APIs
现有以下API:
- 遗产编码数字 :
atob, (中文(简体) ),btoa, (中文(简体) ),decodeURI, (中文(简体) ),encodeURI, (中文(简体) ),decodeURIComponent, (中文(简体) ),encodeURIComponent - 流线数字 :
ReadableStream, (中文(简体) ),ReadableStreamBYOBReader, (中文(简体) ),ReadableStreamBYOBRequest, (中文(简体) ),ReadableStreamDefaultReader, (中文(简体) ),ReadableStreamDefaultController, (中文(简体) ),ReadableByteStreamController, (中文(简体) ),WritableStreamByteLengthQueuingStrategyCountQueuingStrategy, (中文(简体) ),TransformStream - 網址数字 :
URL, (中文(简体) ),URLSearchParams - 控制台数字 :
console - 业绩数字 :
Performance - 任务数字 :
queueMicrotask, (中文(简体) ),setIntervalsetTimeoutclearIntervalclearTimeout - 地点数字 :
WorkerLocation, (中文(简体) ),location - 编码数字 :
TextEncoder, (中文(简体) ),TextDecoder, (中文(简体) ),CompressionStream, (中文(简体) ),DecompressionStream - 结构化克隆数字 :
structuredClone - 获取数字 :
fetch, (中文(简体) ),Request, (中文(简体) ),Response, (中文(简体) ),Headers - 窗体、文件和块数字 :
FormData, (中文(简体) ),MultipartFormData, (中文(简体) ),File, (中文(简体) ),Blob - 密码数字 :
SubtleCrypto, (中文(简体) ),Crypto, (中文(简体) ),crypto, (中文(简体) ),CryptoKey - 中止数字 :
AbortController, (中文(简体) ),AbortSignal
使用量
安装和运行为节点.js库 :
npm install @bytecodealliance/componentize-js
import { componentize } from '@bytecodealliance/componentize-js';
import { writeFile } from 'node:fs/promises';
const { component } = await componentize(`
import { log } from 'local:hello/logger';
export function sayHello (name) {
log(\`Hello \${name}\`);
}
`, `
package local:hello;
interface logger {
log: func(msg: string);
}
world hello {
import logger;
export say-hello: func(name: string);
}
`);
await writeFile('test.component.wasm', component);
见 类型.d.ts 用于完整的接口选项.
组件本身可以在任何组件运行时间执行,参见 实例 在Wasmtime结束工作流程.
自定义 wizer 二进制
使用自定义( 预下载) wizer 二进制,设置 wizerBin 选项.
同步支持
为了支持同步操作,所有功能可以选择被写成同步或sync函数,尽管它们总是会变成同步组件函数.
例如,用于 fetch 需要 async 调用, 我们可以使用 async 函数写入相同的示例组件 :
export async function sayHello (name) {
const text = await (await fetch(`http://localhost:8080/${name}`)).text();
console.log(text);
}
整合JS将自动解决通过功能返回的保证,以同步返回值,在JS组件内运行事件循环到解析.
此同步只为导出函数所支持 - 导入的函数只能是同步的,等待组件- 模型级的同位素支持.
国 际
集成JS可直接用作CLI,也可通过 jco componentize 命令 :
直接使用
npm install -g @bytecodealliance/componentize-js
示例
componentize-js --wit wit -o component.wasm source.js
见 jco componentize --help 更多细节.
通过 jco componentize
npm install -g @bytecodealliance/jco @bytecodealliance/componentize-js
示例
jco componentize source.js --wit wit -o component.wasm
见 jco componentize --help 更多细节.
特征
根据目标世界和预期能力,可以对发动机中的一组启用功能进行定制.
默认的一组特性包括:
'stdio': 向 stderr 和 stdout 输出错误和控制台记录,取决于wasi:cli财务报告和审定财务报表wasi:io。 。 。 .'random': 支持密码随机, 取决于wasi:random。 。 。 . 被禁用时,随机数仍然会生成,但不会是随机的,而是会完全确定.'clocks':支持计时和持续时间投票,取决于wasi:clocks财务报告和审定财务报表wasi:io。 。 。 . 当禁用时,使用任何定时器功能如设置Timeout或设置Interval会惊慌.'http': 通过fetch在《联合提交的材料》中.'fetch-event'页:1fetch基于收到的请求处理(即.addEventListener('fetch', ...)(中文(简体) )
设置 disableFeatures: ['random', 'stdio', 'clocks', 'http', 'fetch-event'] 将禁用所有创建最小“ 纯” 组件的特性, 而该组件完全不依赖于任何 WASI API , 也仅依赖于目标世界 .
注意纯组件 将不报告错误,而是陷阱,因此只有在经过非常仔细的测试后才能启用.
注意目标世界明确进口的特性不能被禁用 -- -- 如果你将某一部件瞄准一个进口的世界 wasi:clocks,则 disableFeatures: ['clocks'] 将不支持.
请注意,根据组件执行情况,某些功能可能自动被禁用。 例如,如果使用
wasi:http/incoming-handler 手动 fetch-event 无法使用.
使用 StarlingMonkey 软件 fetch-event
StarlingMonkey引擎提供了使用能力 fetchEvent 处理呼叫 wasi:http/[email protected]#handle。 。 。 .
瞄准输出世界时 wasi:http/[email protected] 获取事件将自动附加。 或者,
用自定义处理器来覆盖获取事件,导出一个明示 incomingHandler 或者说 'wasi:http/[email protected]'
对象。 使用 fetchEvent 要求启用 http 特性.
[尖叫声] 如果使用
fetch-event,确保您 别 手动导入( 即导出)incomingHandler从你的ES模块.导出模块
incomingHandler拥有http启用的特性被假定为正在使用wasi:http手动.
API 密码
export function componentize(opts: {
/**
* The path to the file to componentize.
*
* This file must be a valid JavaScript module, and can import other modules using relative paths.
*/
sourcePath: string;
/**
* Path to WIT file or folder
*/
witPath?: string;
/**
* Target world name for componentization
*/
worldName?: string;
/**
* Path to custom ComponentizeJS engine build to use
*/
engine?: string;
/**
* Path to custom weval cache to use
*/
aotCache?: string;
/**
* Enable AoT using weval
*/
enableAot?: boolean;
/**
* Use a pre-existing path to the `weval` binary, if present
*/
wevalBin?: string;
/**
* Use a pre-existing path to the `wizer` binary, if present
*/
wizerBin?: string;
/**
* Path to custom Preview2 Adapter
*/
preview2Adapter?: string;
/**
* Disable WASI features in the base engine
* Disabling all features results in a pure component with no WASI dependence
*
* - stdio: console.log(), console.error and errors are provided to stderr
* - random: Math.random() and crypto.randomBytes()
* - clocks: Date.now(), performance.now()
* - http: fetch() support
*
*/
disableFeatures?: ('stdio' | 'random' | 'clocks' | 'http' | 'fetch-event')[];
/**
* Enable WASI features in the base engine
* (no experimental subsystems currently supported)
*/
enableFeatures?: [];
/**
* Pass environment variables to the spawned Wizer or Weval Process
* If set to true, all host environment variables are passed
* To pass only a subset, provide an object with the desired variables
*/
env?: boolean | Record<string, string>;
/**
* Runtime arguments to provide to the StarlingMonkey engine initialization
* (see https://github.com/bytecodealliance/StarlingMonkey/blob/main/include/config-parser.h)
*/
runtimeArgs?: string;
/**
* Use a debug build
* Note that the debug build only includes the names section only for size optimization, and not DWARF
* debugging sections, due to a lack of support in Node.js for these debugging workflows currently.
*/
debugBuild?: boolean;
/**
* Debug options
*/
debug?: {
/** Whether to enable bindings-specific debugging */
bindings?: boolean;
/** Path to debug bindings to use */
bindingsDir?: string;
/** Whether to enable binary-specific debugging */
binary?: boolean;
/** Path to enable binary-specific debugging */
binaryPath?: string;
/** Whether to enable wizer logging */
wizerLogging: false;
}
}): Promise<{
/**
* Component binary
*/
component: Uint8Array;
/**
* Used guest imports in JavaScript (excluding those from StarlingMonkey engine)
*/
imports: [[string, string]][];
/**
* Debugging output (only present if enabled)
*/
debug?: {
/** Whether bindings debugging was enabled */
bindings?: boolean;
/** Work directory used during processing */
workDir?: string;
/** Whether binary debugging was enabled */
binary?: boolean;
/** Path to the produced binary */
binaryPath?: string;
};
}>
将 JS 源转换为组件 二进制 .
导入只提供已使用的来宾进口清单,而StarlingMonkey引擎可能拉入更多 进口。 直接组成部分分析应用来正确推断实际进口清单.
捐款
为了捐款,你需要设立以下机构:
git submodule update --init --recursive用于更新子模块.- 稳定地用
wasm32-unknown-unknown财务报告和审定财务报表wasm32-wasi目标 已安装. wasi-sdk-20.0安装于/opt/wasi-sdk/
大楼
建立和测试项目可通过国家预防机制的脚本进行(见 package.json:
npm install
npm run build
在能够使用之前 componentize-js 在AOT支持下(例如通过) npm link从 jco),你需要运行:
npm run build:weval
(单位:千美元)npm run build 也会执行 weval 建筑)
这会产生 lib/starlingmonkey_embedding_weval.wasm 财务报告和审定财务报表 lib/starlingmonkey_ics.wevalcache。 。 。 .
清理本地安装( 即去除 StarlingMonkey 的安装):
npm run clean
测试
进行所有测试:
npm run test
使用 AOT( Weval) 进行测试:
npm run test:weval
运行特定测试
要运行一个特定的测试套房,你可以传递一个参数给 vitest数字 :
npm run test -- test/wasi.js
许可证
这个项目根据Apache 2.0许可证获得许可,LLVM例外. 见 自由主义 更多细节.
捐款
除非您另有明确声明,否则有意提交的任何捐款 根据Apache-2.0许可证的定义, 应照此办理,不附加任何条件.