OneScript

Node.js 兼容性

Node.js 特性支持状态与使用限制一览。

OneScript 的脚本运行在 WKWebView 中。通过 Node.js polyfill,尽可能模拟 Node.js 运行时的 API 与行为。兼容基线为 Node.js v24.21.0。

各项特性的支持范围如下。

Node.js 特性支持状态备注
assert / assert/strict支持直接使用 Node.js v24.21.0 的 lib/assert.js 源码,包括差异输出、CallTracker、部分深度比较。能读取源码行时,assert(value) 的错误信息会引用出错表达式。
buffer支持使用 Node.js v24.21.0 的 lib/buffer.js 源码与移植的原生 binding:全部编码、数值读写方法、transcode、isUtf8、isAscii、atob / btoa。由官方 test-buffer-* 测试覆盖(见官方测试基线)。
Blob / File / FormData部分支持复用 WebKit 原生实现,支持文件、表单、原生 Blob.stream() 和流消费;较早系统通过 arrayBuffer() 补齐 bytes()。具体行为随系统 WebKit 版本变化。
fetch部分支持复用原生 Web 对象,HTTP(S) 通过 URLSession 跨域传输。支持响应流、SSE、显式 ReadableStream 上传和进行中的取消;普通请求体经原生编码取得 Content-Length,重放副本保存在内存中。HTTP integrity 校验通过显式错误报告待支持;缓存、响应头语义及系统版本差异详见官方测试结果;iOS 18.2 的少量 text/plain 数据可能触发系统首包缓冲。
events支持使用 Node.js v24.21.0 的 lib/events.js 源码,包括 error 事件语义、once、on、getEventListeners、EventEmitterAsyncResource。全局 EventTarget、Event、CustomEvent、AbortController、AbortSignal 为 Node.js 实现;传给原生 fetch / Request 的信号会自动转换。
fs / fs/promises部分支持API 待补齐。 提供 readFile、writeFile、appendFile、readdir(含 withFileTypes)、mkdir、mkdtemp、rename、copyFile、rm、rmdir、unlink、stat、lstat、access、realpath、truncate 的 Promise、回调和同步(*Sync)API,以及 existsSync。支持文件描述符:open、read、write、writev、fstat、ftruncate、fsync、close,fs.promises.open 返回 FileHandle。createReadStream 与 createWriteStream 使用 Node.js 的流实现,按块读写。提供 fs.constants、Stats、Dirent,错误带有与 Node.js 一致的 code、errno、syscall、path。watch、opendir、创建符号链接以及修改权限和时间戳(chmod、utimes)暂不支持。相对路径以项目目录(process.cwd())为基准;需要跨构建保留的数据请放在项目的持久化数据目录。系统和其他应用的数据仍受 iOS 沙盒保护。
http支持使用 Node.js v24.21.0 的 lib/http.js 及 _http_* 源码,服务端与客户端都基于 net:createServer、Agent(keep-alive 连接复用)、chunked、pipelining、trailers、100-continue、upgrade、CONNECT、headersTimeout / requestTimeout / keepAliveTimeout、maxHeaderSize、insecureHTTPParser 与 Node.js 一致。HTTP 解析器是由 Node.js 同版本 deps/llhttp 编译的 WebAssembly,与 Node.js 的 internalBinding('http_parser') 语义一致;系统禁用 WebAssembly(如锁定模式)时使用 http 会抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM。由官方 test-http-* 测试覆盖(见官方测试基线)。命令行选项(如 --max-http-header-size、--insecure-http-parser)不可设置,使用默认值,可改用对应的 API 选项。全局 fetch 仍走 URLSession,可访问脚本自身的服务器;http.WebSocket 等即平台原生的全局类。
https支持使用 Node.js v24.21.0 的 lib/https.js,基于 http 与 tls:createServer、request / get、keep-alive Agent 与会话复用、ca / checkServerIdentity / rejectUnauthorized、NODE_TLS_REJECT_UNAUTHORIZED 与 Node.js 一致。由官方 test-https-* 测试覆盖。限制同 tls。全局 fetch 仍走 URLSession(使用系统证书库),不受 https.globalAgent 影响。
os支持使用 Node.js v24.21.0 的 lib/os.js 源码。主机名、内核版本、CPU 时间、内存、网络接口、用户信息来自设备。homedir() / tmpdir() 遵循 HOME / TMPDIR:HOME 默认指向项目的持久化数据目录,TMPDIR 默认指向项目的临时目录。getPriority / setPriority 尚未提供。
path支持使用 Node.js v24.21.0 的 lib/path.js 源码,包括 path.win32 与 path.posix。path.matchesGlob 依赖文件系统 glob 实现,尚未提供。
process部分支持按 Node.js v24.21.0 启动流程构建 process 对象:nextTick、exitCode、beforeExit / exit 事件、hrtime、memoryUsage、emitWarning、未捕获异常与未处理 rejection 模式。process.env 包含项目的环境变量。与 Node.js 一样,存在 ref 状态的定时器或进行中的 I/O 时脚本保持运行。stdout / stderr 为写入控制台的可写流。信号只能发给脚本自身;process.report、chdir 尚未提供。
querystring支持使用 Node.js v24.21.0 的 lib/querystring.js 源码。
sqlite支持移植 Node.js v24.21.0 src/node_sqlite.cc 中面向 JavaScript 的部分。SQL 在每个 JS 线程对应的原生线程上执行,使用随 App 内置、与 Node.js 固定版本一致的 SQLite(3.53.4)。提供 DatabaseSync、StatementSync(run / get / all / iterate、命名参数、readBigInts)、自定义函数与聚合函数、setAuthorizer、会话与 changeset、backup()、serialize() / deserialize()、限制项和 createTagStore()。相对路径(包括 ATTACH、URI 和 VACUUM INTO)以项目目录为基准;需要跨构建保留的数据库请放在项目的持久化数据目录。:memory: 与临时数据库始终可用。由官方 test-sqlite-* 测试覆盖(18 个中通过 12 个,其余差异在于垃圾回收时机、--no-experimental-sqlite 开关和一个数据类型比较用例)。限制:iOS 不能加载未签名的原生代码,loadExtension() 会抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM。与 Node.js 一样,只能通过 node: 前缀导入。
stream支持使用 Node.js v24.21.0 的流实现(Readable、Writable、Duplex、Transform、pipeline、finished、compose、stream/promises、stream/consumers、异步迭代与背压)。Web Streams 适配(toWeb / fromWeb)尚未提供。
string_decoder支持使用 Node.js v24.21.0 源码与移植的增量解码 binding。
timers支持使用 Node.js v24.21.0 的定时器实现:Timeout / Immediate 对象、ref / unref、refresh、timers/promises。事件循环遵循 Node.js 的阶段顺序(timers → I/O → check → close)以及 nextTick / microtask 顺序。
url支持使用 Node.js v24.21.0 的 lib/url.js 源码(旧版 url.parse / format / resolve、fileURLToPath、pathToFileURL、domainToASCII)。URL / URLSearchParams 类为 WebKit 原生的 WHATWG 实现。URLPattern 取决于系统支持。
util支持使用 Node.js v24.21.0 的 lib/util.js 源码,包括 inspect、format、parseArgs、styleText、MIMEType、parseEnv、types。JavaScriptCore 不提供 Promise 状态、Proxy 内部与迭代器预览,因此 inspect 将 Promise 显示为 <pending>,无法识别 Proxy。
async_hooks部分支持使用 Node.js v24.21.0 源码。AsyncResource、executionAsyncId、createHook 适用于运行时创建的资源;JavaScriptCore 没有 Promise hook,因此不会触发 Promise 事件,AsyncLocalStorage 的上下文也不会跨 await 传递。
diagnostics_channel / console / domain / punycode支持使用 Node.js v24.21.0 源码。console 输出保留 Node.js 格式(console.table、分组、计数、计时),并转发到 OneScript 控制台。
zlib部分支持实现待补齐,可扩展压缩适配。 仅提供 deflate、inflate 及同步版本;gzip、Brotli、Zstd、流式压缩和 Node.js 压缩选项尚未适配,需补充对应算法与接口。
crypto部分支持兼容层与后端能力共同决定范围,可继续适配。 基于 OpenSSL 3.5.8,覆盖哈希、随机数、密钥派生、加解密、密钥、签名、DH/ECDH、KEM 和证书操作;流式对象受当前 stream 实现限制,secureHeapUsed() 当前返回全零占位值。算法取决于所带后端;FIPS 与 Engine 限制分别见下方条目。
WebCrypto部分支持实现待补齐,可扩展加密适配。 提供全局 crypto、密钥、摘要、签名、派生及部分加解密操作;算法名称识别与具体操作的覆盖范围不同,例如 AES-KW 密钥包装尚未接通。需按算法、操作和参数逐项补齐,由当前兼容层与加密后端共同决定可用范围。
FIPS不支持当前构建未配置 FIPS Provider。 getFips() 返回 0,setFips() 抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM。要提供 FIPS 模式需按 OpenSSL FIPS 要求集成适用的 Provider,并核对其认证范围、版本及运行环境;仅补充 JavaScript API 无法建立 FIPS 合规性。
动态 OpenSSL Engine 加载不支持当前后端构建禁用动态模块加载。 setEngine() 抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM;补充支持需要修改原生构建与适配,外部库加载还受 iOS 代码签名约束。特定实现需经过移植、签名和应用集成。
child_process不支持当前 iOS 应用沙盒与运行架构限制。 spawn / exec 需要启动 OS 可执行程序,fork 需要额外 Node.js 进程;普通 iOS 应用的执行权限和沙盒约束使这套任意子进程模型无法通过 polyfill 补齐。当前导入即抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM。多进程服务可改用 cluster(以线程模拟子进程)或 worker_threads。
cluster支持使用 Node.js v24.21.0 的 lib/cluster.js 与 internal/cluster/* 源码。iOS 不能创建进程,fork() 出的 worker 是以线程模拟的子进程:拥有自己的事件循环、process.env 与进程号(process.pid / process.ppid),对 Node.js API 表现为该进程的主线程(isMainThread 为 true),与 primary 之间的 IPC 支持 json / advanced 序列化与句柄传递。round-robin(默认)与 SCHED_NONE 两种调度都可用:连接与监听套接字经内置网络核心在线程之间传递,多个 worker 共享同一个 http / net 服务器端口。disconnect、kill、exit 事件、setupPrimary({ exec, args, silent, stdio, serialization }) 与 Node.js 一致。由官方 test-cluster-* 测试覆盖。限制:所有 worker 与 primary 共用一个 WebContent 进程(内存不足时一起退出);信号只在 primary 与 worker 之间模拟——worker 监听了该信号时触发事件,否则立即结束该 worker;cwd、uid / gid 与额外的 stdio 文件描述符不可用;UDP(dgram)不可用。
worker_threads支持使用 Node.js v24.21.0 的 lib/worker_threads.js 与 internal/worker* 源码。每个 Worker 是独立的平台 Worker 线程,拥有自己的事件循环、process 与原生网络线程,CPU 密集任务真正并行执行;terminate() 可结束同步死循环。支持文件入口(工程中的 .ts / .js 在运行时按需打包,import.meta 与 __filename 指向源文件)、eval 代码与 data: URL;workerData、MessageChannel / MessagePort(含转移)、receiveMessageOnPort、BroadcastChannel、SharedArrayBuffer 与 Atomics、markAsUntransferable、setEnvironmentData、resourceLimits、stdout / stderr / stdin、execArgv(限 OneScript 支持的选项)、process.exit 只结束当前线程、未捕获异常在父线程触发 error 事件。v8.serialize / deserialize 与结构化克隆使用 V8 序列化格式。由官方 test-worker-*、test-message* 测试覆盖。限制:SHARE_ENV 只在创建时复制环境变量;Atomics.wait 阻塞期间 receiveMessageOnPort 读不到尚未送达的消息;堆快照、CPU / 堆分析与 vm 上下文不可用;Promise 微任务在宏任务边界执行。
net支持使用 Node.js v24.21.0 的 lib/net.js 源码,TCP 与 Unix 域套接字由内置的 libuv(与 Node.js 同一版本)在独立的 IO 线程上执行:listen() 未指定地址时监听 ::(双栈)、allowHalfOpen、autoSelectFamily、setTimeout、setNoDelay / setKeepAlive、resetAndDestroy、BlockList、SocketAddress,错误码与 Node.js 一致。由官方 test-net-* 测试覆盖(见官方测试基线)。限制:不开放文件描述符({ fd }、net.Socket({ handle }) 不可用);Unix 域套接字路径按 process.cwd() 展开为绝对路径,长度不超过 103 字节(iOS 容器路径较长,需选用较短路径);访问局域网设备需要用户授予本地网络权限;App 进入后台后连接可能被系统中断。不同套接字之间的事件先后与 Node.js 一样取决于内核时序。
tls支持使用 Node.js v24.21.0 的 lib/tls.js 与 internal/tls/* 源码。TLS 引擎是由 Node.js 同版本 deps/openssl(OpenSSL 3.5)与 deps/ncrypto 编译的 WebAssembly,SecureContext 与 TLSWrap 移植自 crypto_context.cc / crypto_tls.cc,在脚本线程中运行,不占用小组件与快捷指令扩展的内存额度;首次使用 TLS 时加载(约 2.8 MB)。支持 TLS 1.2 / 1.3、ALPN 与 ALPNCallback、SNICallback、会话恢复与票据、客户端证书、PSK、OCSP、keylog、exportKeyingMaterial、setDefaultCACertificates,错误码与 Node.js 一致;默认 CA 为 Node.js 内置根证书(tls.rootCertificates)。由官方 test-tls-* 测试覆盖。限制:系统证书库(--use-system-ca)与 NODE_EXTRA_CA_CERTS 不可用;OpenSSL 引擎与证书压缩(certificateCompression)不可用;加解密吞吐低于原生 Node.js;系统禁用 WebAssembly(如锁定模式)时使用 tls / https 抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM;Promise 微任务在宏任务边界执行,TLS 回调中以 await 延后的操作晚于 Node.js 生效。
dns / dns/promises部分支持lookup、lookupService 与 Node.js v24.21.0 一致,经系统 getaddrinfo / getnameinfo 解析(同样遵循 VPN 与系统 DNS 设置)。基于 c-ares 的 resolve*、Resolver、setServers 不可用,调用时抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM;getServers() 返回空数组。
WebAssembly(WASM)支持使用 WKWebView 原生 WebAssembly API,通过 WebAssembly.instantiate(bytes) 实例化字节码并执行导出函数;具体特性随 iOS / WebKit 版本而定。导入 .wasm 文件会得到打包后的资源路径,需自行读取字节并实例化。
地理定位(navigator.geolocation)支持基于 Core Location 实现 Web Geolocation API:getCurrentPosition、watchPosition、clearWatch、GeolocationPositionError 与 navigator.permissions.query({ name: "geolocation" })。未清除的 watch 会让脚本保持运行,直到调用 clearWatch。只在 App 位于前台时更新。OneScript API 见 geolocation。
wasi不支持当前缺少 WASI 宿主接口,可适配受限子集。 WASM 执行能力已提供;WASI 额外要求文件描述符、文件系统、时钟和随机数等导入接口。可通过 JavaScript 与受授权的系统能力补充,范围受沙盒权限约束;浏览器中已有 WASI 子集实现。当前导入即抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM。
原生插件(.node / node-gyp)不支持当前 ABI、构建环境与代码签名限制。 .node 插件依赖 Node-API 或 V8 / Node.js 接口,当前 WebView 运行时未提供对应 ABI 和加载器;设备端也未提供 node-gyp 所需工具链。任意下载的原生二进制还受 iOS 签名限制;特定库需针对 iOS 移植、签名并随应用集成。

注:“支持”表示已实现备注列出的功能;“部分支持”表示提供 API 子集或存在行为、平台限制;“不支持”表示当前运行环境无法使用该特性。备注中的“可扩展”说明技术上的实现路径,实际支持以当前版本为准;“平台限制”以普通 iOS 应用的沙盒和签名权限为边界。


内置模块支持 Node.js 标准导入方式,如 import … from 'node:crypto' 和 require('crypto')。推荐显式使用 node: 前缀。

How is this guide?

最后更新于