跳至主要內容

Biome:一個工具取代 ESLint 和 Prettier

Biome:一個工具取代 ESLint 和 Prettier

JavaScript/TypeScript 專案的 linting 和格式化工具鏈一直是個令人頭疼的問題。ESLint 的設定複雜、Prettier 規則衝突、各種外掛相互依賴、版本升級常常破壞設定……這些問題每個前端工程師應該都經歷過。

Biome(前身是 Rome Tools)是一個用 Rust 寫成的高效能工具,目標是整合 linter、formatter、bundler 等工具於一身。目前最成熟的是它的 lint 和 format 功能,執行速度比 ESLint + Prettier 快上 25-35 倍,而且幾乎零設定就能使用。

安裝

# npm
npm install --save-dev --save-exact @biomejs/biome

# pnpm
pnpm add --save-dev --save-exact @biomejs/biome

# 初始化設定檔
npx @biomejs/biome init

這會建立 biome.json

{
  "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  }
}

基本指令

# 格式化(就地修改)
npx biome format --write .

# 只顯示差異,不修改
npx biome format .

# Lint 並自動修復
npx biome lint --write .

# 同時執行 format + lint + import 整理
npx biome check --write .

# 只針對特定檔案
npx biome check --write src/components/Button.tsx

與 ESLint 的差異

Biome 目前已實作超過 200+ 條 lint 規則,涵蓋大部分常用的 ESLint 規則:

{
  "linter": {
    "rules": {
      "recommended": true,
      "correctness": {
        "noUnusedVariables": "error",
        "noUnusedImports": "warn",
        "useExhaustiveDependencies": "warn"
      },
      "suspicious": {
        "noConsoleLog": "warn",
        "noDoubleEquals": "error"
      },
      "style": {
        "noVar": "error",
        "useConst": "error",
        "useTemplate": "warn",
        "noNonNullAssertion": "warn"
      },
      "performance": {
        "noAccumulatingSpread": "warn"
      },
      "a11y": {
        "useAltText": "error",
        "useKeyWithClickEvents": "error"
      }
    }
  }
}

與 Prettier 的差異

Biome 的格式化風格與 Prettier 非常接近,但有幾點不同:

{
  "formatter": {
    "enabled": true,
    "formatWithErrors": false,
    "indentStyle": "space",    // "space" | "tab"
    "indentWidth": 2,
    "lineEnding": "lf",        // "lf" | "crlf" | "cr"
    "lineWidth": 80,
    "attributePosition": "auto" // JSX 屬性換行策略
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "double",      // "double" | "single"
      "jsxQuoteStyle": "double",
      "semicolons": "always",       // "always" | "asNeeded"
      "trailingCommas": "all",      // "all" | "es5" | "none"
      "arrowParentheses": "always"  // "always" | "asNeeded"
    }
  }
}

忽略規則

{
  "linter": {
    "rules": {
      "style": {
        "noParameterAssign": "off"
      }
    }
  },
  "files": {
    "ignore": [
      "dist/**",
      "node_modules/**",
      "*.generated.ts"
    ]
  }
}

在程式碼中忽略特定行:

// biome-ignore lint/suspicious/noConsoleLog: 這裡需要 debug 輸出
console.log('debug info');

// biome-ignore lint: 忽略這行所有 lint 規則
const x = eval('code');

// biome-ignore format: 保持原有格式
const matrix = [
  1, 0, 0,
  0, 1, 0,
  0, 0, 1,
];

整合 VS Code

安裝 Biome VS Code 擴充功能後,在 .vscode/settings.json 中設定:

{
  "[javascript]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true
  },
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true
  },
  "editor.codeActionsOnSave": {
    "quickfix.biome": "explicit",
    "source.organizeImports.biome": "explicit"
  }
}

整合 Git Hooks(使用 lint-staged)

npm install --save-dev lint-staged husky
npx husky init

.husky/pre-commit

npx lint-staged

package.json

{
  "lint-staged": {
    "*.{js,ts,jsx,tsx,json,css}": [
      "biome check --write --no-errors-on-unmatched"
    ]
  }
}

整合 CI/CD

# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  biome:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'npm'
      - run: npm ci
      - name: Run Biome
        run: npx biome ci .
        # ci 模式:有問題時返回非零退出碼,不修改檔案

從 ESLint + Prettier 遷移

Biome 提供了遷移工具:

# 從 ESLint 遷移
npx @biomejs/biome migrate eslint --write

# 從 Prettier 遷移
npx @biomejs/biome migrate prettier --write

遷移後,可以移除相關依賴:

npm uninstall eslint prettier @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-prettier eslint-plugin-prettier
# 根據你的設定移除其他相關套件

Biome 的限制

目前 Biome 還不能完全取代 ESLint 的所有使用場景:

  1. 規則數量:雖然持續增加,但仍少於 ESLint 生態系的總規則數
  2. 框架特定規則:如 eslint-plugin-vueeslint-plugin-react-hooks 中一些框架特定規則
  3. 自訂規則:Biome 目前不支援撰寫自訂 lint 規則(ESLint 插件)
  4. TypeScript 型別感知規則:需要型別資訊的規則尚未完整支援

效能比較

在一個有 2000+ 個 TypeScript 檔案的專案上:

工具 執行時間
ESLint 45 秒
Prettier 12 秒
ESLint + Prettier 57 秒
**Biome** **1.8 秒**

差距相當顯著,特別是在 pre-commit hook 或 CI 環境中,這能大幅縮短等待時間。

總結

對於新專案,我會毫不猶豫地選擇 Biome——零設定、超快速、一個工具解決兩個問題。對於既有專案,如果你的 ESLint 設定不太複雜,遷移成本很低,值得投資。如果你深度依賴特定的 ESLint 插件,可以先觀望,等 Biome 的規則覆蓋率更高再考慮遷移。

分享這篇文章