RemixでのコロケーションがRoute File Naming(v2)でどのように変わるか
昨今、Webフロントエンドにおいて「コロケーション」という考え方を見聞きすることがあります。
これは、関連するソースファイルやリソースを近くに置いておく、という考え方で、ソースコードの整理・管理に幅広く適用できます。
最近よく採用される(要出典)SSRフレームワークにおいても例外ではありません。
しかし、この類のフレームワークではファイルシステムベースのルーティングを採用していることが多く、その性質上ひと工夫必要です。
本記事では、まずRemixでコロケーションを実現する方法と注意点について解説します。
次に、新しい命名規則であるRoute File Naming(v2)におけるコロケーションの実現方法と、従来の方法にあった問題点がどのように解決されているかを解説します。
Route File Namingにおけるコロケーションについて
Route File Naming でのコロケーション実現方法
下記のように設定し、 _private
ディレクトリ以下のファイルをルートファイルとして扱わないようにします。
module.exports = {
ignoredRouteFiles: ["**/.*", "**/_private/**/*"],
};
このようにすることで、例えば下記のようなディレクトリ構造において、 routes/some-feature/_private
ディレクトリ以下のファイル群はルートファイルとして認識されないようになります。
/routes
└── some-feature
├── index.tsx
└── _private
└── internal-component.ts
Route File Naming でのコロケーションの注意点
Route File Namingにおいては、基本的に /routes
以下の js, jsx, ts, tsx ファイルが全てルートファイルだとみなされます。
この場合、Remixでコロケーションをやりたい、という場合に困ってしまいます。
というのも、下記のようなディレクトリ構造があったとして、 internal-component.tsx
からsome-feature
ディレクトリ内で内部的に使うコンポーネントをデフォルトエクスポートしたい、というケースを考えます。
/routes
└── /some-feature
├── index.tsx
└── internal-component.tsx
そうすると、 internal-component.tsx
はルートファイルとして認識され、さらにコンポーネントをデフォルトエクスポートしているので、 /some-feature/internal-component
にアクセスするとその内容がレンダリングされてしまうことになります。
よくみるやり方とその問題点
Remixを始めとしたファイルシステムベースのルーティングを採用したSSRフレームワークでよく見るのが、縦割りのディレクトリ構造を使うやり方です。
/components
└── some-feature
└── internal-component.tsx
/routes
└── /some-feature
└── index.tsx
この方法だと components/some-feature
と routes/some-feature
を行ったり来たりすることになったり、内部的に使いたかったコンポーネントを他のモジュールから予期せず再利用されてしまう、といった懸念があったりします。
Route File Naming(v2)について
Route File Naming(v2)は、Remixの新しいルートファイルの命名規則で、設定ファイルで有効化することができます。
module.exports = {
future: {
v2_routeConvention: true,
},
};
この新しい命名規則では、なんの工夫もなく、より簡単にコロケーションを扱えます。
というのも、RemixのRoute File Naming(v2) では大幅な変更がなされており、
ディレクトリ内に route.tsx
あるいは index.tsx
があるとき、ディレクトリ内の他のモジュールはルートファイルとして認識されないようになっているからです。
例えば、下記のようなディレクトリ構造があるとき、URLと対応するルートファイルは表のようになります。
/routes
├── posts.$var.tsx
└── posts._index
├── route.tsx
└── util.ts
パス | ルートファイル |
---|---|
/posts | /routes/posts._index/route.tsx |
/posts/123 | /routes/posts.$var.tsx |
従来の命名規則と互換性はないのですが、とてもシンプルで扱いやすくなったように感じます。
Discussion