Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
怖くない!GritQLでBiomeプラグインを作ろうよ
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
晴れ井戸
July 23, 2025
Technology
570
1
Share
怖くない!GritQLでBiomeプラグインを作ろうよ
2025/7/23に開催された、Biome v2リリース記念 公式LTパーティ のLT発表資料です
晴れ井戸
July 23, 2025
More Decks by 晴れ井戸
See All by 晴れ井戸
JSX - 歴史を振り返り、⾯⽩がって、エモくなろう
pal4de
5
1.4k
Other Decks in Technology
See All in Technology
AI時代の私の技術インプットとアウトプット術
tonkotsuboy_com
15
7.4k
NFLコンペ2026 解法
lycorptech_jp
PRO
0
120
A Harness for Behaviour: how to get AI to generate code that does what we intend, or "TDD in the age of AI"
xpmatteo
0
480
シンデレラなんかになりたくない!ガラスの靴が割れた時代にどう歩く?
nomizone
0
210
AI活用の格差をなくす:チーム全体のAI開発生産性を底上げする方法
moongift
PRO
1
120
Oracle Cloud Infrastructure:2026年5月度サービス・アップデート
oracle4engineer
PRO
1
200
CloudFront VPCオリジンとVPC Latticeサービスの内部ALBをマルチアカウントで一元利用しよう
duelist2020jp
5
250
GitHub Copilot のこれまでとこれから: From Copilot to Collaborative Agents
yuriemori
1
220
JEP 522 Deep Dive - G1 GC同期コスト削減によるスループット向上を徹底検証&解説
tabatad
1
210
個人AIからチームAIへ:開発における品質と生産性の再設計
moongift
PRO
0
250
ポスター発表&デモと総括 / Poster Presentations & Demonstrations and Summary
ks91
PRO
0
150
Harnessing the Power of Mocks and Stubs in PHPUnit / #laravellivejp
asumikam
0
720
Featured
See All Featured
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
580
Site-Speed That Sticks
csswizardry
13
1.2k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.3k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Evolving SEO for Evolving Search Engines
ryanjones
0
210
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
61
44k
4 Signs Your Business is Dying
shpigford
187
22k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
210
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
820
How to Ace a Technical Interview
jacobian
281
24k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
GraphQLとの向き合い方2022年版
quramy
50
15k
Transcript
怖くない! GritQLでBiomeプラグイン GritQLが採⽤された理由を知り、基本を学んで、仲良くなろう Biome v2リリース記念 公式LTパーティ 2025/7/23
⾃⼰紹介 AIでノーコードで エッジコンピューティングな ⼤学発ベンチャーの 株式会社TechSwordで インターフェースやデザインなどの ソフトウェアエンジニアを やっています 晴れ井⼾ @pal4de
お断り これは短期間のキャッチアップの成果物です >< 網羅的にGritを知ろうと努めましたが ヘンなところがあったら教えてください ><
v2.0おめでとうございます • 型推論 • 設定ファイルの再構成 • ルールの⾒直し • Biome Assistの導⼊
• モノレポ対応 • ✨ プラグイン (ベータ) ✨ 等々...
プラグインの 指定⽅法... ESLint PluginはJS/TSで 定義できるのとは違い... Biomeのプラグインは .gritとかいう 気味の悪い 拡張⼦ のファイルで表現される
{ "plugins": ["./path-to-plugin.grit"] } ?!??!???!?👆
.gritの雰囲気 これは確かに 不気味かも `$fn($args)` where { $fn <: `Object.assign`, register_diagnostic(
span = $fn, message = "Prefer object spread instead of" + " `Object.assign()`" ) }
なぜGritなんだろう Biome PluginのRFCを読み解こう
RFCを⾒てみる プラグインに関する 決定の経緯と今後の⽅針は、 RFCとしてまとめられている RFC: Biome Plugins Proposal https://github.com/biomejs/biome/discussions/1762
JS/TSで書きたいんだけど A. わかる でもJS/TSはBiomeにとってパフォーマンスが⾜りない… から最初に取り組むべきではない… ⾼速で柔軟で便利な技術、ないかな…!
候補となった技術たち Comby テキストベースの コード検索‧置換技術 ⾼速で便利! だけど、柔軟性が ⾜りない Semgrep / ast-grep
ASTベースのコード 検索‧置換技術 ⾼速で柔軟! だけど、使い勝⼿に クセあり 巨⼤なYAMLを 書かないといけない Grit ASTベースのコード 検索‧置換技術 柔軟で便利で、 ⼗分に⾼速! これでは!?
最後の後押しになったのは ✨ 2つのチームの邂逅 ✨ Biomeチーム 🤝 Gritチーム Gritが候補に上がった時、すぐにコンタクトを取ってくれた 激アツの協業体制
GritQLと仲良くなろう GritQLで書くBiomeプラグインを学ぶ
改めてGritのイメージ Gritに期待される機能性を ⾝近なもので例えるなら VSCodeの 検索/置換機能とか awkとか なイメージ パターンを書く ↓ マッチ
↓ 置換などのアクション
ASTベースの強み テキストベース 単純⼀致や正規表現に対するマッチ コーディングスタイルの 変化に弱い インデントや引⽤符、セミコロンの有無など... ASTベース プログラムの構造に対するマッチ プログラムを⽂字の並びと してではなく、
意味の塊で認識 コーディングスタイルの 変化に対して強い!
ASTを⾒てみよう ASTはコードの構造を咀嚼したデータのこと 例えばこんなコードのASTを⾒てみよう console.log("Hello, World!");
⽣のAST あまり向き合いたくない { "type": "Program", "start": 0, "end": 29, "body":
[ { "type": "ExpressionStatement", "start": 0, "end": 29, "expression": { "type": "CallExpression", "start": 0, "end": 28, "callee": { "type": "MemberExpression", "start": 0, "end": 11, "object": { "type": "Identifier", "start": 0, "end": 7, "name": "console" }, "property": { "type": "Identifier", "start": 8, "end": 11, "name": "log" },
GritQLなら こう書ける これは なんか すごいぞ `console.log("Hello, World!");`
GritQLを書くときの考え⽅ やりたいことを下記の形で⾔い換える: [ASTのパターン] に⼀致する時、 [置換などのアクション] する ※ ただし、今の所は「警告する」しかアクションがない
カスタムルール の基本型 ルールの数だけ 右記の記述を繰り返す パターン where { 条件..., register_diagnostic( severity=重大度,
span=波線引く範囲への参照, message=メッセージ ) }
パターン 先ほど⾒た `console.log` とかを 書ける場所 `useEffect` とか `42`とか `const` とか書いていい
パターン where { 条件..., register_diagnostic( severity=重大度, span=波線引く範囲への参照, message=メッセージ ) }
メタ変数 Gritの重要な登場⼈物として 「メタ変数」というものがある プレースホルダやワイルドカードのようなイメージ `console.log($msg)` とか `$fn($$$arguments)` とか `Object.assign($target, $...)`とか
$$$hoge は列挙した値を丸ごとキャプチャ する記述 $_ や $... で無名のメタ変数を使える パターン where { 条件..., register_diagnostic( severity=重大度, span=波線引く範囲への参照, message=メッセージ ) }
追加条件 パターンで表現しきれない 追加の条件を記述できる 「左辺が右辺の条件を満たす」 という趣旨の演算⼦ <: を使ったり $arr <: `[]`
とか $fn <: includes `useEffect` とか パターン where { 条件..., register_diagnostic( severity=重大度, span=波線引く範囲への参照, message=メッセージ ) }
registerなんちゃら register_diagnosticは マッチするルールが あったことを、Biome に通知する関数 ここは直感通りの使い勝⼿です パターン where { 条件...,
register_diagnostic( severity=重大度, span=波線引く範囲への参照, message=メッセージ ) }
具体例 Object.assignを ⾒つけたら報告する例 ⾒慣れたら意外ともう怖くない `$fn($args)` where { $fn <: `Object.assign`,
register_diagnostic( span = $fn, message = "`Object.assign()`じゃなくて" + "スプレッド構文を使ってね " ) }
具体例 `$fn($_, [])` where { $fn <: includes `useEffect`, register_diagnostic(
span = $fn, message = "依存配列が空だよ", severity = "error" ) } useEffectの 依存配列が空だったら 報告する例 これは正規表現では難しいヤツだ...!
パターンや条件の論理演算 and { … } や or { … }
豊かな表現⼒を⽰唆する⾯⽩キーワード contains within bubble some before after … 他にもGritの機能盛りだくさん
⾒てると楽しいよ!勉強してみてね! Linter プラグイン | Biome https://biomejs.dev/ja/linter/plugins BiomeでGritQLがどう扱えるか丁寧に解説されています GritQL Reference https://docs.grit.io/language/syntax
GritQLの仕様が⼀覧できる 細かいことがわからなくてもみてて楽しい
Biomeプラグインのこれから Grit以外の選択肢もあるし、Girtでやりたいこともある
でもJS/TSで 書きたいよう! import Biome, { matches, transform, into } from
"$biome-plugin"; Biome.traversal.onEnter({ kind: "JsLogicalExpression", operator: "&&" }, (expr) => { if ( expr.right.kind === "JsCallExpression" && matches( expr.left, expr.right.callee ) ) { transform(expr, into`${expr.left}?.()`); } }); 構想はあるよ これも楽しみだね
auto fixは...? 多分 もうすぐできるように なるよ GritQLの本領発揮! `$path && $path()` =>
`$path?.()`
他にも楽しみなこと オリジナルのGritではサポートされている機能に 追従していくみたい • 複数ファイルにまたがる修正 • カスタムルールのsuppression • シーケンシャルな処理 対応状況は
https://github.com/biomejs/biome/issues/2582 で⾒れるよ