TypeScript
Nub 如何在原生 Node 上运行完整的 TypeScript 接口——不可擦除语法、资源管理降级和 source map——这些原生 Node 都不做。
Nub 运行整个 TypeScript 接口,不只是 Node 内置类型剥离接受的 可擦除子集。以 .ts、.tsx、.mts 和 .cts 结尾的文件直接执行:Nub 通过 module.registerHooks() 加载钩子用其基于 oxc 的转译器转译它们,然后将结果交给 Node。
nub index.ts
nub server.tsx转译在 Node 看到代码之前发生,所以本页的转换在 Nub 支持的每个 Node 版本(18.19+)上都有效。唯一的例外是 source map;参见下方 Source map。
类型被剥离,不被检查
Nub 不做类型检查——类型被剥离以供执行。在编辑器和 CI 中保留 tsc --noEmit 进行类型验证。node_modules 内的文件也从不被转译;它们完全按包发布的方式加载。
不可擦除语法
enum、namespace、参数属性和 import = 等语法需要转换,不只是类型移除——Node 的类型剥离拒绝所有这些。Nub 的转译器作为正常流水线的一部分发射运行时形式。
enum Color { Red, Green, Blue }
namespace Geometry {
export const PI = 3.14159;
}
class User {
constructor(public id: string, private name: string) {}
}
import fs = require("node:fs");你通过编写来选择语法;Nub 让它运行。
JSX 和装饰器各有自己的页面:参见 JSX 了解 .jsx / .tsx 运行时和 tsconfig 配置,装饰器了解旧版 experimentalDecorators 形式和 emitDecoratorMetadata。
普通 JavaScript
你项目的普通 JavaScript——.js、.mjs 和 .cjs——通过相同的流水线。Nub 的 Node 下限无法原生解析的现代语法以与 .ts 文件中完全相同的方式降级,所以相同的源码无论扩展名如何行为一致:using / await using、v 标志(unicode-sets)正则如 /\p{Letter}/v 和装饰器都能运行。
// app.js — 在 Nub 支持的每个 Node 上运行
using handle = openHandle();
const letters = /\p{Letter}/v;没有需要降级内容的文件原封不动交给 Node——逐字节,不重新格式化也不加 source map 尾部——所以不需要转换的普通 .js 就是你写的文件。node_modules 内的文件从不被转译;它们按包发布的方式加载,在每个层级上。
.js 文件中的 JSX 不在范围内——使用 .jsx。Nub 将 .js 解析为 JavaScript 而非 JSX,所以 < 是比较运算符,不是元素。
显式资源管理
显式资源管理——using 和 await using 声明——在 Nub 的整个 Node 下限上运行。较旧的 Node(Node 22 的 V8)无法原生解析 using——它是硬 SyntaxError——所以 Nub 的转译器在 Node 看到之前将其降级为基于辅助函数的形式。
class Handle {
[Symbol.dispose]() { console.log("disposed"); }
}
{
using h = new Handle();
console.log("using h");
}
console.log("after scope");$ nub resource.ts
using h
disposed
after scope降级目标为 es2022——仍重写 using 的最高目标,同时保持 Node 22 已支持的一切(顶层 await、类字段、私有方法)不变。释放辅助函数通过 Nub 内嵌的运行时解析;你不需要安装任何东西。
Source map
Nub 为每个转译文件生成内联 source map 并注入 --enable-source-maps,所以未捕获的错误和 console.trace() 打印指向你原始 TypeScript 源码和行号的帧——而非生成的 JS。默认开启;不需要记住标志,且在 nub --inspect 下 .ts 源码中设置的断点正确落地。
$ nub app.ts
/path/to/app.ts:2
throw new Error("kaboom");
^
Error: kaboom
at boom (/path/to/app.ts:2:8)
at Object.<anonymous> (/path/to/app.ts:4:1)堆栈帧报告 app.ts:2:8——你源码中的行,而非转译输出。要关闭它,传递 --no-enable-source-maps。
Source map 在每个支持的 Node 版本上注入,除了 26.2.x 补丁带,在该带中 Node 回归使得开启 source map 时无消息的 assert(false) 重新抛出为 TypeError 而非 AssertionError。在 26.2.x 上 Nub 不注入该标志,所以该处的堆栈跟踪不会被重映射。其他所有版本(18.19 到 26.1,以及 26.3+)都获得 source map。