Chapter 10

Domain 规则与 GritQL 进阶

Biome v2 引入的两大机制——Domain(领域规则组)让配置更语义化,GritQL 让你自己写规则。了解它们,Biome 就能完全取代 custom ESLint plugin。

10.1 Domain 是什么

过去规则都挂在"类别"下——correctnesssuspicious 等。这对"这个项目用什么框架"不敏感。Biome v2 补了一个垂直切片:Domain,按"框架/场景"聚合规则。

next
Next.js 专有规则——noImgElementnoHeadElementuseClientDirectivenoSyncScripts 等。
react
React 通用规则,Hook 依赖检查、key 必填、事件处理器命名等。
solid
SolidJS 反应性规则——noDestructuringProps 等。
test
测试场景——自动放宽一些规则(noExplicitAnynoExcessiveCognitiveComplexity),同时加严部分(noFocusedTests—禁止 .only 提交)。
project
项目级跨文件规则(需要 TS project 能力),比如 noPrivateImports

配置方法

{
  "linter": {
    "domains": {
      "next": "recommended",
      "react": "recommended",
      "test": "all"
    }
  }
}

取值:"none" | "recommended" | "all"。打开后该 domain 的规则会被批量启用;仍可在 rules 里单条覆盖级别。

10.2 基于类型推断的规则

ESLint 中的 @typescript-eslint/no-floating-promisesno-misused-promises 等需要类型信息——这些在 Biome v1 是不可能做的(Biome 不做类型检查)。

Biome v2 引入"轻量类型推断":不复现 tsc 的完整语义,但能沿着 AST 做基本的类型跟踪,足以发现 Promise 忘记 await、传错参数个数之类的典型问题。

{
  "linter": {
    "rules": {
      "nursery": {
        "noFloatingPromises": "error",
        "noMisusedPromises": "error"
      }
    }
  }
}

这些规则通常放在 nursery(孵化)分组,稳定后会升入正式分组。生产用要关注每次升级的 changelog。

10.3 GritQL:自己写规则

ESLint 时代自定义规则要发 npm 包 + 写 JS AST visitor。Biome 2025 推出了 GritQL 插件——一种小型 DSL,用声明式模式匹配 + 重写描述"这段代码要报错/这样改"。

例子 1:禁用 lodash.get,建议原生 optional chain

// .biome/plugins/no-lodash-get.grit
language js

pattern lodash_get_call() {
  `get($obj, $path)` where {
    $obj <: contains `lodash`
  } => `$obj?.$path`
}

pattern main() {
  lodash_get_call()
}

例子 2:禁止在 React Server Component 里调用 useState

language js

pattern no_usestate_in_server_component() {
  `useState` within file $f where {
    $f <: not contains `'use client'`
  } => log("useState 只能在 'use client' 文件里使用")
}

注册到 biome.json

{
  "plugins": ["./.biome/plugins/no-lodash-get.grit"]
}

下次跑 biome check,这条规则就像内置的一样工作——既能报告、也能 autofix(重写箭头 => 即重写逻辑)。

GritQL 的设计哲学

它不是通用图灵完备 DSL,而是 结构化查找替换。对大多数团队"禁用某 API"、"强制用某个 helper"、"补上 try-catch" 类场景足够;复杂逻辑仍建议维持 TypeScript 自定义规则(Biome 路线图上)。

10.4 CSS / GraphQL 支持

Biome v2 扩展到了 CSS 与 GraphQL:

{
  "css": {
    "formatter": { "enabled": true, "quoteStyle": "double" },
    "linter":    { "enabled": true }
  },
  "graphql": {
    "formatter": { "enabled": true },
    "linter":    { "enabled": true }
  }
}

CSS 规则覆盖 stylelint 常用项:noDuplicatePropertiesuseCssVariablenoUnknownUnit 等。

10.5 性能优化技巧

10.6 未来路线(2026+)

  1. TS 原生规则:更接近 tsc 的类型推断能力
  2. Markdown / YAML formatter
  3. Svelte / Vue / Astro 组件完整支持(目前仅部分)
  4. Bundler 级"project lint":跨文件的循环依赖、未使用导出
  5. 独立发布为 Rust crate:让 CLI 生态(Deno、Bun build)直接嵌入 Biome

10.7 实战清单:现代前端项目的"最佳 biome.json"

{
  "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
  "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
  "files": {
    "ignore": ["**/.next/**", "**/dist/**", "**/coverage/**", "**/*.gen.ts"]
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100,
    "lineEnding": "lf"
  },
  "organizeImports": { "enabled": true },
  "javascript": {
    "formatter": {
      "quoteStyle": "double",
      "jsxQuoteStyle": "double",
      "semicolons": "always",
      "trailingCommas": "all",
      "arrowParentheses": "always"
    }
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "suspicious": { "noExplicitAny": "warn" },
      "style": { "useConst": "error" },
      "complexity": { "noExcessiveCognitiveComplexity": { "level": "warn", "options": { "maxAllowedComplexity": 15 } } }
    },
    "domains": {
      "next": "recommended",
      "react": "recommended",
      "test": "recommended"
    }
  },
  "overrides": [
    {
      "include": ["**/*.test.ts", "**/*.spec.ts"],
      "linter": {
        "rules": { "suspicious": { "noExplicitAny": "off" } }
      }
    }
  ]
}

结语

走完十章,Biome 的图谱已经完整:一份 biome.json + 一个二进制 + 一个 LSP。它解决了前端工具链十年来"配置碎片 + JS 工具龟速"的老问题,并通过 v2 的 domain、GritQL、类型感知规则在不断靠近"ESLint 能做的它都能做、还更快"。

接下来你可以:

感谢阅读。古法编程团队祝你的仓库再无 lint 与 format 扯皮之日。