我們正在招募 C/C++ 和 Zig 工程師,一同打造 JavaScript 的未來!加入我們的團隊 →
上週,我們在 Bun v0.6.0 中推出了全新的 JavaScript 打包器。
今天,我們推出了對 CommonJS 的原生執行階段支援、Bun.build()
中更聰明的 CommonJS -> ES 模組轉換、bun run 中的 $npm_lifecycle_event
、Bun.serve() 串流檔案的錯誤修正、createConnection
(在 node:net
中) 的錯誤修正以及更多內容
curl -fsSL https://bun.dev.org.tw/install | bash
npm install -g 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
原生 CommonJS 執行階段支援
我們已在 Bun 中重新實作 CommonJS 支援,從僅限轉譯器支援改為在執行階段中原生支援。這修正了許多阻礙 npm 套件在 Bun 中運作的錯誤,並提高了與 Node.js 的相容性。
以下是 3 個因此解除封鎖的套件
Vue
先前,導入 Vue 會回報缺少匯出錯誤。感謝原生的 CommonJS 支援,Vue 現在可以開箱即用。
在 Bun v0.6.5 中
3.3.4
import {version} from "vue";
console.log(version);
在 Bun v0.6.4 及更早版本中
import {version} from "vue";
console.log(version);
> SyntaxError: Import named 'version' not found in module './node_modules/vue/index.mjs'.
Winston logger
先前,嘗試使用 Winston logger 時,Bun 會拋出錯誤。現在,它可以開箱即用。
在 Bun v0.6.5 中
info: What time is the testing at? {"service":"user-service"}
import winston from "winston";
const logger = winston.createLogger({
level: "info",
format: winston.format.json(),
defaultMeta: { service: "user-service" },
transports: [
//
// - Write all logs with importance level of `error` or less to `error.log`
// - Write all logs with importance level of `info` or less to `combined.log`
//
new winston.transports.File({ filename: "error.log", level: "error" }),
new winston.transports.File({ filename: "combined.log" }),
],
});
//
// If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
//
logger.add(
new winston.transports.Console({
format: winston.format.simple(),
})
);
logger.log({
level: "info",
message: "What time is the testing at?",
});
在 Bun v0.6.4 及更早版本中
1 | import winston from "winston";
2 |
3 | winston.format.json();
^
TypeError: undefined is not an object (evaluating 'winston.format.json')
input.js:3:0
Viem
先前,導入 "viem"
會拋出 ReferenceError
。感謝原生的 CommonJS 支援,viem 現在可以如預期載入。
在 Bun v0.6.5 中
[Function: createClient]
import { createClient } from "viem";
console.log(createClient);
在 Bun v0.6.4 及更早版本中
11 | if (param.type.startsWith("tuple"))
12 | return `(${formatAbiParams(param.components, { includeName })})${param.type.slice(5)}`;
13 | return param.type + (includeName && param.name ? ` ${param.name}` : "");
14 | };
15 |
16 | var {InvalidDefinitionTypeError} = import.meta.require("viem/dist/esm/errors/abi.js");
^
ReferenceError: Cannot access uninitialized variable.
input.js:16:0
具體來說,變更了什麼?
先前,Bun 會將 CommonJS 模組轉譯成如下形式的 ES 模組
// Bun v0.6.4 and earlier wrapper:
import { cjs2ESM } from "bun:wrap";
export default cjs2ESM((module, exports) => {
/* ...code */
});
另外,所有對這些模組的 import
都會被重寫,以檢查它是否為 CommonJS 模組,如果是,則呼叫該函數並傳回 CommonJS 匯出,而不是 ES 模組匯出。
該步驟有錯誤。在我們解析原始碼之前,我們並不總是知道模組是否為 CommonJS。package.json
有一些提示,但很多時候並不準確。
在 Node.js 中,靜態已知的 CommonJS 匯出會變成具名的 ES 模組匯出。例如,module.exports = { a: 'b' }
會變成 export const a = 'b'
。我們忽略了在 Bun 中執行此操作,而是使用轉譯器來重寫 CommonJS 模組的用法,以直接使用 module.exports
。這種方法無法正確處理 export * from
或 export * as
。有時我們也無法偵測到 CommonJS 模組 (或錯誤地假設 ES 模組是 CommonJS)。
因此,我們從頭開始重新實作了所有這些運作方式。
現在,當 Bun 的 JavaScript 執行階段偵測到 CommonJS 模組時
- 將模組包裝在一個以
module
和exports
作為參數的函數中。
(function (module, exports, require) {
/* ...code */
})(module, exports, require);
執行產生的函數
將
exports
的屬性附加為具名的 ES 模組匯出。
這表示 export * from '...'
和 export * as ...
可以如預期運作。此外,Bun 現在也支援依賴「寬鬆模式」功能 (如 with
) 和隱含全域變數賦值的套件。與之前一樣,您可以繼續在 ES 模組中使用 import
和 require
。
打包器中更聰明的 CommonJS -> ESM 轉換
與執行階段 CommonJS 變更無關,我們也讓 Bun.build()
在將 CommonJS 模組轉換為 ES 模組方面變得更聰明。
在 Bun 的下一個版本中
— Jarred Sumner (@jarredsumner) 2023 年 5 月 28 日
"bun build" 中的 CommonJS -> ESM 轉換變得更聰明一點。
現在它可以處理 "module.exports = { a: 'b' }" 了 pic.twitter.com/6wv23buf1t
bun run 中的 $npm_lifecycle_event
您現在可以在 bun run
腳本中存取 $npm_lifecycle_event
。$npm_lifecycle_event
環境變數會設定為執行的腳本名稱。這對於偵測執行了哪個 package.json 腳本非常有用。
bun run hey
hey
console.log(process.env.npm_lifecycle_event);
感謝 @TiranexDev 的貢獻!
Bun.serve() 串流檔案的錯誤修正
Bun 現在全域忽略 SIGPIPE
信號,這修正了一個錯誤,該錯誤會導致在 Linux 上使用 new Response(Bun.file(path))
串流檔案時,當客戶端提早斷線時 Bun 可能會崩潰。
node:net
中 createConnection
的錯誤修正
這修正了 node:net
中的參數解析問題,該問題導致 createConnection
在某些情況下失敗。感謝 @cirospaciari 的貢獻!
轉譯器與打包器錯誤修正
Bun 先前錯誤地將 Symbol["for"]
和其他幾十個透過靜態已知計算屬性字串文字存取的全域無副作用 getter 轉譯為 undefined
。此問題已修正。此錯誤是在 Bun v0.6.0 中引入的,並在 v0.6.4 中開始影響 Bun 的 JavaScript 執行階段。感謝 @zloirock 回報此問題。