Closed9
GritQL を使って Biome の Plugin を書いてみる

試しに Hello world とマッチする GritQL を書いてみる
no-hello-world-console.grit
`console.log("Hello, world!")`
test.js
console.log("Hello, world!");
biome.jsonc
{
"$schema": "https://biomejs.dev/schemas/2.0.6/schema.json",
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"linter": {
"enabled": true,
"rules": {
"recommended": false,
"suspicious": {
// "noConsole": "warn"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
},
"assist": {
"enabled": false
},
"plugins": ["./plugins/no-hello-world-console.grit"]
}
Lint を実行しても警告が出てくれない。
全く同じ構文で biome search コマンドを実行するという検知してくれる。

他の書き方を試したがこれも警告が出ない。
`console.log($message)`
`console.$method($message)` where {
$method <: `log`
}
どちらとも biome search
では検知される。

no-object-assign.grit
`$fn($args)` where {
$fn <: `Object.assign`,
register_diagnostic(
span = $fn,
message = "Prefer object spread instead of `Object.assign()`"
)
}
test.js
Object.assign({}, { a: 1, b: 2 });
Linter プラグインの例にあるパターンを試したら動いた。

CSS 用のルールを書く場合は一番上に language の指定が必要。
no-explicit-colors.grit
language css;
`$selector { $props }` where {
$props <: contains `color: $color` as $rule,
not $selector <: r"\.color-.*",
register_diagnostic(
span = $rule,
message = "Don't set explicit colors. Use `.color-*` classes instead."
)
}
test.css
a {
color: red;
}
.color-primary {
color: blue;
}
.color-secondary {
color: green;
}
この場合 .color-*
クラス以外で色を設定すると警告が出る。

単純にノードを使ってマッチングするだけじゃだめで register_diagnostic() を使って、
-
span
: 警告対象のノード -
message
: エラーメッセージ -
severity
: 重要度 (オプショナル)
を指定する必要がある。
最初の console.log
に対する Plugin はこれがないから何も表示されなかった。
no-hello-world-console.grit
`console.log($args)` where {
$args <: `"Hello, world!"`,
register_diagnostic(
span = $args,
message = "Avoid using console.log('Hello, world!') in production code",
severity = "error"
)
}
無事に動いた。

no-console.grit
`console.$method($args)` where {
register_diagnostic(
span = $method,
message = "Don't use console methods in production code",
severity = "warn"
)
}
console*
を一括で禁止したい場合は上記のように Metavariables を使って書くことができる。

感想や気になったことなど
- ESLint の
no-restricted-syntax
みたいに AST Explorer 使って、サクッと書くみたいな方法があるのかな。ある程度は Metavariables でカバーできそうな気もするけど。 - テストがマークダウンと YAML しかサポートされてなさそう?
- Pattern Modifiers や Conditional Operators を使った複雑なクエリも試したい
-
Rewrites の例にあるように lint error の autofix 対応がしやすそう
- こういうやつ
`console.log($my_message)` => `winston.info($my_message)`
- こういうやつ
-
Playground 使おうとしたら壊れてた😇

今回試したリポジトリ
このスクラップは3ヶ月前にクローズされました