[筆記] Bun vs Node.js

janlin002
9 min readSep 28, 2023
Photo by Christiana Kamprogianni on Unsplash

在文章開始前非常推薦大家去看原文,我這邊只會幫大家把重點點出來,並且提出一些自己的想法

前陣子 Bun 發表 1.0.0 以後,馬上引起大家熱烈的討論,不過因為有了前面 Deno 的經驗,所以我選擇持續觀察,而不是一下就花費大量時間跟精力去研究這個新的 runtime

不過看最近持續有人在討論他,想說花點時間來研究看看:

什麼是 Bun?

Bun 是 JavaScript 的執行環境(runtime),就跟過去我們一直用的 Node.js 一樣,不過由於 Node.js 開發時間很長了,有很多設計沒有設計好,所以很多人都出來打造新的執行環境,像是 Node.js 的作者 Ryan Dahl 自己出來寫了 Deno ,還有 Oven 團隊開發了 Bun ,所以可以說是 Bun 是建立在 Node.js 的基礎上,做了更多更好的優化,讓我們可以在使用上有更快速地使用體驗

Bun 帶來了什麼?

和傳統的 Node.js 這種傳統的 runtime 不同,Bun 直接內置了打包器、轉譯器、任務運行器和 npm客戶端,言下之意就是我們不在需要 webpack、rollup、babel 、ts-node …,就可以直接使用 Jsx 跟 Ts 了,簡單來說就是把技能樹點滿

Bun 為什麼快?

和 Node.js, Deno 不同,Bun 並沒有延續使用 V8 引擎,而是直接選擇了 JavaScriptCore 引擎。

JavaScriptCore 引擎優先考慮如何擁有更快的啟動時間和減少記憶體使用。V8 引擎則是優先考慮快速執行,並進行更多運行時優化,這可能會導致更多記憶體使用。

另外,Bun 是用一種具有手動內存管理的低級編程語言 ZIG 編寫的,ZIG 是一種靜態類型、編譯型的語言,專注於性能。它提供了低級別的控制,允許我們直接操作內存,從而可以優化代碼實現最大的性能。

Deno 去哪了?

相信各位讀者有在關心前端趨勢的話,一定曾經被 Deno 燒到過,Deno 貴為 Node.js 作者的代表作之一,相信關注者的數量一定不在少數,但為什麼 Deno 雷聲大雨點小呢?難到 Deno 沒有一點值得學的地方嗎?

錯!Deno 提出了很多不錯的概念,其中最有力的賣點的大概就是對於 TypeScript 的支援性,不再像過去 Node.js 一樣,需要安裝各種套件,例如: ts-node ,才能運行,他可以原生支援 TypeScript,但由於 Deno 開發出來的功能對於原本的使用者來說只能算是 「次要功能」,所以使用者才沒有足夠的誘因轉換過去,或許哪天 Deno 推出了一個 Node.js 沒有的強大功能,大家就會紛紛開始學習 Deno 了

JavaScript runtime

前面一直提到 runtime 這個關鍵字,但相信很多人不知道意思,或是認為他是什麼執行時間,其實文中有對於 runtime 做了一個解釋,我覺得算是簡單易懂

A JavaScript runtime is an environment which provides all the necessary components in order to use and run a JavaScript program.

這邊大概翻譯一下,簡單來說就是就是提供一個環境讓你可以在裡面運行 JavaScript

像是我們都知道 JavaScript 中有一寫特定義的語法,例如: var, let, const,這些都是 JavaScript 的一部分。但是只有程式語言的話還不夠,我們還需要有個地方可以去使用它,而這個地方就叫做執 runtime,舉個例子,大家最常用的 runtime 就是「瀏覽器」。

而這個 runtime 會提供給你一些東西使用,例如說 DOM(document)、console.log、setTimeout,這些其實都不是 JavsScript 本身的一部分。

而我們前面一直提到的 Node.js , Bun, Deno 其實都算是一種 runtime

JavaScript engine

JavaScript 引擎是一種將我們編寫的 JavaScript 程式碼轉換為機器碼的程序,使電腦能夠執行特定的任務。
像是 Node.js 使用的是 Google 的 V8,Bun 使用的是 Safari 提供的 JavaScriptCore

Transpiler 編譯器
即使 Node.js 是當今最廣為人知的 runtime ,但最為人詬病的就是他不能原生支援 TypeScript (雖然越來越多大公司在放棄 TypeScript,但他還是有一定的好處的),如果我們需要在 Node.js 中使用 TypeScript ,會需要自己下載 ts-node 來編譯成 JavaScript。

不過這個問題在 Bun 裡面就被解決了,Bun 讓我們可以直接運行 TypeScript 的程式碼,然後會在背後自動幫我們轉成 JavaScript ,讓我們不需要自己額外去下載多餘的套件

ESM and CommonJS

相信各位前端的大大,都一定聽過一個古老的故事:在過去 JavaScript 還沒有模組化的時候,百家爭鳴,出現了很多的規範,像是: AMD、CommonJS、UMD,其中最有名的就是 Node.js 的 CommonJS 跟 ESM。

寫法上也有些許的不同,例如: CommonJS 必須使用 require 跟 module.esports,而 ESM 是使用 import 跟 export

不過 Bun 卻可以同時支援這兩種寫法

import react from "react";
const react = require("react");

Hot reloading

過去有一段時間,前端社群天天都在討論 hot reload ,到底 hot reload 是什麼?

Hot reload 是能夠對運行時的 JavaScript 模塊進行更新的一種技術,簡單來說就是在你程式碼寫完以後,不用自己手動去重整畫面,畫面就會自動更新

過去如果 Node.js 需要實現 Hot reload,有兩種方式:

  1. 使用 nodemon
  2. 使用 — watch,不過這個寫法只支援 Node.js 18 以後

Bun 卻原生提供了 — hot 寫法

bun --hot index.ts

Bun vs Node.js 套件管理
原文提供了一個非常清楚的表格,基本上 Bun 的寫法跟 yarn 是一樣的

試用

首先我們先下載 bun

curl -fsSL https://bun.sh/install | bash

下載完以後,我們建立一個 file 叫 index.ts

touch index.ts

有一點要注意是 ts 不是 js,主要是想要試用看看能不能直接使用 TypeScript
然後我們在 index.ts 裡面加入

export default {
port: 3000,
fetch(request) {
return new Response("Hi, Jan!Welcome to Bun!");
},
};

直接到 terminal 下指令

bun index.ts   

你會看到 http://localhost:3000/ 出現了 Hi, Jan!Welcome to Bun!

參考文章
https://www.builder.io/blog/bun-vs-node-js#strong-what-is-bun-strong

https://www.readfog.com/a/1674029026219495424

--

--