Node.js v25.0.0 文档
- Node.js v25.0.0
- 目录
-
索引
- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲区
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入器 API
- 子进程
- 集群
- 命令行选项
- 控制台
- 加密
- 调试器
- 已弃用的 API
- 诊断通道
- DNS
- 域
- 环境变量
- 错误
- 事件
- 文件系统
- 全局对象
- HTTP
- HTTP/2
- HTTPS
- 检查器
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:module
API - 模块:包
- 模块:TypeScript
- 网络
- 操作系统
- 路径
- 性能钩子
- 权限
- 进程
- Punycode
- 查询字符串
- 逐行读取
- REPL
- 报告
- 单一可执行文件应用
- SQLite
- 流
- 字符串解码器
- 测试运行器
- 定时器
- TLS/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用工具
- V8
- 虚拟机
- WASI
- Web Crypto API
- Web Streams API
- 工作线程
- Zlib
- 其他版本
- 选项
WebAssembly 系统接口 (WASI)#
node:wasi
模块目前不提供某些 WASI 运行时所提供的全面文件系统安全属性。未来可能会也可能不会实现对安全文件系统沙箱的完全支持。在此期间,请勿依赖它来运行不受信任的代码。
源代码: lib/wasi.js
WASI API 提供了 WebAssembly 系统接口规范的实现。WASI 通过一组类 POSIX 函数,让 WebAssembly 应用程序能够访问底层操作系统。
import { readFile } from 'node:fs/promises';
import { WASI } from 'node:wasi';
import { argv, env } from 'node:process';
const wasi = new WASI({
version: 'preview1',
args: argv,
env,
preopens: {
'/local': '/some/real/path/that/wasm/can/access',
},
});
const wasm = await WebAssembly.compile(
await readFile(new URL('./demo.wasm', import.meta.url)),
);
const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());
wasi.start(instance);
'use strict';
const { readFile } = require('node:fs/promises');
const { WASI } = require('node:wasi');
const { argv, env } = require('node:process');
const { join } = require('node:path');
const wasi = new WASI({
version: 'preview1',
args: argv,
env,
preopens: {
'/local': '/some/real/path/that/wasm/can/access',
},
});
(async () => {
const wasm = await WebAssembly.compile(
await readFile(join(__dirname, 'demo.wasm')),
);
const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());
wasi.start(instance);
})();
要运行上面的示例,请创建一个名为 demo.wat
的新 WebAssembly 文本格式文件。
(module
;; Import the required fd_write WASI function which will write the given io vectors to stdout
;; The function signature for fd_write is:
;; (File Descriptor, *iovs, iovs_len, nwritten) -> Returns number of bytes written
(import "wasi_snapshot_preview1" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32)))
(memory 1)
(export "memory" (memory 0))
;; Write 'hello world\n' to memory at an offset of 8 bytes
;; Note the trailing newline which is required for the text to appear
(data (i32.const 8) "hello world\n")
(func $main (export "_start")
;; Creating a new io vector within linear memory
(i32.store (i32.const 0) (i32.const 8)) ;; iov.iov_base - This is a pointer to the start of the 'hello world\n' string
(i32.store (i32.const 4) (i32.const 12)) ;; iov.iov_len - The length of the 'hello world\n' string
(call $fd_write
(i32.const 1) ;; file_descriptor - 1 for stdout
(i32.const 0) ;; *iovs - The pointer to the iov array, which is stored at memory location 0
(i32.const 1) ;; iovs_len - We're printing 1 string stored in an iov - so one.
(i32.const 20) ;; nwritten - A place in memory to store the number of bytes written
)
drop ;; Discard the number of bytes written from the top of the stack
)
)
使用 wabt 将 .wat
编译为 .wasm
。
wat2wasm demo.wat
安全#
WASI 提供了一个基于能力(capabilities-based)的模型,通过该模型为应用程序提供其自定义的 env
、preopens
、stdin
、stdout
、stderr
和 exit
能力。
Node.js 当前的威胁模型不像某些 WASI 运行时那样提供安全的沙箱环境。
虽然支持这些能力特性,但它们在 Node.js 中并不构成一个安全模型。例如,文件系统沙箱可以通过各种技术被绕过。该项目正在探索未来是否可以添加这些安全保证。
类: WASI
#
WASI
类提供了 WASI 系统调用 API 以及用于处理基于 WASI 的应用程序的附加便利方法。每个 WASI
实例代表一个独立的环境。
new WASI([options])
#
options
<Object>args
<Array> 一个字符串数组,WebAssembly 应用程序会将其视为命令行参数。第一个参数是 WASI 命令本身的虚拟路径。默认值:[]
。env
<Object> 一个类似于process.env
的对象,WebAssembly 应用程序会将其视为其环境。默认值:{}
。preopens
<Object> 此对象表示 WebAssembly 应用程序的本地目录结构。preopens
的字符串键被视为文件系统内的目录。preopens
中相应的值是这些目录在主机上的真实路径。returnOnExit
<boolean> 默认情况下,当 WASI 应用程序调用__wasi_proc_exit()
时,wasi.start()
会返回指定的退出码,而不是终止进程。将此选项设置为false
将导致 Node.js 进程以指定的退出码退出。默认值:true
。stdin
<integer> 在 WebAssembly 应用程序中用作标准输入的文件描述符。默认值:0
。stdout
<integer> 在 WebAssembly 应用程序中用作标准输出的文件描述符。默认值:1
。stderr
<integer> 在 WebAssembly 应用程序中用作标准错误的文件描述符。默认值:2
。version
<string> 请求的 WASI 版本。目前唯一支持的版本是unstable
和preview1
。此选项是必需的。
wasi.getImportObject()
#
返回一个导入对象,如果除了 WASI 提供的导入之外不需要其他 WASM 导入,则可以将其传递给 WebAssembly.instantiate()
。
如果版本 unstable
被传入构造函数,它将返回
{ wasi_unstable: wasi.wasiImport }
如果版本 preview1
被传入构造函数,或者没有指定版本,它将返回
{ wasi_snapshot_preview1: wasi.wasiImport }
wasi.start(instance)
#
instance
<WebAssembly.Instance>
尝试通过调用 instance
的 _start()
导出来开始执行该实例作为 WASI 命令。如果 instance
不包含 _start()
导出,或者如果 instance
包含 _initialize()
导出,则会抛出异常。
start()
要求 instance
导出一个名为 memory
的 WebAssembly.Memory
。如果 instance
没有 memory
导出,则会抛出异常。
如果 start()
被调用多次,则会抛出异常。
wasi.initialize(instance)
#
instance
<WebAssembly.Instance>
尝试通过调用 instance
的 _initialize()
导出来将其初始化为 WASI 反应器(reactor),如果该导出存在的话。如果 instance
包含 _start()
导出,则会抛出异常。
initialize()
要求 instance
导出一个名为 memory
的 WebAssembly.Memory
。如果 instance
没有 memory
导出,则会抛出异常。
如果 initialize()
被调用多次,则会抛出异常。
wasi.finalizeBindings(instance[, options])
#
instance
<WebAssembly.Instance>options
<Object>memory
<WebAssembly.Memory> 默认值:instance.exports.memory
。
在不调用 initialize()
或 start()
的情况下,为 instance
设置 WASI 主机绑定。当 WASI 模块在子线程中实例化以在线程间共享内存时,此方法非常有用。
finalizeBindings()
要求 instance
导出一个名为 memory
的 WebAssembly.Memory
,或者用户在 options.memory
中指定一个 WebAssembly.Memory
对象。如果 memory
无效,则会抛出异常。
start()
和 initialize()
会在内部调用 finalizeBindings()
。如果 finalizeBindings()
被调用多次,则会抛出异常。
wasi.wasiImport
#
- 类型:<Object>
wasiImport
是一个实现 WASI 系统调用 API 的对象。在实例化 WebAssembly.Instance
期间,应将此对象作为 wasi_snapshot_preview1
导入来传递。