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
forwardRef を禁止したくて Biome に PR を出した話
Search
Ryuya Yanagi
January 16, 2026
Technology
160
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
forwardRef を禁止したくて Biome に PR を出した話
Ryuya Yanagi
January 16, 2026
More Decks by Ryuya Yanagi
See All by Ryuya Yanagi
BFCacheを活用して無限スクロールのUX を改善した話
apple_yagi
0
170
最近の推しリンター、Oxlintをご紹介
apple_yagi
0
430
PR_TIMESにおけるFastlyの導入と運用について.pptx.pdf
apple_yagi
1
61
PR TIMESにおけるNext.jsとcacheの付き合い方
apple_yagi
4
3.1k
開発速度を上げつつ品質を保つためのフロントエンド開発
apple_yagi
1
990
Other Decks in Technology
See All in Technology
インシデントレスポンス演習 I / Incident Response Exercise I
ks91
PRO
0
110
Kiroで書いた 設計書 が AI レビューの 採点基準 になる
ezaki
0
140
Flow 不死:AI 時代 DevOps 的不變本質
cheng_wei_chen
2
450
不要なレビューをAIにまかせて AIコーディングの環境改善を加速した
shoota
1
250
GitHub Copilot 最新アップデート – 「一歩先」の実践活用術
moulongzhang
5
1.6k
OTel × Datadog で 「AI活用」を計測し、改善に繋げる
shihochan
2
550
[チョークトーク資料]AWS DevOps Agent を使いこなす / AWS Dev Ops Agent Chalk Talk AWS Summit Japan 2026
kinunori
3
730
IaC コードを資産へ:AWS CDK 社内ライブラリと横断展開 / aws-summit-japan-2026
gotok365
10
1.5k
白金鉱業Meetup_Vol.24_「AIエージェントは分けるほど良い」は本当か? / Is it true that “the more you divide AI agents, the better”?
brainpadpr
1
430
千葉での単身赴任からAWSをやり続け、千葉に戻ってきた話
yama3133
1
100
FPGAの開発コンペでZephyrを使ってみた
iotengineer22
0
170
現場のトークンマネジメント
dak2
1
160
Featured
See All Featured
Designing for Timeless Needs
cassininazir
1
260
How to build a perfect <img>
jonoalderson
1
5.7k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.8k
The Cult of Friendly URLs
andyhume
79
6.9k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
270
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
370
Technical Leadership for Architectural Decision Making
baasie
3
420
Bash Introduction
62gerente
615
220k
Transcript
forwardRef を禁止したくて Biome に PR を出した話 FE Yatai Talks vol.1
やなぎ PR TIMES フロントエンドエンジニア X:@apple_yagi こう見えて?二児のパパです
みなさん React 19 使ってますか?
Actions 系の hooks の追加 useActionState / useFormStatus / useOptimistic use
API の追加 静的サイト用の新しい DOM API の追加 react-dom/static に prerender / prerenderToNodeStream が追加 React Server Components / Server Actions forwardRef なしで ref を渡せるように変更 <Context.Provider> の代わりに <Context> を Provider としてレンダリングできるよ うに変更 etc.. React 19 の変更点
Actions 系の hooks の追加 useActionState / useFormStatus / useOptimistic use
API の追加 静的サイト用の新しい DOM API の追加 react-dom/static に prerender / prerenderToNodeStream が追加 React Server Components / Server Actions forwardRef なしで ref を渡せるように変更 <Context.Provider> の代わりに <Context> を Provider としてレンダリングできるよ うに変更 etc.. React 19 の変更点
// React v18 import { forwardRef } from "react"; const
MyInput = forwardRef(function MyInput({ placeholder }, ref) { return <input placeholder={placeholder} ref={ref} />; }); // React v19 function MyInput({ placeholder, ref }) { return <input placeholder={placeholder} ref={ref} />; } forwardRef は将来非推奨になる予定だが、まだ @deprecated はついていない 間違えて使う可能性があるので禁止したい forwardRef なしで ref を渡せるように変更
ESLint @eslint-react/no-forward-ref react-x/no-forward-ref Biome noReactForwardRef Oxlint 未対応 jsPlugins を用いて @eslint-react/no-forward-ref
などを 使用することができる forwardRef を禁止する Lint ルール
Biome を使っているプロジェクトで ルールを有効にしてみる
{ "linter": { "enabled": true, "rules": { "recommended": true, "nursery":
{ "noReactForwardRef": "error" } } }, "formatter": { "enabled": true } } noReactForwardRef を有効にする
あれ?エラーにならないな
Biome の内部実装を見てみる
impl Rule for NoReactForwardRef { fn run(ctx: &RuleContext<Self>) -> Self::Signals
{ let node = ctx.query(); let model = ctx.model(); let callee = node.callee().ok()?; let is_react_19 = ctx .get_service::<Option<(Utf8PathBuf, Arc<PackageJson>)>>() .and_then(|manifest| { manifest .as_ref() .map(|(_, package_json)| package_json.matches_dependency("react", ">=19.0.0")) }); if is_react_19 == Some(false) { return None; } is_react_call_api(&callee, model, ReactLibrary::React, "forwardRef").then_some(()) } } noReactForwardRef の内部実装の抜粋
package.json から React のバージョンを取得し、19.0.0 より下であれば None を返し、上であ れば forwardRef を使用しているか判定する
let is_react_19 = ctx .get_service::<Option<(Utf8PathBuf, Arc<PackageJson>)>>() .and_then(|manifest| { manifest .as_ref() .map(|(_, package_json)| package_json.matches_dependency("react", ">=19.0.0")) }); if is_react_19 == Some(false) { return None; } is_react_call_api(&callee, model, ReactLibrary::React, "forwardRef").then_some(()) noReactForwardRef の内部実装の抜粋
なるほど、わい pnpm catalogs 使ってるんやが
"Catalogs" are a workspace feature for defining dependency version ranges
as reusable constants. Constants defined in catalogs can later be referenced in package.json files. https://pnpm.io/catalogs 「カタログ」は、依存関係のバージョン範囲を再利用可能な定数として定義するための ワークスペース機能です。カタログで定義された定数は、後で package.json ファイルか ら参照できます。 by Nani 翻訳 pnpm catalogs とは
package.json に記述する React のバージョンが "catalog:" となるため、正しいバージョン を解決することができない # pnpm-workspace.yaml packages:
- "apps/*" - "packages/*" catalog: react: 19.2.1 react-dom: 19.2.1 # package.json { "devDependencies": { "react": "catalog:", "react-dom": "catalog:" } } pnpm catalogs とは
ちなみにこの問題は ESLint では発生しない
import module from "node:module"; import path from "node:path"; const _require
= module.createRequire(process.cwd() + path.sep); export function getReactVersion(): string { return _require("react").version; } export function create(context: RuleContext<MessageID, []>): RuleListener { // Skip if React version is less than 19.0.0 const version = getReactVersion() if (compare(version, "19.0.0", "<")) { return {}; } return { CallExpression(node) { ... }, }; } no-forward-ref の内部実装のイメージ(ESLint)
module.createRequire を使用して現在の作業ディレクトリ基準の require を作成し、 プロジェクトに入っている React のバージョンを取得する import module from
"node:module"; import path from "node:path"; const _require = module.createRequire(process.cwd() + path.sep); export function getReactVersion(): string { return _require("react").version; } Biome は Rust で実装されているので、この手法が使えず package.json をパースして React の バージョンを取得している React のバージョンの取得方法
この問題を解決するために pnpm-workspace.yaml からバージョンを取得できるようにする Pull Request を出してみた(出してから時間が経ってしまったのでマージされるかは怪しい) https://github.com/biomejs/biome/pull/8396 ただ、最近 yarn と
bun にも catalogs 機能があることに気づいたのでそちらは別途対応が必要 となる yarn catalogs は pnpm catalogs と同じ記法だが、bun catalogs は package.json に catalog を定義する そもそもバージョンの取得方法を根本的に変えた方が良いか? 作業ディレクトリの node_modules の中を探索するとか 有識者の方、ご意見お待ちしております この問題の解決策として
React 19 では forwardRef を書く必要はなくなった 将来非推奨になる予定 ESLint/Biome には forwardRef を禁止する
Lint ルールがある Biome は今のところ pnpm catalogs を解決できない 自分の PR がマージされたら解決するはず まとめ