iT邦幫忙

2024 iThome 鐵人賽

DAY 23
1
Modern Web

Rust 的戰國時代:探索網頁前端工具的前世今生系列 第 23

Day 23:什麼是 Oxc?什麼是 void(0)?

  • 分享至 

  • xImage
  •  

前言

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

voidzero

雖然前面 Day 18 有點到一些,但今天在看完了這場 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 生態系的底層仍需要同時仰賴多套工具。

map

所以決定不要只停在統一 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 上玩過:

roadmap

原本只是個 side project

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 等工具。

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

文章同步發表於個人部落格


上一篇
Day 22:Rspack / Rsbuild 入門 (2) - 打包工具分析、Rsdoctor、chunk splitting
下一篇
Day 24:Rust 學習筆記 (1) - 千里始於 Hello, world!
系列文
Rust 的戰國時代:探索網頁前端工具的前世今生30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言