Node.js v26.0.0 說明文件
- Node.js v26.0.0
- 目錄
- 索引
- 關於此說明文件
- 用法與範例
- 斷言測試
- 非同步內容追蹤
- Async hooks
- Buffer
- C++ 擴充套件
- 使用 Node-API 的 C/C++ 擴充套件
- C++ 嵌入器 API
- 子程序
- 叢集
- 命令列選項
- Console
- Crypto
- 除錯器
- 棄用的 API
- Diagnostics Channel
- DNS
- 網域 (Domain)
- 環境變數
- 錯誤
- 事件
- 檔案系統
- 全域變數
- HTTP
- HTTP/2
- HTTPS
- 檢查器
- 國際化
- 模組:CommonJS 模組
- 模組:ECMAScript 模組
- 模組:
node:moduleAPI - 模組:套件
- 模組:TypeScript
- Net
- Iterable Streams API
- OS
- Path
- 效能勾子 (Performance hooks)
- 權限
- 程序
- Punycode
- 查詢字串
- Readline
- REPL
- 報告
- 單一可執行應用程式
- SQLite
- Stream
- 字串解碼器
- 測試執行器
- 計時器
- TLS/SSL
- 追蹤事件
- TTY
- UDP/資料報
- URL
- 公用工具
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- 工作執行緒
- Zlib
- Zlib 可反覆運算壓縮
- 其他版本
- 選項
WebAssembly 系統介面 (WASI)#
穩定性:1 - 實驗性
node:wasi 模組目前並未提供某些 WASI 執行環境所具備的全面性檔案系統安全性屬性。未來可能會實作,也可能不會實作對安全檔案系統沙盒的完整支援。在此同時,請勿依賴它來執行不可信的程式碼。
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。如果 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() 的情況下,設定 WASI 主機繫結至 instance。當 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 匯入傳遞。