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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
410
PR_TIMESにおけるFastlyの導入と運用について.pptx.pdf
apple_yagi
1
60
PR TIMESにおけるNext.jsとcacheの付き合い方
apple_yagi
4
3.1k
開発速度を上げつつ品質を保つためのフロントエンド開発
apple_yagi
1
990
Other Decks in Technology
See All in Technology
2026 TECHFRESH 畢業分享會 - AI-Native 重塑軟體工程與虛擬講師
line_developers_tw
PRO
0
1.2k
スキルと MCP ツール、責務をどう分けるか? AI が迷わないインターフェース設計の戦略
cdataj
1
1.1k
Claude Code の Sandbox 機能を Anthropic Sandbox Runtime(srt) で試そう!/lets-play-anthropic-sandbox-runtime
tomoki10
1
640
日本 Fintech 未来予測レポート 2027〜2028年(手動編集版)
8maki
0
2.4k
SONiCのLinuxベースを活かしたZabbix監視
sonic
0
200
SONiCの統計情報を取得したい
sonic
0
190
脱SaaS!FDEを支えるプロビジョニングと分離設計
knih
0
150
人材育成分科会.pdf
_awache
4
280
Bucharest Tech Week 2026 - Guardians of the Cloud-Native Galaxy
edeandrea
PRO
0
110
When Platform Engineering Meets GenAI
sucitw
0
110
新しいUbuntu/GNOMEが使いたいからXからWaylandへ移行頑張ってるの巻 2026-06-20
nobutomurata
0
140
自宅LLMの話
jacopen
1
610
Featured
See All Featured
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
180
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
The SEO Collaboration Effect
kristinabergwall1
1
490
The Language of Interfaces
destraynor
162
27k
Into the Great Unknown - MozCon
thekraken
41
2.6k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
460
RailsConf 2023
tenderlove
30
1.5k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
600
The SEO identity crisis: Don't let AI make you average
varn
0
490
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
210
Rebuilding a faster, lazier Slack
samanthasiow
85
9.5k
Utilizing Notion as your number one productivity tool
mfonobong
4
320
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 がマージされたら解決するはず まとめ