scriptc:無需 JavaScript 引擎即可將 TypeScript 編譯為原生可執行檔
TypeScript 到 Native 編譯器。沒有註釋,沒有方言,與在 Node 上運行的 TypeScript 相同,由真正的 TypeScript 編譯器進行類型檢查並編譯為原生。
秒懂
- 它是什麼?
- 基於原始資料對 vercel-labs/scriptc 的概述,涵蓋其三種編譯分層、正確性保障、效能資料與開發工作流程。
- 適合誰用?
- scriptc 是一個活躍專案,擁有 2,891 顆星和 66 個 fork。README 記錄了其測試與建置快取,但未揭露生產使用者、安全稽核或除 Apple M 系列測量之外的基準環境。
- 可以商用嗎?
- 可以。Apache-2.0 是寬鬆授權:你可以使用、修改並販售以它為基礎的軟體,只需保留著作權與授權聲明。
- 還在維護嗎?
- 有在維護。儲存庫最近一次提交在 1 天前。
- 用什麼語言寫的?
- 主要是 TypeScript(依據 GitHub 的語言統計)。
以上回答依據專案的 GitHub 資料(最近同步於 2026年9月14日)與我們的分析,不構成法律意見。
開源專案深度解析
零執行期 TypeScript
scriptc 將 TypeScript 編譯為原生可執行檔,二進位中不含 Node.js、V8 或任何 JavaScript 引擎。README 展示了一個費氏數列函數,透過 `scriptc run fib.ts` 執行,並建構出約 178KB、啟動時間約 2ms 的自包含二進位。安裝命令為 `npm install -g scriptc`,要求系統預先安裝 clang(Xcode 命令列工具內建)。macOS arm64 是主要平台,Linux 和 Windows 二進位透過交叉編譯產生,並由各自的差異測試通道驗證。
scriptc 在「零執行期 TypeScript」這一面向的判讀要落在具體材料上:scriptc、Node.js 24、scriptc run hello.ts、scriptc build、--emit=ir、--emit=c、--emit=llvm、--emit=asm、--emit=obj、scriptc coverage、SCRIPTC_TARGET=wasm32-wasi、SCRIPTC_CC=zigcc、--dynamic 與 quickjs-ng。這些名稱是讀者檢查輸入、執行路徑與輸出結果時可直接搜尋的記號。對於 README 沒有交代的作業系統差異、效能數字、相容版本或安全承諾,本文保留為未知,不把推測寫成能力。
採用前可在隔離目錄以 scriptc 的 README 指定入口開始,記錄命令回傳、產物位置及錯誤訊息,再對照同一份文件的限制段落。若命令、設定鍵或資料格式在來源中沒有明確說明,就應視為待確認事項,而不是預設功能。
衡量哪些程式碼可以靜態編譯
scriptc 逐結構分析程式,決定哪些部分能編譯為原生程式碼。`coverage` 命令報告分析的語句數、靜態編譯的語句數以及帶有錯誤碼(如 SC1090 和 SC2020)的阻塞項。README 描述三個明確層級:靜態編譯(原生程式碼,無引擎)、透過 `--dynamic` 旗標使用內嵌 quickjs-ng 引擎(約 620KB)動態執行、以及被拒絕的程式碼(給出特定錯誤碼和通常的重寫提示)。任何內容都不會被靜默錯誤編譯。
scriptc 在「衡量哪些程式碼可以靜態編譯」這一面向的判讀要落在具體材料上:scriptc、Node.js 24、scriptc run hello.ts、scriptc build、--emit=ir、--emit=c、--emit=llvm、--emit=asm、--emit=obj、scriptc coverage、SCRIPTC_TARGET=wasm32-wasi、SCRIPTC_CC=zigcc、--dynamic 與 quickjs-ng。這些名稱是讀者檢查輸入、執行路徑與輸出結果時可直接搜尋的記號。對於 README 沒有交代的作業系統差異、效能數字、相容版本或安全承諾,本文保留為未知,不把推測寫成能力。
靜態編譯的覆蓋面
靜態層覆蓋語言和標準程式庫中實際程式使用的特性:支援單一繼承和動態分派的類別、閉包、泛型(單態化)、判別聯集、基於堆疊纖維的 async/await、例外、解構、展開、getter/setter、迭代器、模板字串和正規表示式。標準程式庫包括 UTF-16 精確字串、JS 精確順序的陣列/Map/Set、帶執行期驗證的 JSON、Math、型別化陣列和 Buffer,以及 Error 階層結構。Node API 覆蓋 fs、path、process、child_process、os、crypto、url、zlib、計時器和伺服器堆疊(net、http、https、tls、dgram、dns、fs.watch、readline)。`fetch` 和 WHATWG web 子集在同一原生 net/TLS 堆疊上執行。使用 `--dynamic` 時,npm 依賴按 Node 演算法解析,對照其 .d.ts 進行型別檢查,其 JS 在建置時嵌入二進位。
scriptc 在「靜態編譯的覆蓋面」這一面向的判讀要落在具體材料上:scriptc、Node.js 24、scriptc run hello.ts、scriptc build、--emit=ir、--emit=c、--emit=llvm、--emit=asm、--emit=obj、scriptc coverage、SCRIPTC_TARGET=wasm32-wasi、SCRIPTC_CC=zigcc、--dynamic 與 quickjs-ng。這些名稱是讀者檢查輸入、執行路徑與輸出結果時可直接搜尋的記號。對於 README 沒有交代的作業系統差異、效能數字、相容版本或安全承諾,本文保留為未知,不把推測寫成能力。
正確性保障
每次變更都會執行兩個強制機制。差異測試將每個語料庫程式(800+ 測試)在 Node 和原生二進位下執行,要求 stdout、stderr 和退出碼逐位元組匹配。數字格式化採用 JS 精確演算法,已在百萬個雙精度浮點數上針對 Node 進行模糊驗證。伺服器透過即時用戶端驅動對兩種實作進行測試。記憶體安全通道在 AddressSanitizer 和參考計數稽核下重新執行整個語料庫;洩漏和釋放後使用被視為建置失敗。與 Node 的少數刻意差異(約幾十處,主要涉及計時內部與錯誤物件屬性)均有文件記錄並編號。
scriptc 在「正確性保障」這一面向的判讀要落在具體材料上:scriptc、Node.js 24、scriptc run hello.ts、scriptc build、--emit=ir、--emit=c、--emit=llvm、--emit=asm、--emit=obj、scriptc coverage、SCRIPTC_TARGET=wasm32-wasi、SCRIPTC_CC=zigcc、--dynamic 與 quickjs-ng。這些名稱是讀者檢查輸入、執行路徑與輸出結果時可直接搜尋的記號。對於 README 沒有交代的作業系統差異、效能數字、相容版本或安全承諾,本文保留為未知,不把推測寫成能力。
效能資料與建置快取
在 Apple M 系列上與 Node、Go、Rust 和 Zig 對比(輸出位元組一致),scriptc 的啟動時間約為 2.4ms(Node 約 47ms),靜態二進位大小 170-200KB(使用 --dynamic 並嵌入依賴時約 3MB),記憶體 RSS 典型 1-4MB(Node 為 67-116MB)。執行效能被描述為在大多數工作負載上與系統語言相當,整數推斷和所有權分析在路線圖上。建置使用內容定址快取,在輕量工具鏈探測後,未變更的可執行檔或程式庫將直接恢復,無需重建或重新連結。快取身分包含解析後的系統頭位元組、連結器/組譯器身分以及精確的隱式連結輸入。所有快取二進位、歸檔和執行期物件均經過校驗和驗證。`SCRIPTC_NO_CACHE=1` 完全停用快取,`SCRIPTC_CACHE_DIR` 選擇快取根目錄。
scriptc 在「效能資料與建置快取」這一面向的判讀要落在具體材料上:scriptc、Node.js 24、scriptc run hello.ts、scriptc build、--emit=ir、--emit=c、--emit=llvm、--emit=asm、--emit=obj、scriptc coverage、SCRIPTC_TARGET=wasm32-wasi、SCRIPTC_CC=zigcc、--dynamic 與 quickjs-ng。這些名稱是讀者檢查輸入、執行路徑與輸出結果時可直接搜尋的記號。對於 README 沒有交代的作業系統差異、效能數字、相容版本或安全承諾,本文保留為未知,不把推測寫成能力。
逃生艙
scriptc 提供四個逃生艙。`comptime(() => ...)` 在編譯器內的隔離 VM 中執行 TypeScript,並將結果作為字面量烘焙進二進位。原生 FFI(`--ffi`)將僅簽名宣告的 TypeScript 綁定到直接 C ABI 呼叫,並連結清單宣告的歸檔、物件和系統程式庫。`--dynamic` 旗標為 npm 依賴和 `any` 程式碼嵌入引擎;`coverage --dynamic` 精確報告哪些語句在何處執行。受檢轉換使 `JSON.parse(...) as Config` 插入執行期驗證,拋出的可捕獲錯誤會指出違規路徑。
scriptc 在「逃生艙」這一面向的判讀要落在具體材料上:scriptc、Node.js 24、scriptc run hello.ts、scriptc build、--emit=ir、--emit=c、--emit=llvm、--emit=asm、--emit=obj、scriptc coverage、SCRIPTC_TARGET=wasm32-wasi、SCRIPTC_CC=zigcc、--dynamic 與 quickjs-ng。這些名稱是讀者檢查輸入、執行路徑與輸出結果時可直接搜尋的記號。對於 README 沒有交代的作業系統差異、效能數字、相容版本或安全承諾,本文保留為未知,不把推測寫成能力。
架構與開發
管線為 TypeScript → tsc 解析/型別檢查 → 降級到型別化 IR → C 程式碼 → clang → 原生可執行檔。編譯器套件負責前端、IR 和後端;執行期套件是 C 執行期,包含參考計數值、堆疊纖維和事件迴圈;CLI 提供 `build`、`run` 和 `coverage`。開發使用 pnpm:`pnpm install && pnpm build`,然後 `pnpm test` 執行差異語料庫和診斷快照,或 `SCRIPTC_SAN=1 pnpm test` 進行 ASan 和 RC 稽核。沙箱測試在 Vercel Sandboxes 上執行,Pro+ 閘道速度快,Hobby 閘道平行度較低。每個功能都附帶差異測試;兩條通道均為綠色是合併標準。專案採用 Apache-2.0 授權,授權授予永久、全球、非獨佔、免費、免版稅的版權和專利授權,但 README 未說明保固或支援條款。
scriptc 在「架構與開發」這一面向的判讀要落在具體材料上:scriptc、Node.js 24、scriptc run hello.ts、scriptc build、--emit=ir、--emit=c、--emit=llvm、--emit=asm、--emit=obj、scriptc coverage、SCRIPTC_TARGET=wasm32-wasi、SCRIPTC_CC=zigcc、--dynamic 與 quickjs-ng。這些名稱是讀者檢查輸入、執行路徑與輸出結果時可直接搜尋的記號。對於 README 沒有交代的作業系統差異、效能數字、相容版本或安全承諾,本文保留為未知,不把推測寫成能力。
編輯結論
scriptc 是一個活躍專案,擁有 2,891 顆星和 66 個 fork。README 記錄了其測試與建置快取,但未揭露生產使用者、安全稽核或除 Apple M 系列測量之外的基準環境。 使用者適合先以 scriptc 的 README 命令和具體檔案做小範圍核對;不適合把 scriptc 的倉庫統計當成生產保證。
社群筆記