Bun v1.1.14 隆重登場!此版本修正了 63 個錯誤(解決了 519 個 👍 問題)。使用 bun patch
修補 node_modules。bun:sqlite
中無 ORM 的物件映射。將所有 fetch()
呼叫記錄為 curl
命令。Node.js 相容性改進。bun install 錯誤修正、bun:sqlite
錯誤修正、Windows 錯誤修正。以及更多內容。
我們正在舊金山招聘系統工程師,以打造 JavaScript 的未來!
先前版本
v1.1.13
修正了 97 個錯誤(解決了 211 個 👍 問題)。bun install、WebSocket 伺服器、fetch、worker_threads 的可靠性改進。worker_threads 現在支援 eval。URL.createObjectURL
、堆疊追蹤錯誤位置改進、多個bun install
修正v1.1.10
修正了 20 個錯誤。Windows 上未快取的 bun install 速度提升 2 倍。fetch()
使用的記憶體最多減少 2.8 倍。bun install、sourcemaps、Windows 可靠性改進和 Node.js 相容性改進的多項錯誤修正v1.1.0
Bundows。Windows 支援已推出!
安裝 Bun
curl -fsSL https://bun.dev.org.tw/install | bash
npm install -g bun
powershell -c "irm bun.sh/install.ps1|iex"
scoop install bun
brew tap oven-sh/bun
brew install bun
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun
升級 Bun
bun upgrade
bun patch
Bun v1.1.14 為 Bun 的套件管理器引入了一個新的子命令:bun patch
bun patch <pkg>
有時,相依性套件存在錯誤或缺少功能。您可以 fork 該套件、進行修改並發布。但對於一個小的變更來說,這需要大量工作。如果您不想維護 fork 版本怎麼辦?如果您想繼續接收來自原始套件的更新,但同時包含您的變更,又該怎麼辦?
bun patch
讓修改相依性套件變得容易,無需 fork 或 vendoring。變更會保存在 .patch
檔案中,這些檔案可以被審查、共享、版本控制,並在其他專案中重複使用。這些 .patch
檔案會在 bun install
時自動套用,結果會快取在 Bun 的 Global Cache 中。
若要開始使用,請執行 bun patch <pkg>
以修補套件。
bun patch is-even
bun patch v1.1.14
+ is-even@1.0.0
5 packages installed [3.00ms]
To patch is-even, edit the following folder:
node_modules/is-even
Once you're done with your changes, run:
bun patch --commit 'node_modules/is-even'
在內部,這會在 node_modules 中複製套件,並使用其自身的全新副本,與共享快取隔離。這讓您可以安全地編輯套件目錄中的檔案,而不會影響全域快取。
由於我們複製了套件,您可以在專案的 node_modules 資料夾中本機測試您的修補程式。這讓您可以輕鬆地迭代變更並驗證它們是否如預期般運作。
一旦您對變更感到滿意,請執行 bun patch --commit <pkg>
以儲存您的變更。
bun patch --commit is-even
當您執行 bun patch --commit is-even
時,Bun 會
- 產生包含您變更的修補程式檔案
- 將相依性新增至
package.json
中的"patchedDependencies"
- 將修補程式檔案儲存在專案根目錄下的
patches/
中
修補程式檔案使用標準 diff
格式,因此您可以像其他任何程式碼一樣審查、共享和進行版本控制。
diff --git a/index.js b/index.js
index 832d92223a9ec491364ee10dcbe3ad495446ab80..2a61f0dd2f476a4a30631c570e6c8d2d148d419a 100644
--- a/index.js
+++ b/index.js
@@ -1,14 +1 @@
-/*!
- * is-even <https://github.com/jonschlinkert/is-even>
- *
- * Copyright (c) 2015, 2017, Jon Schlinkert.
- * Released under the MIT License.
- */
-
-'use strict';
-
-var isOdd = require('is-odd');
-
-module.exports = function isEven(i) {
- return !isOdd(i);
-};
+module.exports = (i) => (i % 2 === 0)
感謝 @zackradisic 實作 bun patch
!
更佳的 bun:sqlite
此版本為 Bun 的內建 sqlite 模組 bun:sqlite
新增了多項改進。
使用 query.as(Class)
進行無 ORM 的物件映射
bun:sqlite
現在支援將查詢結果映射到類別的實例。這讓您可以將方法、getter 和 setter 附加到查詢結果,而無需使用 ORM。
import { Database } from "bun:sqlite";
const db = new Database("my.db");
class Tweet {
id: number;
text: string;
username: string;
get isMe() {
return this.username === "jarredsumner";
}
}
const tweets = db
.query("SELECT * FROM tweets")
.as(Tweet);
for (const tweet of tweets.all()) {
if (!tweet.isMe) {
console.log(`${tweet.username}: ${tweet.text}`);
}
}
屬性不需要預先在類別上定義(這裡只是為了讓範例更容易閱讀),而且查詢中欄位的順序並不重要。
這是一種將查詢結果映射到物件的輕量方式。在底層,它的運作方式類似於 Object.create
,這表示它不會呼叫建構子、執行預設初始化器,並且無法存取私有欄位。
as
方法在 Statement
類別上定義,因此您可以將其與 get
和 all
方法一起使用。重要的是要注意,這不是 ORM。它不管理關聯性、產生 SQL 或任何類似的東西。它只是讓查詢傳回類別實例而不是純物件。
運作方式
當您呼叫 query.as(Class)
時,Bun 會建立一個以類別原型為基礎的新物件,並將查詢結果指派給它。
const query = db.query("SELECT * FROM tweets").as(Tweet);
// Get the first row as a Tweet instance
const tweet: Tweet = query.get();
// Each row is a Tweet instance
const allTweets: Tweet[] = query.all();
使用 strict: true
進行更簡化的查詢綁定
此版本為 Database
建構子新增了一個新的 strict?: boolean
選項,讓您在將值綁定到預先處理的語句時,可以省略 $
、@
或 :
前綴。
import { Database } from "bun:sqlite";
const db = new Database(":memory:", {
strict: false,
strict: true,
});
const query = db.query(`select $message;`);
query.all({
$message: "Hello world"
message: "Hello world"
});
當 strict: true
時,如果查詢缺少任何綁定,將會拋出錯誤。
為了保持向後相容性,strict
預設為 false。建議在新專案中啟用此選項。
使用 query.run(sql)
追蹤變更
Database
和 Statement
上的 run
方法現在會傳回一個具有 changes
和 lastInsertRowid
屬性的物件。這讓追蹤變更和取得最後插入的列 ID 變得更容易。
import { Database } from "bun:sqlite";
const db = new Database(":memory:");
db.run(`CREATE TABLE hey ( id INTEGER, data TEXT)`);
const { changes, lastInsertRowid } = db.run(
`insert into hey (id, data) values (1, 'foo')`,
);
console.log({
changes, // => 1
lastInsertRowid, // => 1
});
這在驗證查詢是否已對資料庫進行變更時非常重要。先前,run
會傳回 undefined
。
使用 safeIntegers: true
的 BigInt
當 safeIntegers
為 true
時,bun:sqlite
將會以 bigint
類型傳回整數。
import { Database } from "bun:sqlite";
const db = new Database(":memory:", { safeIntegers: true });
const query = db.query(
`SELECT ${BigInt(Number.MAX_SAFE_INTEGER) + 102n} as max_int`,
);
const result = query.get();
console.log(result.max_int); // => 9007199254741093n
這些整數必須在 64 位元範圍內。如果輸入超出此範圍,bun:sqlite
將會拋出錯誤。
import { Database } from "bun:sqlite";
const db = new Database(":memory:", { safeIntegers: true, strict: true });
db.run("CREATE TABLE test (id INTEGER PRIMARY KEY, value INTEGER)");
const query = db.query("INSERT INTO test (value) VALUES ($value)");
try {
query.run({ value: BigInt(Number.MAX_SAFE_INTEGER) ** 2n });
} catch (e) {
console.log(e.message); // => BigInt value '81129638414606663681390495662081' is out of range
}
有時,您只希望特定查詢具有此行為。safeIntegers
方法在 Statement
上可用。
import { Database } from "bun:sqlite";
const db = new Database(":memory:", { strict: true });
const query = db.query("SELECT $value as value").safeIntegers(true);
const result = query.get({ value: BigInt(Number.MAX_SAFE_INTEGER) + 102n });
console.log(result.value); // => 9007199254741093n
已修正:query.values() 在處理重複欄位名稱時的問題
一個錯誤導致在呼叫 query.values()
時,重複的欄位名稱被忽略。此問題已修正。
import { Database } from "bun:sqlite";
const db = new Database();
const result = db.prepare("select 1 as id, 2 as id").values();
console.log(result);
已修正
[
[ 1, 2 ]
]
先前
[
[ 2 ]
]
此錯誤最常在使用 JOIN 時發生。
已修正:bun:sqlite
在使用表格 JOIN 時崩潰的問題。
在聯結具有重複欄位的表格時,有時會發生的崩潰問題已修正。這會影響使用 Drizzle 的 bun:sqlite
驅動程式和 .leftJoin
。
bun install 可靠性
已修正:Tarball 下載失敗時以非零程式碼結束的問題
當 tarball 下載失敗時,bun install
會以零結束代碼退出。此問題已修正。當任何 HTTP 請求失敗時,bun install
現在將以非零結束代碼退出,以便 CI 系統停止建置。
已修正:bun install
處理過渡性資料夾相依性的問題
有時,套件會發布到 npm 註冊表,並帶有 file:
相依性。有時
感謝 @dylan-conway 修正此問題。
已修正:bun install
解壓縮錯誤修正
.tar.gz
封存檔有可能包含同一目錄的多個條目(一個帶有 ./
,一個沒有)。Bun 現在在解壓縮時會處理此情況,而不是報告它要解壓縮到的目錄已存在的錯誤。
感謝 @dylan-conway 修正此問題。
已修正:在 workspace 中使用 bun install --production
時,會包含 devDependencies 的問題
當 --production
傳遞給 workspace 中的 bun install
時,workspace 套件的開發相依性會包含在安裝中。現在已不再如此。
同時也修正了在這種情況下的斷言失敗。
已修正:在 Windows 上未傳遞 npm_config_user_agent
的問題
為了讓專案初始化腳本(如 create-next-app
)知道要使用哪個套件管理器,套件管理器應設定 npm_config_user_agent
環境變數。Windows 上的 Bun 並非總是將修改後的環境變數傳遞給子進程,因此此問題已修正。
例如,在 Windows 上建立新的 Next.js 專案將正確地告知 Next.js 使用 bun install
。
PS> bun create next-app
✔ What is your project named? … my-app
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Creating a new Next.js app in D:\Projects\my-app.
-Using npm.
+Using bun.
Initializing project with template: app-tw
感謝 @SunsetTechuila 修正此問題。
偵錯 fetch()
此版本新增了一個新的環境變數,以協助偵錯使用 fetch()
或 node:http
時的網路流量。
當 BUN_CONFIG_VERBOSE_FETCH=1
作為環境變數傳遞時,Bun 將記錄所有通過 fetch
和 node:http
用戶端的網路流量。
將 fetch() 印成 curl
命令
當 BUN_CONFIG_VERBOSE_FETCH=curl
設定為環境變數時,Bun 將把所有通過 fetch
和 node:http
用戶端的網路流量印成 curl
命令。
process.env.BUN_CONFIG_VERBOSE_FETCH = "curl";
await fetch("https://example.com", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ foo: "bar" }),
});
這會將 fetch
請求印成 curl
命令,讓您可以複製貼上到終端機中以重現請求。
[fetch] $ curl --http1.1 "https://example.com/" -X POST -H "content-type: application/json" -H "Connection: keep-alive" -H "User-Agent: Bun/1.1.14" -H "Accept: */*" -H "Host: example.com" -H "Accept-Encoding: gzip, deflate, br" --compressed -H "Content-Length: 13" --data-raw "{\"foo\":\"bar\"}"
[fetch] > HTTP/1.1 POST https://example.com/
[fetch] > content-type: application/json
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.1.14
[fetch] > Accept: */*
[fetch] > Host: example.com
[fetch] > Accept-Encoding: gzip, deflate, br
[fetch] > Content-Length: 13
[fetch] < 200 OK
[fetch] < Accept-Ranges: bytes
[fetch] < Cache-Control: max-age=604800
[fetch] < Content-Type: text/html; charset=UTF-8
[fetch] < Date: Tue, 18 Jun 2024 05:12:07 GMT
[fetch] < Etag: "3147526947"
[fetch] < Expires: Tue, 25 Jun 2024 05:12:07 GMT
[fetch] < Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
[fetch] < Server: EOS (vny/044F)
[fetch] < Content-Length: 1256
您可以使用此功能來偵錯網路請求、重現網路請求,或檢查不同的 JavaScript/TypeScript 工具在網路上傳送的內容,而無需設定代理。
Node.js 相容性改進
node:fs/promises
函式現在接受 FileHandle
使用 node:fs/promises
時,readFile
、writeFile
和 appendFile
函式接受 FileHandle
物件作為輸入。
import { open, readFile } from 'node:fs/promises';
using file = await open("example.txt", "rw");
const contents = await readFile(file);
console.log(contents);
await writeFile(file, `New data: ${Math.random()}\n`);
感謝 @nektro 實作此功能。
process.env.NODE_TLS_REJECT_UNAUTHORIZED
您現在可以在執行時設定 process.env.NODE_TLS_REJECT_UNAUTHORIZED
,以停用或啟用 SSL 憑證驗證。這對於測試或偵錯很有用,但不應在生產環境中啟用。
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
await fetch("https://self-signed.badssl.com"); // no error
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "1";
await fetch("https://self-signed.badssl.com"); // throws error
先前,此環境變數只能在啟動時傳遞。現在,可以在執行時設定。
已修正:node:http
/ express
中的停滯問題
一個影響 node:http 伺服器的錯誤,其中 req.completed
從未設定為 true,會導致 Express 中的某些請求無限期停滯。感謝 @cirospaciari,此問題已修正
已修正:blob.type
競爭條件有時會導致來自 fetch
的 blob.type
變成 undefined
。感謝 @cirospaciari,此問題現已解決。
const blob = await fetch("https://bun.dev.org.tw/logo.svg").then((res) => res.blob());
console.log("Blob type is:", blob.type);
已修正:blob.name
可寫入
您現在可以設定 Blob
物件上的 name
屬性。
const blob = await fetch("https://bun.dev.org.tw/logo.svg").then((res) => res.blob());
blob.name = "bun!!!!!";
console.log(blob.name); // "bun!!!!!"
先前,設定 blob.name
會拋出 TypeError
1 | const blob = await fetch("https://bun.dev.org.tw/logo.svg").then((res) => res.blob());
2 | blob.name = "bun!!!!!";
^
TypeError: Attempted to assign to readonly property.
已修正:透過 SSL 的 WebSocket 處理大型二進位酬載的問題
先前,當透過 wss://
WebSocket 連線傳送大型二進位酬載時,訊息可能未被傳送。這是因為未從 BoringSSL 呼叫 set_retry_write
。感謝 @cirospaciari 修正此問題。
已修正:Bun 不再使 Windows 終端機崩潰
在 Windows 上,ENABLE_VIRTUAL_TERMINAL_INPUT
旗標始終在主控台輸入上啟用。如果在退出前不移除此旗標,大多數 shell 會崩潰(cmd.exe
方向鍵失效、Powershell 經常崩潰、nu
無法接受新行等)。此旗標已移除,因為 Bun 不再需要設定此旗標來處理其輸入(prompt()
、node:readline
、bun init
等)。
感謝 @paperclover 修正此問題。
已修正:WebSocket 標頭大小寫與 node 不一致的問題
先前,使用 new WebSocket
會將所有標頭轉換為小寫文字。這對於某些期望標頭具有特定大小寫的伺服器造成了一些問題,即使標頭本應不區分大小寫。現在,知名的標頭將被標準化為其標準形式,而自訂標頭將保留其精確的大小寫。
例如
const ws = new WebSocket("ws://127.0.0.1:3000", {
headers: {
"Origin": "https://127.0.0.1:3000",
"authorization": "password",
"X-some-Other-header": "bun!",
},
});
將傳送這些標頭
> Origin: https://127.0.0.1:3000
> Authorization: password
> X-some-Other-header: bun!
感謝 @cirospaciari 修正此問題。
已修正:Bun Shell 中的記憶體洩漏
已修正影響 Bun Shell 的記憶體洩漏。這會導致 shell 物件永遠不會被垃圾回收,從而阻止記憶體被回收。
已修正:error.line 的回歸問題
一個 error.line
和 error.column
會傳回 0
的錯誤已修正。此回歸問題是在 v1.1.13
中引入的。