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++:
| 场景 | Perry | Node.js | 提升 |
|---|---|---|---|
| 闭包 10M 次调用 | 10ms | 309ms | 31x |
| 阶乘累加(整数) | 31ms | 596ms | 19x |
| 类方法调用 10M 次 | 1ms | 11ms | 11x |
前端工程师可以直接用 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 工具开发)深耕,比全面铺开更容易形成差异化竞争力。