avatar
threadsinstagram

什麼是 Oxc?什麼是 void(0)?

Table of Contents

前言

前幾天在 ViteConf 2024 時,Evan You 宣佈成立一間新公司 — void(0),目標在打造一整套開源、統一、高效能的 JavaScript 開發工具鏈。

vite conf 2024 with voidzero announcement

今天在看完了這場 keynote 與後面 Oxc 專案的核心開發者 Boshen 的介紹後,認為核心開發團隊經過一年的研究後講的又更清楚了,因此也做了些筆記,那就讓我們快速了解一下這個 Oxc 跟這個 void(0) 是怎麼回事吧。

什麼是 void(0)?

Vite 現在的缺點與困境

vite issues

雖然 Vite 生態系四年來成長速度很快,但這兩年都不斷提到目前有一些痛點:

  • esbuild 在 dev 中被拿來當 dep. pre-bundling (或稱 dep. optimizer) 的打包,但它在 code splitting、tree-shaking、plugin 的不足讓 Vite 無法完全用它做為統一的 bundler
  • Rollup 打包速度太慢
  • Rollup 目前底層用上的 SWC 有執行檔過大的問題,舉例在 macOS 上 SWC 的 binary 檔案有 37MB,幾乎是 Vite 本身的兩倍多。且 SWC 本身也沒有提供完整的 bundler 功能。
  • esbuildRollup 兩套 bundler 造成 dev / prod 行為不一致,有時會在上線後才發現 bug
  • 多套的工具造成 build pipeline 的過程中轉譯語言成本的浪費:
    • 同樣一段程式碼,在 Vite 做 production build 時重複被解析成 AST、轉譯、序列化成字串
    • 這些資料在這三個工具的原生執行環境中傳輸,像是從 Go process 傳到 JS main thread,再傳到 Rust,再傳回 JS,中間的轉換過程浪費成本
    • 如果開啟 source map 的功能後上述的狀況會更糟糕,因為在每一步傳輸中都會需要重新映射(remapping)這些 source map 再去做合併

💡 補充:SWC 筆記

參考 SWC 官網介紹,整理一下筆記:

  • 可以理解為更快的 Babel
  • 因為是以 Rust 為基底做開發,比 Babel 快 20~70 倍 (隨著編譯時使用的硬體資源提升有所不同)
  • 用途
    • 主要用來轉譯 JS/TS 成瀏覽器可識別的一般 JS
    • minification
    • 可與 webpack 搭配 (swc-loader)
    • 可用來增進 Jest 效能 (@swc/jest)
  • 一些應該不太重要的業界冷知識
    • SWC 原作者是個 1997 的韓國小哥 DongYoon Kang (kdy)
    • Next.js 12 的文章中提到,目前 Vercel 已挖角了 SWC 作者 kdy 及 Parcel 核心貢獻者 Maia Teegarden,決心投資 Rust 生態系

為什麼要成立 void(0)?這是什麼?

voidzero-2

綜上所述的問題,去年 Vite 團隊決定與 Rspack 團隊一同開發 Rolldown,但當團隊越鑽越深時,發現如果不一次做到好,底層的這些問題可能仍會歷史重演,JS 生態系的底層仍需要同時仰賴多套工具。

roadmap for voidzero

所以決定不要只停在統一 bundler 這一步,想要將底層工具鏈也全部串起來,也因此募資並成立了 void(0) 這間公司想打造一個全方位的 JS 工具鏈,希望能達到這樣的願景:

  • 統一 (Unifoed):希望能在 dev / prod 轉換程式碼時都使用同一套工具、使用相同的 AST、同樣的設定、同樣的模組格式、路徑解析方式
  • 高效能 (High Performance):做打包與轉譯等工作,應使用編譯型 (compiled-to-native) 語言,不僅可以增加 DX、加快產品交付,甚至能幫在座的各位省機器的成本
  • 可組合 (Composable):工具鏈中的每一段應要是可獨立使用的,像是 parser、resolver、transformer 等,應該都要是一個套件,不論是 NPM packages 或是 Rust crates
  • 框架不可知論 (Runtime Agnostic):這工具鏈應該不限制只能被用在某個框架中

什麼是 Oxc?

上面有看到在 Vite 的生態系中,Oxc 是一個可組合的語言工具鏈,其中含有一整套的 npm package 與 Rust crates,包含 parser、linter、formatter、transformer、minifier、resolver、semantic analysis 這些功能。

效能大比拼

或許你可能會對其中的這些工具感到困惑,直接看一下效能比拼中比對的對應工具,會看到一些熟悉的工具:

  • Oxc parserSWC 快 3 倍、比 Biome 快 5 倍
  • Oxc linter (又稱 oxlint) 比 ESLint 快 50~100 倍,當今天能擴充更多 CPU 核心時還能更快
  • Oxc resolverwebpack/enhanced-resolve 快 28 倍
  • Oxc transformer
    • TypeScript/TSX 轉譯:比 SWC 快 4 倍、比 Babel 快 40 倍
    • React Refresh:比 SWC 快 6 倍、比 Babel 快 70 倍
    • 產出 TypeScript 的聲明檔 (.d.ts):比 tsc 快 20~45 倍
  • Oxc 比起 SWC 與 Babel 有更少的記憶體使用與更小的套件與執行檔大小

而其中仍然有幾個工具我沒很懂它的用途,也做一下筆記:

  • Parser 會用來解析 JS、JSX、TSX 並能生成 AST (Abstract Syntax Tree 抽象語法樹) 供後續 bundler 做語法分析,像是進入點在哪、需要轉譯成什麼模組、tree shaking 等
  • Resolver 用來解析 Node.js 的模組路徑
  • Transformer 利用 parser 產出的 AST,分析並轉譯出需要的 JS 檔案

從上面這些比較,可以理解為 Oxc 的目標想把以前的一些工具像是 Babel、ESLint、tsc、prettier 等 JS 開發工具鏈用 Rust 改寫來做一個效能提速,基本上跟另外一個 Biome 是同樣的目標,都想以 Rust 來實現更快速的工具。

Oxc 進度

但比較可惜的是目前這個工具鏈還在開發中,目前只有其中幾個工具可使用,在想可能等它再穩定些再回頭來學習,目前只有在 Oxc playground 上玩過:

Oxc roadmap now

原本只是個 side project

Oxc introduction from boshen

補充一個可能不太重要的冷知識,Oxc 核心開發者 BoShen 在議程中提到,這個 Oxc 最一開始只是他基於學習 Rust 的 side project,先是學著用 JS/TS 如何寫出 parser、linter 等,再進階到做出一個 Rust 版的 oxlint 並發佈這個工具,而後來 Preact 作者 Jason、和 Evan 都嘗試將 oxlint 拿來替代原本的 Linter 發現在大專案中的效能節省了數倍,因此才有了今天的故事。

小結

今天透過觀看 ViteConf 2024 更了解到 void(0) 這個前陣子在社群上引起討論的消息,知道它旨在打造一個全方位的 JS 工具鏈,而其中的這個 Oxc 將在未來做為其他工具的底層,來提供可在所有框架間組合的 parser、linter、transformer 等工具。

也趁機會了解了這些底層工具的用途,如果有什麼問題也歡迎在下面留言告訴我,我們明天見!