Skip to content
← Back to rules

react/only-export-components 制限

何を実行するか

モジュールがReactコンポーネント(および関連するHMR対応アイテム)のみをエクスポートすることを保証し、 高速リフレッシュ(別名:ホットロード)がコンポーネントの状態を安全に保持できるようにします。 具体的には、モジュールのエクスポートの構造と一般的なエントリポイント(例:createRoot(...).render(<App />))が、 react-refreshなどの統合機能が期待するものと一致しているか検証します。

このルールは eslint-plugin-react-refresh のルールに基づいています。

なぜこれは良くないのか

高速リフレッシュは、モジュールがコンポーネントをエクスポートし、 リフレッシュランタイムを混乱させるパターンを回避している場合にのみ、状態を確実に保持できます。
問題のあるパターン(例:export *、匿名のデフォルト関数、JSXの配列のエクスポート、非コンポーネントのエクスポートをサポートされていない方法で混ぜるなど)は次のような問題を引き起こす可能性があります:

  • 編集時にコンポーネントが再マウントされ、状態が失われる
  • 更新が見逃される(リフレッシュがない)または範囲が広すぎること
  • バンダラーによって挙動が異なる脆弱なHMR動作

予測可能なエクスポートを強制することで、開発中に編集が高速かつ状態を保持したまま行われます。

このルールに対して不正なコードの例:

jsx
// 1) 利用ユーティリティとコンポーネントをサポートされていない方法で混ぜている
export const foo = () => {}; // ユーティリティ、コンポーネントではない
export const Bar = () => <></>; // コンポーネント
jsx
// 2) 匿名のデフォルトエクスポート(名前は必須)
export default function () {}
jsx
// 3) すべてを再エクスポートすると、何がエクスポートされているかが隠れる
export * from "./foo";
jsx
// 4) JSXのコレクションをエクスポートすると、コンポーネントが検出できなくなる
const Tab = () => null;
export const tabs = [<Tab />, <Tab />];
jsx
// 5) そのモジュール内でコンポーネントを定義しながら、同じモジュール内でルートを起動している
const App = () => null;
createRoot(document.getElementById("root")).render(<App />);

このルールに対して正しいコードの例:

jsx
// 名前付きまたはデフォルトのコンポーネントエクスポートは問題ない
export default function Foo() {
  return null;
}
jsx
// オプションや命名規則により許可されている場合、ユーティリティと併存可能
const foo = () => {};
export const Bar = () => null;
jsx
// エントリポイントファイルではインポートされたコンポーネントをレンダリングしてもよい
import { App } from "./App";
createRoot(document.getElementById("root")).render(<App />);

設定

このルールは以下のプロパティを持つ設定オブジェクトを受け入れます。

allowConstantExport

type: boolean

default: false

コンポーネントエクスポートと一緒にプリミティブな定数(文字列/数値/真偽値/テンプレートリテラル)をエクスポートすることを許可します。
この機能を有効化するバンドラーの高速リフレッシュ統合が対応している場合に推奨されます(プラグインの vite プレセットによって有効化されます)。

jsx
// allowConstantExport: true の場合に許可される
export const VERSION = "3";
export const Foo = () => null;

allowExportNames

type: string[]

default: []

特定の名前付きエクスポートをHMR対応として扱う(ホットリプレースが特定のエクスポートを行うフレームワークなどで有用)。
たとえば、Remixでは次のようになります: { "allowExportNames": ["meta", "links", "headers", "loader", "action"] }

checkJS

type: boolean

default: false

.tsx/.jsx 以外に、.js ファイル内のJSXもチェックします。
誤検出を減らすため、このオプションが有効になると、React をインポートしているファイルのみがチェック対象になります。

customHOCs

type: string[]

default: []

カスタム高階コンポーネントでラップされたコンポーネントをエクスポートしている場合、それらの識別子をここにリストアップして誤検出を回避してください。

使用方法

このルールを有効化するには、設定ファイルまたはCLIを使用できます:

json
{
  "plugins": ["react"],
  "rules": {
    "react/only-export-components": "error"
  }
}
bash
oxlint --deny react/only-export-components --react-plugin

参照