Perry:原生 TypeScript 编译器

8 阅读8分钟

Perry 是什么?

Perry 既是工具,也是语言生态系统的延伸。 更准确地说,它是一个原生 TypeScript 编译器(工具属性为主),底层用 Rust 编写,借助 SWC 解析 TypeScript 源码、用 LLVM 生成原生机器码,最终输出无需 Node.js/浏览器的独立可执行文件。它不发明新语言,你写的仍然是 TypeScript,但它把 TypeScript 的运行边界从"浏览器/Node 沙箱"扩展到"操作系统原生层"。


一、Perry 给前端开发者带来的能力扩展

1. 跨平台原生应用开发(一套代码,10 个平台目标)

Perry 内置 perry/ui 声明式 UI 系统,直接编译为平台原生 Widget,彻底绕开 Electron/WebView:

perry compile src/main.ts --target ios -o MyApp
perry compile src/main.ts --target android -o MyApp
perry compile src/main.ts --target wasm -o app.wasm
perry compile src/main.ts --target web -o app.html

支持的目标涵盖 macOS / iOS / iPadOS / visionOS / tvOS / watchOS / Android / Windows / Linux / Web / WASM,以及各平台的桌面小组件(WidgetKit / Wear OS Tile)。

示例: 用 TypeScript 写的 SwiftUI 风格 UI,一份代码同时出 macOS 应用和 iOS App:

import { App, VStack, Button, Text } from 'perry/ui';

const body = VStack(16, [
  Text("Hello from Perry!"),
  Button("Click me", () => console.log("clicked"))
]);
App({ title: 'Demo', width: 400, height: 300, body });

编译为 macOS 原生二进制:perry compile src/main.ts -o demo && ./demo


2. 高性能服务端/系统级程序

Perry 在多数基准测试中比 Node.js 快 2x–31x(闭包场景 31 倍),部分场景甚至超过 Rust/C++:

场景PerryNode.js提升
闭包 10M 次调用10ms309ms31x
阶乘累加(整数)31ms596ms19x
类方法调用 10M 次1ms11ms11x

前端工程师可以直接用 TypeScript 写 CLI 工具、后台守护进程、高并发 API Server,输出 ~330KB 的单一可执行文件,无需携带 node_modules。


3. 真正的多线程并发

通过 perry/thread 模块暴露操作系统真实线程,不再受限于浏览器的单线程 + Web Worker 消息传递模型:

import { parallelMap, spawn } from 'perry/thread';

// 跨所有 CPU 核心并行处理数组
const results = parallelMap([1,2,3,4,5], n => heavyComputation(n));

// 后台线程
const result = await spawn(() => processLargeFile('/data/1GB.csv'));

4. 编译到 WebAssembly

perry compile src/main.ts --target wasm -o app.wasm

前端开发者可以直接把 TypeScript 逻辑编译为 WASM 模块,嵌入现有 Web 应用,获得接近原生的计算性能。


5. 发布与生态

Perry 内置的 perry publish ios / android / macos 命令会把 TypeScript 源码发送到云端构建服务器,完成跨编译、代码签名、打包发布,整个流程对前端工程师非常友好。


二、前端开发者需要深入补足的核心能力

Perry 打开了原生开发的大门,但要真正驾驭这些能力,需要建立新的知识体系:


1. TypeScript 类型系统的深度掌握(最直接的投资)

Perry 在编译期做静态类型推断,不支持运行时动态类型检查,装饰器(Decorators)目前也不支持。你需要深入掌握:

  • 泛型(Generics)的单态化(monomorphization)原理
  • 联合类型(Union Types)、类型守卫(Type Guards)
  • 条件类型(Conditional Types)、映射类型(Mapped Types)
  • satisfies 操作符、模板字面量类型
// Perry 会在编译期将泛型单态化,需要理解这一行为的影响
function max<T extends number>(a: T, b: T): T {
  return a > b ? a : b;
}
// 编译后为针对 number 的 i64/f64 特化实现,无装箱开销

2. 编译器与运行时基础知识

Perry 的编译链:TypeScript → SWC 解析 → HIR(High-level IR)→ LLVM IR → 机器码。理解以下概念会让你写出更高效的代码:

  • 逃逸分析(Escape Analysis):Perry 会检测不逃逸的对象,直接用寄存器替代堆内存。写小型局部对象而不是 class 实例时,可以利用这一优化:
// Perry 会做标量替换:Point 的字段变成寄存器,零堆分配
function distance(x1: number, y1: number, x2: number, y2: number): number {
  const dx = x2 - x1;  // 纯局部计算,无对象逃逸
  const dy = y2 - y1;
  return Math.sqrt(dx * dx + dy * dy);
}
  • NaN-boxing 值表示:Perry 将所有值压缩为 64 位 word,理解这点有助于避免不必要的装箱操作
  • 内存管理:Perry 有 GC(标记-清扫),但知道何时会触发 GC 压力(大量短生命周期对象)有助于性能调优

3. 系统编程基础(Rust / C++ 概念入门)

Perry 本身用 Rust 编写,其性能理念(所有权、零开销抽象)值得了解。不需要精通 Rust,但要理解:

  • 栈(Stack)vs 堆(Heap)分配的区别和性能影响
  • 内存布局(数组连续内存、对象字段对齐)
  • 平台 ABI(调用约定、链接器的作用)
# Perry 需要系统 C 链接器
xcode-select --install  # macOS
sudo apt install build-essential  # Linux

理解链接器工作原理,有助于你调试二进制大小问题(Perry 支持按需链接,~330KB 起步)。


4. 操作系统与平台 API 知识

