biome-gritql

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Biome GritQL Custom Lint Rules

Biome GritQL 自定义Lint规则

Create AST-based custom lint rules using Biome's GritQL plugin system.
使用Biome的GritQL插件系统创建基于AST的自定义lint规则。

Quick Start

快速开始

Create a rule file (
rules/no-use-effect-fetch.grit
):
gritql
`useEffect($callback, $deps)` where {
    $callback <: contains `fetch`,
    register_diagnostic(
        span = $callback,
        message = "Don't fetch inside useEffect. Use TanStack Query instead.",
        severity = "error"
    )
}
Add to
biome.json
:
json
{
  "plugins": ["./rules/no-use-effect-fetch.grit"]
}
Run:
bunx biome check
or any equivalent command to run linter in the codebase
创建规则文件(
rules/no-use-effect-fetch.grit
):
gritql
`useEffect($callback, $deps)` where {
    $callback <: contains `fetch`,
    register_diagnostic(
        span = $callback,
        message = "Don't fetch inside useEffect. Use TanStack Query instead.",
        severity = "error"
    )
}
添加至
biome.json
json
{
  "plugins": ["./rules/no-use-effect-fetch.grit"]
}
运行:
bunx biome check
或其他等效命令来在代码库中运行linter

GritQL Syntax

GritQL语法

Basic Pattern Matching

基础模式匹配

gritql
`pattern_to_match` where {
    register_diagnostic(
        span = $matched_var,
        message = "Your message here",
        severity = "error"  // hint | info | warn | error
    )
}
make sure to read documentation
gritql
`pattern_to_match` where {
    register_diagnostic(
        span = $matched_var,
        message = "Your message here",
        severity = "error"  // hint | info | warn | error
    )
}
请务必阅读文档

Variables

变量

  • $name
    - captures any single node
  • $args
    - captures arguments
  • $_
    - wildcard (match but don't capture)
  • $name
    - 捕获任意单个节点
  • $args
    - 捕获参数
  • $_
    - 通配符(匹配但不捕获)

Operators

操作符

OperatorMeaning
<:
matches / contains
<: contains
deep contains
<: r"regex"
regex match
not
negation
and
both conditions
or
either condition
操作符含义
<:
匹配 / 包含
<: contains
深度包含
<: r"regex"
正则匹配
not
取反
and
同时满足条件
or
满足任一条件

Common Rule Patterns

常见规则模式

Ban a Function Call

禁用函数调用

gritql
`console.log($args)` where {
    register_diagnostic(
        span = $args,
        message = "Remove console.log before committing",
        severity = "warn"
    )
}
gritql
`console.log($args)` where {
    register_diagnostic(
        span = $args,
        message = "Remove console.log before committing",
        severity = "warn"
    )
}

Ban a Hook (React)

禁用Hook(React)

gritql
`useMemo($args)` where {
    register_diagnostic(
        span = $args,
        message = "useMemo unnecessary with React Compiler. Remove it.",
        severity = "warn"
    )
}
gritql
`useMemo($args)` where {
    register_diagnostic(
        span = $args,
        message = "useMemo unnecessary with React Compiler. Remove it.",
        severity = "warn"
    )
}

Ban Dynamic Imports

禁用动态导入

gritql
`await import($path)` where {
    register_diagnostic(
        span = $path,
        message = "Use static imports at the top of the file",
        severity = "error"
    )
}
gritql
`await import($path)` where {
    register_diagnostic(
        span = $path,
        message = "Use static imports at the top of the file",
        severity = "error"
    )
}

Require Pattern in Context

要求上下文模式

gritql
`useState($initial)` where {
    not $initial <: contains `atom`,
    register_diagnostic(
        span = $initial,
        message = "Prefer Jotai atoms over useState for shared state",
        severity = "info"
    )
}
gritql
`useState($initial)` where {
    not $initial <: contains `atom`,
    register_diagnostic(
        span = $initial,
        message = "Prefer Jotai atoms over useState for shared state",
        severity = "info"
    )
}

CSS Rules

CSS规则

gritql
language css;

`$selector { $props }` where {
    $props <: contains `color: $color` as $rule,
    not $selector <: r"\.color-.*",
    register_diagnostic(
        span = $rule,
        message = "Use .color-* utility classes instead of explicit colors"
    )
}
gritql
language css;

`$selector { $props }` where {
    $props <: contains `color: $color` as $rule,
    not $selector <: r"\.color-.*",
    register_diagnostic(
        span = $rule,
        message = "Use .color-* utility classes instead of explicit colors"
    )
}

Project Structure

项目结构

project/
├── biome.json
└── rules/
    ├── no-console-log.grit
    ├── no-use-memo.grit
    ├── no-use-callback.grit
    ├── no-dynamic-import.grit
    └── no-fetch-in-effect.grit
project/
├── biome.json
└── rules/
    ├── no-console-log.grit
    ├── no-use-memo.grit
    ├── no-use-callback.grit
    ├── no-dynamic-import.grit
    └── no-fetch-in-effect.grit

biome.json Configuration

biome.json配置

json
{
  "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
  "plugins": [
    "./rules/no-console-log.grit",
    "./rules/no-use-memo.grit",
    "./rules/no-use-callback.grit"
  ],
  "linter": {
    "enabled": true
  }
}
json
{
  "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
  "plugins": [
    "./rules/no-console-log.grit",
    "./rules/no-use-memo.grit",
    "./rules/no-use-callback.grit"
  ],
  "linter": {
    "enabled": true
  }
}

Creating Rules Workflow

规则创建流程

  1. Identify the pattern to ban/enforce
  2. Create
    .grit
    file in
    rules/
    directory
  3. Write the GritQL pattern with clear error message
  4. Add path to
    biome.json
    plugins array
  5. Test with
    bunx biome check
    or any equivalent command to run linter in the codebase
  1. 确定要禁用/强制执行的模式
  2. rules/
    目录中创建
    .grit
    文件
  3. 编写带有清晰错误提示的GritQL模式
  4. 将路径添加至
    biome.json
    的plugins数组
  5. 使用
    bunx biome check
    或其他等效命令在代码库中运行linter进行测试

Guidelines

指导原则

  • Keep error messages actionable - tell the user what to do instead
  • Use
    severity = "error"
    for hard requirements,
    "warn"
    for preferences
  • Put all
    .grit
    files in a
    rules/
    directory
  • Name files descriptively:
    no-X.grit
    or
    prefer-Y.grit
  • Test rules against real code before committing
  • 错误提示要具备可操作性——告诉用户应该怎么做
  • 对于硬性要求使用
    severity = "error"
    ,对于偏好性要求使用
    "warn"
  • 将所有
    .grit
    文件放在
    rules/
    目录中
  • 文件命名要具有描述性:
    no-X.grit
    prefer-Y.grit
  • 在提交前针对真实代码测试规则

Why This Matters

为何这很重要

Instructions in CLAUDE.md degrade as context fills up. Linter rules provide immediate, persistent feedback. When Claude violates a pattern, it sees the error and self-corrects - no context drift.
CLAUDE.md中的说明会随着上下文填充而失效。Linter规则能提供即时、持久的反馈。当Claude违反模式时,它会看到错误并自我修正——不会出现上下文漂移问题。

Resources

资源