執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

JSON5

通過執行環境 API 和打包工具整合,使用 Bun 內建對 JSON5 檔案的支援

在 Bun 中,JSON5 與 JSON、TOML 和 YAML 一樣,是一等公民。你可以:

  • 使用 Bun.JSON5.parse 和 Bun.JSON5.stringify 解析和字串化 JSON5
  • 在執行環境將 JSON5 檔案作為模組 import 和 require(包括熱過載和監視模式支援)
  • 在前端應用中使用 Bun 的打包工具 import 和 require JSON5 檔案

相容性

Bun 的 JSON5 解析器使用 Rust 編寫,並通過了 官方 JSON5 測試套件中的 100% 測試。翻譯後的測試套件列出了每個測試用例。


執行環境 API

Bun.JSON5.parse()

將 JSON5 字串解析為 JavaScript 值。

TypeScript
import { JSON5 } from "bun";

const data = JSON5.parse(`{
  // JSON5 支援註釋
  name: 'my-app',
  version: '1.0.0',
  debug: true,

  // 允許尾隨逗號
  tags: ['web', 'api',],
}`);

console.log(data);
// {
//   name: "my-app",
//   version: "1.0.0",
//   debug: true,
//   tags: ["web", "api"]
// }

支援的 JSON5 特性

JSON5 是基於 ECMAScript 5.1 語法的 JSON 超集。它支援:

  • 註釋:單行(//)和多行(/* */)
  • 尾隨逗號:物件和陣列中
  • 未加引號的鍵:任何有效的 ECMAScript 5.1 識別符號
  • 單引號字串:除了雙引號字串之外
  • 多行字串:使用反斜槓進行換行延續
  • 十六進位制數:0xFF
  • 前導和尾隨小數點:.5 和 5.
  • Infinity 和 NaN:正數和負數
  • 顯式加號:+42
TypeScript
const data = JSON5.parse(`{
  // 未加引號的鍵
  unquoted: 'keys work',

  // 單引號和雙引號
  single: 'single-quoted',
  double: "double-quoted",

  // 尾隨逗號
  trailing: 'comma',

  // 特殊數字
  hex: 0xDEADbeef,
  half: .5,
  to: Infinity,
  nan: NaN,

  // 多行字串
  multiline: 'line 1 \
line 2',
}`);

錯誤處理

如果輸入不是有效的 JSON5,Bun.JSON5.parse() 會丟擲 SyntaxError:

TypeScript
try {
  JSON5.parse("{invalid}");
} catch (error) {
  console.error("解析 JSON5 失敗:", error.message);
}

Bun.JSON5.stringify()

將 JavaScript 值序列化為 JSON5 字串。

TypeScript
import { JSON5 } from "bun";

const str = JSON5.stringify({ name: "my-app", version: "1.0.0" });
console.log(str);
// {name:'my-app',version:'1.0.0'}

美化輸出

傳入 space 引數來格式化輸出並縮排:

TypeScript
const pretty = JSON5.stringify(
  {
    name: "my-app",
    debug: true,
    tags: ["web", "api"],
  },
  null,
  2,
);

console.log(pretty);
// {
//   name: 'my-app',
//   debug: true,
//   tags: [
//     'web',
//     'api',
//   ],
// }

space 引數可以是數字(空格數),也可以是字串(用作每一層的縮排字串):

TypeScript
// 使用製表符縮排
JSON5.stringify(data, null, "\t");

特殊值

與 JSON.stringify 不同,JSON5.stringify 會保留特殊數值:

TypeScript
JSON5.stringify({ inf: Infinity, ninf: -Infinity, nan: NaN });
// {inf:Infinity,ninf:-Infinity,nan:NaN}

模組匯入

ES 模組

可以直接將 JSON5 檔案作為 ES 模組匯入:

config.json5
{
  // 資料庫設定
  database: {
    host: "localhost",
    port: 5432,
    name: "myapp",
  },

  features: {
    auth: true,
    rateLimit: true,
    analytics: false,
  },
}

預設匯入

app.ts
import config from "./config.json5";

console.log(config.database.host); // "localhost"
console.log(config.features.auth); // true

命名匯入

可以將頂層屬性作為命名匯入進行解構:

app.ts
import { database, features } from "./config.json5";

console.log(database.host); // "localhost"
console.log(features.rateLimit); // true

CommonJS

也可以在 CommonJS 中使用 require 匯入 JSON5 檔案:

app.ts
const config = require("./config.json5");
console.log(config.database.name); // "myapp"

// 解構也支援
const { database, features } = require("./config.json5");

JSON5 熱過載

當你使用 bun --hot 執行應用程式時,Bun 會在 JSON5 檔案發生更改時重新載入它們:

config.json5
{
  server: {
    port: 3000,
    host: "localhost",
  },
  features: {
    debug: true,
    verbose: false,
  },
}
server.ts
import { server, features } from "./config.json5";

Bun.serve({
  port: server.port,
  hostname: server.host,
  fetch(req) {
    if (features.verbose) {
      console.log(`${req.method} ${req.url}`);
    }
    return new Response("Hello World");
  },
});

使用熱過載啟動:

terminal
bun --hot server.ts

打包工具整合

使用 Bun 打包時,打包工具會在建置時解析匯入的 JSON5 檔案,並將它們作為 JavaScript 模組包含在內:

terminal
bun build app.ts --outdir=dist

在建置時解析意味著:

  • 生產環境中無需承擔執行環境 JSON5 解析開銷
  • 更小的打包體積
  • 對未使用的屬性進行搖樹最佳化(命名匯入)

動態匯入

你可以動態匯入 JSON5 檔案:

TypeScript
const { default: config } = await import("./config.json5");