大家好,這里是大家的林語冰。持續(xù)關(guān)注,堅持閱讀,每天一次,進(jìn)步一點。
近年來,前端社區(qū)涌現(xiàn)了一大坨運行時,包括但不限于:
圖片
去年,“Bun 之父”J.S. 官宣 Bun 1.0 新鮮出爐,今年 Bun 團(tuán)隊更是野心勃起,企圖用 Bun 打敗 Node。說是這樣說,氣勢不能輸,但私以為 Node 重度用戶的“路徑依賴”沒那么容易克服,大多數(shù)用戶(包括本人)大概率還是會在 Node 的舒適圈中“圈地自萌”。
話雖如此,還是有一大坨道友先質(zhì)疑、再質(zhì)疑:
Bun 直男翻譯為“包子”,或者“小圓甜蛋糕”,我有一個大膽的想法:Bun 的含義大概是想成為像 Node 一樣前端愛好者生活必需的“面包”,抑或是企圖在運行時市場瓜分一塊“蛋糕”。
說巧不巧,初露頭角的 Bun 的頭像就是一大坨名副其實的包子,而成名多年的 Node 的吉祥物還在路上。
圖片
根據(jù) Bun 的官方公關(guān),Bun 是一款可以和 JS/TS “夢幻聯(lián)動”的 all-in-one toolkit(一體化工具人)。換而言之,Bun 是妥妥的“斜杠青年” —— Bun 是運行時/包管理器/打包器/測試運行器。Bun 主打的就是一條龍服務(wù) —— Node 有的我都有,Node 原生沒有的,不好意思我也有。
Node 于 2009 橫空出世,這位“00后”如今可謂人氣爆棚,以至于某些道友指貓為狗 —— Node 是一門“編程語言”,這大約就是“人怕出名貓怕胖”。
圖片
雖然但是,像 React 和 Angular 等前端技術(shù)一樣,隨著代碼屎山與日俱增,Node 的熵值也突破天際。
舉個栗子,臭名昭著的“npm 依賴地獄”,愛因斯坦看完都要重新審視相對論了。
圖片
再舉個栗子,Node 默認(rèn)的包管理工具 npm 差強人意,所以 Node 社區(qū)不得不“反復(fù)造輪子”,導(dǎo)致像我一樣的“選擇困難癥晚期患者”初學(xué) Node 時一臉懵逼:
“Node 之父” R.D. 后知后覺,等到它想優(yōu)化 Node 的時候,Node 已經(jīng)形成“劣幣驅(qū)逐良幣”的不可抗力,就像強人工智能吊打卷毛狒狒一樣暴走失控了。于是乎,“Node 之父”為了避免在 Node 中一邊開飛機(jī)一邊修飛機(jī),果斷切換賽道,化身成為“Deno 之父”。
作為“Node 之父”,R.D. 曾在公眾場合中毫無保留地公開處刑 Node 的“七大罪”,可謂罄竹難書、“父呲子笑”。反觀作為“Deno 之父”,R.D. 確實是模范爸爸。
Deno 是 JS/TS 的安全運行時,原生支持 TS,無需手動配置。與 Node 不同,Node 的腳本默認(rèn)具有廣泛的權(quán)限,Deno 則認(rèn)為“腳本千萬條,安全第一條”,要求開發(fā)者顯式賦予敏感操作的權(quán)限,比如文件系統(tǒng)的讀寫。這自然增加了我們的學(xué)習(xí)成本和心智負(fù)擔(dān),但 Deno 的魯棒性確實對 Node “降維打擊”。
Bun 的初衷大抵也是如此,為了對 Node 基建“降維打擊”,Bun 被設(shè)計為比 Node 更絲滑、更精簡的現(xiàn)代化競品,而不僅僅是備胎。
Node 主要使用 C艸 編寫,而 Bun 則使用 Zig (低階通用編程語言)編寫。本質(zhì)上而言,Bun 是一個 JS/TS 的運行時。所謂運行時,顧名思義就是一個提供使用和運行程序的環(huán)境。
運行時的關(guān)鍵組件之一是 JS 引擎,用于將 JS 代碼轉(zhuǎn)換為機(jī)器碼。Node 使用為 Chrome 瀏覽器提供支持的谷歌 V8 引擎,而 Bun 則使用 JSC(JavaScriptCore),此乃蘋果為 Safari 瀏覽器開發(fā)的開源 JS 引擎。
V8 和 JSC 各有千秋,兩者使用了不同的架構(gòu)和優(yōu)化策略。JSC 優(yōu)先考慮更快的啟動時間和更少的內(nèi)存占用,短板在于更慢的執(zhí)行時間。V8 優(yōu)先考慮更快的執(zhí)行和更多的運行時優(yōu)化,短板在于更多的內(nèi)存開銷。
圖片
如你所見,Bun 的運行性能比 Node 快 4.81 倍。
雖然 Node 是一個給力的 JS 運行時,但 Node 原生并不支持 TS。要在 Node 中跑 TS,需要訴諸第三方包。一種常見方案是,使用諸如 tsx/esbuild/babel 等依賴先將 TS 轉(zhuǎn)換為 JS,然后按需“優(yōu)雅降級”為低版兼容性代碼。
相比之下,Bun 內(nèi)置了 TS 轉(zhuǎn)譯器,原生支持 .js/.ts/.jsx/.tsx 文件,無需安裝任何外部依賴。Bun 的內(nèi)置轉(zhuǎn)譯器將各種亂七八糟的文件無縫轉(zhuǎn)換為平平無奇的 JS,無需額外步驟就能直接跑 TS。
尤其在跑 TS 文件時,這種性能跑分會被放大,因為 Node 在運行前需要足夠的前戲 —— 一個多余的轉(zhuǎn)譯步驟。
圖片
如你所見,Bun 跑 TS 時對 Node 生態(tài)“降維打擊”。
Node 生態(tài)的另一個“阿喀琉斯之踵”在于模塊系統(tǒng),模塊系統(tǒng)允許我們將代碼組織成可復(fù)用片段,目前人氣爆棚的兩個模塊系統(tǒng)是:
CJS 源自 Node,使用 require/module.exports 處理同步模塊,適合服務(wù)端操作。ES6 強勢引入 ESM 則采用 import/export 語法,提供靜態(tài)異步模塊,且可以針對 Vite 等現(xiàn)代構(gòu)建工具優(yōu)化,比如 tree-shaking(樹搖優(yōu)化)。
Node 原生支持 CJS,漸進(jìn)實驗性支持 ESM。作為前端愛好者,一般初戀都是瀏覽器,后來和 Node 貼貼可能會很折磨,因為 CJS 和 ESM 再次讓我們選擇困難,最終導(dǎo)致決策癱瘓。
在 Node 中使用 ESM 常見方案,包括但不限于:
Node 從 CJS 過渡到 ESM 走了很長的路,花了整整 5 年才在沒有實驗標(biāo)志的情況下支持 ESM。不管是學(xué)習(xí)成本、開發(fā)體驗還是心智模型,模塊的兼容性始終是壓在 Node 心頭的一只胖橘。
Bun 原生兼容 CJS/ESM,無需任何配置。Bun 的亮點功能是,它能夠在同一文件中同時支持 import/require(),類似于舊版 TS 的奇葩模塊語法,這在 Node 中是不可能事件:
// Bun 中的混合模塊語法import vue from 'vue'const react = require('react')
雖然但是,私以為混合模塊可能是“設(shè)計失誤”,或者說“在飆歷史倒車”。從兼容性看,混合模塊在技術(shù)上是一個自然延伸的功能,但對于用戶而言,拋開學(xué)習(xí)成本和心智模型不談,混合模塊明顯增加了維護(hù)的熵值。我的個人心證是,建議大家不管在瀏覽器還是 Node 中,都盡量擁抱標(biāo)準(zhǔn)的 ESM。
舉個栗子,Vite 是一個人氣爆棚的現(xiàn)代化工具,Vite 在開發(fā)環(huán)境擁抱標(biāo)準(zhǔn)的 ESM,在生產(chǎn)構(gòu)建則按需轉(zhuǎn)譯模塊語法。盡管如此,還是存在一大坨 corner case(極端用例),這是 Vite 使用 rollup 構(gòu)建時無法完美兼容的,尤大一度在 ViteConf 國際大會上瘋狂吐槽。老粉都知道,去年我共享的 Vite 前沿資訊有提及,Vite 已經(jīng)直接棄用 CJS。猶豫就會敗北,私以為 ESM 只會比 CJS 越來越流行,這就是標(biāo)準(zhǔn)的魔力,就像專一的鏟屎官更能被貓貓青睞。
總而言之,個人建議在使用 Bun 時,盡量避免使用混合模塊語法,因為一點也不符合人體工程學(xué)。
Vite 等現(xiàn)代化工具的福利之一是熱重載,在代碼更改時可以自動刷新或重新加載 App,無需完全重啟,真正做到一邊開飛機(jī)、一邊修飛機(jī),提高開發(fā)效率和開發(fā)體驗。
Node 以前原生不支持熱重載,常見方案包括但不限于:
雖然但是,nodemon 可能會中斷,比如斷開 HTTP 和 WebSocket 連接,而 --watch 還處于實驗階段。
Bun 使用 --hot flag 原生支持熱重載,與需要重啟整個進(jìn)程的 Node 不同,Bun 會就地重載代碼,而不會終止舊進(jìn)程。這可以確保 HTTP 和 WebSocket 的連接不間斷,并保留 App 狀態(tài),提供更絲滑的開發(fā)體驗。
除了 JS 的標(biāo)準(zhǔn)(比如模塊),對瀏覽器標(biāo)準(zhǔn)的 Web API(比如 WebSocket),Node 的支持也不一致。
舉個栗子,Node 的早期版本不支持瀏覽器中常用的 fetch API,我們必須依賴 node-fetch 等第三方模塊來“曲線救國”。雖然但是,Node 18+ 開始實驗性支持 fetch,目測未來可期。
Bun 則內(nèi)置支持這些 Web 標(biāo)準(zhǔn) API,我們可以直接使用穩(wěn)定的 fetch/Request/Response 等 API,無需任何額外依賴。由于這些 API 是 Bun 的原生實現(xiàn),所以其性能比第三方備胎更快、更可靠。
使用 Web 標(biāo)準(zhǔn) API 設(shè)置 HTTP 服務(wù)器或 WebSocket 服務(wù)器,它每秒處理的請求比 Node 多 4 倍,處理的 WebSocket 消息比 Node 的 ws 包多 5 倍。
簡而言之,Node 生態(tài)的大部分功能需要我們手動安裝第三方包來“曲線救國”,而 Bun 不僅原生支持,而且青出于藍(lán)。
Bun 本身還是一個功能強大的包管理器。
舉一反一,CRUD 相關(guān)命令不能說是毫無關(guān)系,只能說是一毛一樣:
Bun | npm | 目的 |
|
| 安裝 |
|
| 將新依賴添加到項目中 |
|
| 添加新的開發(fā)依賴 |
|
| 從項目中刪除依賴 |
|
| 將指定包更新到最新版本 |
|
| 從 |
Bun 的命令似曾相識,沒有壓力山大的學(xué)習(xí)成本,只有無縫銜接的開發(fā)體驗。而且 Bun 采用每個操作系統(tǒng)可用的最快系統(tǒng)調(diào)用,確保最佳性能,擁有比 npm 快幾個數(shù)量級的安裝速度,充分利用全局模塊緩存,消除從 npm 注冊表的冗余下載,從此告別“npm 黑洞”,愛因斯坦看完不用再重新審視相對論了。
本人現(xiàn)在使用的是 pnpm,但還是欲求不滿,但是 Bun 可以真正讓我們幸福感拉滿:
圖片
天下武功,唯快不破。如你所見,Bun 啪的一下很快啊就下載完了。
所謂打包,指的是是獲取多個 JS 文件,并將其合并到一個或多個優(yōu)化包中的過程。此過程還可能涉及轉(zhuǎn)換,比如將 TS 轉(zhuǎn)換為 JS,或者壓縮代碼減小體積。Node 的打包通常由第三方工具而不是 Node 本身處理。Node 生態(tài)目前有一大坨人氣爆棚的打包器,包括但不限于
它們都提供了代碼分割、樹搖優(yōu)化和熱模塊替換等功能。
Bun 本身也是一個打包器。它旨在打包各種平臺的 JS/TS 代碼,包括瀏覽器中的前端 App(Vue/React App)和 Node。Bun 比 esbuild 快 1.75 倍,并且對 Webpack 等其他打包器“降維打擊”。
圖片
Bun 的一個天秀功能是 JS 宏,這允許在打包期間執(zhí)行 JS 函數(shù),并將結(jié)果直接內(nèi)聯(lián)到最終打包中。
舉個栗子,在打包過程中利用 JS 宏來獲取貓貓的名字,該宏不是運行時的 API 調(diào)用,而是在打包時獲取數(shù)據(jù),將結(jié)果直接內(nèi)聯(lián)到最終產(chǎn)物中:
// cats.tsexport async function getCat() { const response = await fetch('https://space.bilibili.com/3493137875994964?spm_id_from=333.1245.0.0') const cat = await response.json() return cat.name}// index.ts// Bun 的 JS 宏import { getCat } from './cats.ts' with { type: 'macro' }const cat = await getCat()// build/index.js// 打包后直接內(nèi)聯(lián)數(shù)據(jù),比如貓貓的名字var cat = await '人貓神話'console.log(cat)
雖然 Node 一般依賴 Vitest/Jest 來滿足 TDD(測試驅(qū)動開發(fā)),但 Bun 內(nèi)置了測試運行器,它被設(shè)計為完全兼容 Jest。Jest 是一個以“expect”風(fēng)格 API 聞名的測試框架,這種兼容性確保熟悉 Vitest/Jest 愛好者可以無縫銜接到 Bun,沒有任何陡峭的學(xué)習(xí)曲線。
Bun 的測試運行器不僅涉及兼容性;還涉及速度。舉個栗子,Bun 中的 expect().toEqual() 比 Vitest 快 10 倍。
Bun 和 Node 目前測評跑分的異同點,包括但不限于:
對照實驗 | Node | Bun |
編程語言 | C艸 | Zig |
JS 引擎 | 谷歌 Chrome V8 | 蘋果 Safari JSC |
TS 轉(zhuǎn)譯 | 第三方包 | 原生支持 |
模塊系統(tǒng) | 從 CJS 過渡到 ESM | 原生支持混合模塊 |
fetch | 第三方包/實驗性支持 | 原生支持 |
熱重載 | 第三方包/實驗性標(biāo)志 | 原生支持 |
包管理器 | npm/pnpm | 原生支持 |
打包工具 | Vite | 原生支持 |
TDD | Vitest | 原生支持 |
Bun 目前的痛點(個人向),包括但不限于:
Node 憑借其成熟的生態(tài),一直在前端運行時穩(wěn)坐頭等艙,強如 Deno 也難以撼動其霸主地位。雖然但是,Bun 正以一位不容小覷的挑戰(zhàn)者身份嶄露頭角。雖然 Bun 還未成年,但它名噪一時毋庸置疑,目測是一只潛力股。目前,Bun 針對 MacOS 和 Linux 進(jìn)行了優(yōu)化,而 Windows 的支持正在進(jìn)行中。不幸的是,本人日常開發(fā)使用的偏偏是 Windows 系統(tǒng)......
本文鏈接:http://www.tebozhan.com/showinfo-26-70414-0.html為什么 Bun 可能對 Node 降維打擊?
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 轉(zhuǎn)轉(zhuǎn)基于MQ的分布式重試框架設(shè)計方案
下一篇: 大規(guī)模敏捷測試怎么做(集成篇)