Remix でルーティング設定時、 routes のネストを深くしたい
背景
前提条件
- Remix ^2.7.2
- Vite ^5.1.0
- remix-flat-routes ^0.6.4
初めに
Remix はファイルベースルーティングである。
例えば、以下のフォルダ構成にすると、
app/
├── routes/
│ ├── _index.tsx
│ ├── about.tsx
│ ├── concerts._index.tsx
│ ├── concerts.$city.tsx
│ ├── concerts.trending.tsx
│ └── concerts.tsx
└── root.tsx
以下テーブルのように、良い感じにルーティングを定義してくれる。
URL | Matched Route |
---|---|
/ |
app/routes/_index.tsx |
/about |
app/routes/about.tsx |
/concerts |
app/routes/concerts._index.tsx |
/concerts/trending |
app/routes/concerts.trending.tsx |
/concerts/salt-lake-city |
app/routes/concerts.$city.tsx |
問題
上記の定義を見て、個人的にフォルダ構造を深く設定したい欲求が発生した。
機能や関心を単位として、1つのフォルダにファイルを置きたい。
また、 URL のパスが深くなると、 .
を繋げていくため、ファイルまたはフォルダ名が長くなる懸念がある。
しかし Remix では、フォルダのネストを深くしても、ルートを作成しないことがわかった。
どうにか解決したい。
app/routes直下のフォルダのみがルートとして登録されます。深くネストされたフォルダは無視されます。app/routes/about/header/route.tsxのファイルはルートを作成しません。
app/ ├── routes/ │ └── about/ │ ├── header/ │ │ └── route.tsx │ └── route.tsx └── root.tsx
選択肢
案1: remix.config.js に手動で定義
手間がかかるし避けたかった。
ファイルベースルーティングなんだから、深いネストもフォルダ構造で良い感じにして欲しい気持ちが強くなる。
Remixではremix.config.jsを使って手動でルートを設定することができます。この柔軟性により、開発者はプロジェクトに適した方法でアプリケーションを構成することができます。
ref: Route Configuration | Remix
案2: remix-flat-route を導入
Remix のリファレンスに remix-flat-routes ってライブラリの紹介があった。
ref: Route File Naming | Remix
解決策: remix-flat-route を導入
ライブラリをインストールする。
yarn add -D remix-flat-routes
Remix + Vite の場合、 remix.config.js ではなく vite.config.ts に定義するため注意すること。
Vite | Remix
import { flatRoutes } from 'remix-flat-routes';
import { vitePlugin as remix } from '@remix-run/dev';
import { defineConfig } from 'vite';
// ...
export default defineConfig({
plugins: [
remix({
ignoredRouteFiles: ['**/*'],
routes: async (defineRoutes) => flatRoutes('routes', defineRoutes),
}),
// ...
],
// ...
});
結果
満足。
なお、結果に記載したフォルダ構造は、TODO リストの CRUD アプリケーションをイメージして記述した。
完成後のリポジトリは以下の通り。
ref: masayuki-0319/remix_todoapp at topics/add_remix_flat_routes
Before
app/routes
├── _index.tsx
├── posts
├── posts.$postId
│ └── route.tsx
├── posts.$postId.delete
│ └── route.tsx
├── posts.$postId_.edit
│ └── route.tsx
├── posts._index
│ └── route.tsx
└── posts.new
└── route.tsx
After
app/routes
├── _index.tsx
└── posts+
├── $postId.delete.tsx
├── $postId.edit.tsx
├── $postId.tsx
├── index.tsx
└── new.tsx
参考 URL
remix-flat-routes
kiliman/remix-flat-routes: Remix package to define routes using the flat-routes convention
remix-flat-routes 導入リポジトリ
epicweb-dev/epic-stack: This is a Full Stack app starter with the foundational things setup and configured for you to hit the ground running on your next EPIC idea.
kentcdodds/kentcdodds.com: My personal website
remix-flat-routes 紹介
Remix v2 のルーティングにおける flat-routes と Dot Delimiters
Discussion