Vercel 的 scriptc:TypeScript 到本地编译器,二进制中没有 JavaScript 引擎
零运行时 TypeScript。scriptc 将普通 TypeScript 编译成小巧、快速的本地可执行文件——没有 Node,没有 V8,没有 JavaScript 引擎在二进制中。$ cat fib.ts function fib(n: number): number { return n < 2 ? n : fib(n - 1) + fib(n - 2); } console.log(fib(30)); $ scriptc run fib.ts 832040 $ scriptc build fib.ts && ls -la fib -rwxr-xr-x 178K fib # 一个自包含的本地二进制文件,启动时间约 2 毫秒 不会对你的代码做任何更改。没有注解,没有方言——和在 Node 上运行的相同 TypeScript,经过真实的 TypeScript 编译器类型检查,并编译为本地代码。编译的行为与 Node 字节对字节相同。安装 $ npm install -g scriptc 需要 clang(随 Xcode 命令行工具预装)。macOS arm64 是主要平台;Linux 和 Windows 二进制通过交叉编译构建,每个都经过其自己的差异测试通道验证。这个想法:你能看到的静态性 大多数 TypeScript 的静态性远比生态系统假设的要高。scriptc 决定逐构造地什么可以编译为本地代码——并告诉你:$ scriptc coverage app.ts statements analyzed 4481 compile statically 4451 (99%) blockers: ×2 functions with optional parameters as values SC1090 ×1 Promise.reject SC2020 三个层次,总是明确的: 静态编译——本地代码,无引擎。这是默认设置,且是唯一模式,除非你选择退出。动态运行(--dynamic)——嵌入的 JavaScript 引擎(quickjs-ng,约 620KB)执行无法静态编译的内容:npm 依赖项的已打包 JS,任何类型代码。每个返回静态代码的值在运行时都经过验证——不真实的类型会抛出可捕获的 TypeError,而不是破坏内存。拒绝——所有其他失败时都会返回特定错误代码、代码框架,并且通常提供重写提示。没有任何东西会静默地编译错误。 编译的内容 静态表面覆盖了语言和真实程序所使用的标准库: 语言——使用单一继承和真正动态调度的类(在证明安全时去虚拟化)、具有 JS 捕获语义的闭包、泛型(单态化)、根据 TypeScript 自身细化驱动的标记值的区分联合、在堆栈上堆栈化的异步/等待(具有 JS 精确调度)、具有 finally 的异常、解构、扩展、可选/默认/剩余参数、getter/setter、字符串/数组/映射/集合的迭代器、模板字面量、正则表达式(引擎是与 ECMAScript 精确字节码解释器 QuickJS 使用的相同,链接到仅使用正则表达式的二进制文件)。 标准库——具有 UTF-16 精确语义的字符串、具有 JS 精确顺序和标识的数组/映射/集合、具有运行时验证的 JSON 转换、Math、类型数组和 Buffer、具有类型捕获的错误层级。 Node 的 API 表面——fs(同步和承诺)、path(字节精确端口)、process、child_process 与管道流、os、crypto、url / URL、zlib、定时器和无依赖事件循环上的信号处理程序——和服务器堆栈:net、http、https、tls(提供 mbedTLS)、dgram、dns、fs.watch、readline。真实的代理服务器会编译。fetch 和 WHATWG web 子集(流、Headers、AbortSignal)在相同的本地网络/TLS 堆栈上——重定向、gzip、AbortSignal.timeout、Node 样式错误原因;没有 libcurl,没有系统 HTTP 依赖。 npm 依赖(使用 --dynamic)——包使用 Node 自身的算法解析,针对其已打包的 .d.ts 进行类型检查,并在构建时将它们的 JS 嵌入到二进制文件中。二进制文件在运行时不会读取 node_modules。程序针对 TypeScript 的真实 es2025 库进行类型检查(加上 @types/node,当你的项目有时),你的 tsconfig.json 管理检查严格性。任何没有减小的代码都是精确的诊断,从不会让人惊讶。 正确性 两个执行机制在每次更改时运行: 差异测试——每个语料库程序(800+ 测试)在 Node 和作为本地二进制下运行;stdout、stderr 和退出代码必须字节对字节匹配。数字格式是 JS 精确(最短往返,经过数百万个双精度数的模糊验证)。使用实时客户端驱动程序对服务器进行测试,验证两个实现。 内存安全通道——整个语料库在 AddressSanitizer 下重新运行,进行引用计数审核;内存泄漏和使用后释放将导致构建失败。与 Node 的故意差异(有几十个,主要围绕时间内部和错误对象属性)都有记录并编号;没有任何东西会静默地产生差异。 性能 在 Apple M 系列上测量,针对 Node、Go、Rust 和 Zig 中相同的工作负载(所有字节相同的输出,经过验证): 维度 scriptc 上下文 启动 ~2.4ms Node: ~47ms;与 Zig 持平,领先于 Go/Rust 二进制大小 170–200KB 静态,~3MB(使用 --dynamic + 嵌入依赖) Go: ~2MB;Node SEA: 60–100MB 内存(RSS) 1–4MB 一般 Node: 67–116MB 运行时 JS 忠实 f64 语义;在大多数工作负载中与系统语言具有竞争力 整数推断和所有权分析在工作路线图中。 逃生通道,诚实定价 comptime(() => ...) 在构建时运行 TypeScript(在一个 is...
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