Perry 编译到各平台原生 Widget,需要理解:

  • macOS/iOS:AppKit(NSView)、UIKit 的组件树思维
  • Android:Android Views、JNI 桥接机制
  • Windows:Win32 消息循环、句柄管理
  • Linux:GTK4 事件循环
// perry/ui 的组件模型与原生平台强相关
import { NavigationStack, List, Text } from 'perry/ui';
// 这段代码在 iOS 上编译为 UINavigationController + UITableView
// 在 macOS 上编译为 NSSplitViewController 结构
// 需要理解各平台的差异来写出跨平台一致的 UX

5. 并发编程模型

从浏览器的"事件循环 + Promise"迁移到"真实多线程"时,需要理解:

  • 数据竞争(Data Race):Perry 的线程通过深拷贝传值,但你需要理解为什么这是必要的
  • 线程池与工作分配parallelMap 如何切分任务、合并结果
  • 异步 I/O vs 多线程:Perry 默认用 Tokio 异步 I/O,perry/thread 提供显式线程,两者适用场景不同
import { parallelMap, spawn } from 'perry/thread';

// 适合:CPU密集型计算(图像处理、加密、数学计算)
const hashes = parallelMap(files, f => computeHash(f));

// 不适合:I/O 密集型(直接用 async/await + Tokio 即可)
const data = await fetch('https://api.example.com/data');

6. 构建系统与 CI/CD 工程化

Perry 有复杂的跨平台发布矩阵,需要掌握:

  • GitHub Actions / CI 流水线:Perry 本身的 .github/workflows/release-packages.yml 是很好的学习模板
  • 交叉编译(Cross Compilation):为目标平台(iOS/Android)在 macOS 上构建二进制
  • 代码签名(Code Signing):iOS/macOS 应用必须签名,perry publish 封装了这一流程但需理解原理
  • 包体积优化:理解 Perry 的按需链接、stripping 机制,以及 --enable-js-runtime 带来的 +15MB 代价

三、可发展的方向与路径指导

方向 A:原生应用开发工程师

路径:TypeScript → Perry UI → 单一平台(如 macOS)深耕 → 多端扩展

需要补充的能力:

  • 平台 HIG(Human Interface Guidelines)设计规范
  • 应用沙箱、权限模型(entitlements)
  • App Store 发布与审核流程

示例里程碑:用 Perry 构建一个类似"Mango"(7MB 的 MongoDB GUI)的桌面工具并上架 Mac App Store。


方向 B:高性能后端/系统工具开发者

路径:Node.js API Server → Perry 编译的高性能 API → CLI 工具 → 系统守护进程

需要补充的能力:

  • HTTP 协议深度(keep-alive、连接池、TLS)
  • 数据库驱动原理(perry-sqlite / perry-postgres 是 sqlx 的包装)
  • 进程管理、信号处理(perry 的 child_process.spawnBackground
// 用 Perry 写一个高性能 API,性能接近 Rust 水平
import fastify from 'fastify';
import { PrismaClient } from 'perry-sqlite';

const app = fastify();
const db = new PrismaClient();

app.get('/users', async () => {
  return db.user.findMany({ take: 20, orderBy: { createdAt: 'desc' } });
});

app.listen({ port: 3000 });
// perry compile src/main.ts -o api && ./api
// 启动时间 <100ms,无 V8 cold start

方向 C:WebAssembly / 跨平台 SDK 开发者

路径:前端 → Perry WASM 输出 → 封装为 SDK → 供多端调用

需要补充的能力:

  • WASM 内存模型(线性内存、导入/导出接口)
  • JavaScript ↔ WASM 互操作(类型映射、内存传递)
  • wasm-pack / wabt 生态工具链
perry compile src/encoder.ts --target wasm -o encoder.wasm
# 在浏览器中以接近原生速度运行 TypeScript 业务逻辑

方向 D:游戏/实时渲染工程师

路径:Canvas/WebGL → Bloom Engine(Perry 的原生游戏引擎)→ Metal/DirectX 12/Vulkan

需要补充的能力:

  • 图形渲染管线(顶点着色器、片元着色器)
  • 游戏循环(update/render 分离、帧率锁定)
  • 物理引擎基础(碰撞检测、刚体模拟)
  • 音频系统(空间音效、混音)
// Bloom Engine 支持写 TypeScript 游戏,编译到 Metal/Vulkan
// 一套代码覆盖 macOS / iOS / Android / Windows

方向 E:编译器/语言工具链贡献者

路径:使用 Perry → 理解 HIR 结构 → 贡献代码优化 / 新 TypeScript 特性支持

需要补充的能力:

  • 编译原理:词法分析、语法分析、AST → IR 降级
  • LLVM IR 基础(基本块、phi 节点、内存 SSA)
  • Rust 语言(Perry 全部用 Rust 编写)
  • 如何读写 crates/perry-hir/src/ir.rs 添加新 HIR 节点

Perry 仓库本身的贡献指南非常清晰,这是少有的"可以从 TypeScript 前端直接切入编译器内核"的机会。


总结

Perry 的本质是把 TypeScript 变成一门系统级语言。对前端开发者而言,最大的价值在于:用已经熟悉的语言,获得过去只属于 Swift/Kotlin/Rust 工程师的能力范围(原生 UI、高性能计算、跨平台发布)。但要真正吃透这些能力,需要在 TypeScript 类型系统、编译器/内存原理、操作系统平台知识、并发模型这四个维度上做系统性补强。选择一个切入点(如原生 macOS 工具开发)深耕,比全面铺开更容易形成差异化竞争力。