夜猫的小站

Remixjs 路由规则及remix-flat-routes

Published on
阅读时间:7分钟1271

本文最近一次更新于 182 个天前,其中的内容很可能已经有所发展或是发生改变。

前言

在remixjs中定义路由只需要按照照约定好的文件夹结构和文件名即可,但是规则更新好多版本,使人有很多误解,所以我基于当前版本总结了一下,方便后续使用时查询。

一、背景

在remixjs中定义路由只需要按照照约定好的文件夹结构和文件名即可,但是规则更新好多版本,使人有很多误解,所以我基于当前版本总结了一下,方便后续使用时查询。 官方文档:https://remix.run/docs/en/main/file-conventions/routes

阅读本文前请先阅读官方文档,对官方路由有一定的了解

二、remixjs路由版本

  • @remix-run/dev v2.13.1
  • remix-flat-routes ^0.6.5

remix-flat-routes 是一个remixjs路由插件,可以解决官方文档中描述的路由规则无法满足的问题

三、官方文档中描述的路由规则

3.1 基础路由规则

app/
├── routes/
│   ├── _index.tsx
│   └── about.tsx
└── root.tsx

index.tsx 是默认路由,当访问根路径时,会自动匹配到该路由,当访问其他路径时,会自动匹配到对应的路由,例如访问 /about 时,会自动匹配到 about.tsx 路由,如果该路由不存在,会自动匹配到 _index.tsx 路由

3.2 再来一个复杂的

 app/
├── routes/
│   ├── _index.tsx
│   ├── about.tsx
│   ├── concerts._index.tsx
│   ├── concerts.$city.tsx
│   ├── concerts.trending.tsx
│   └── concerts.tsx
└── root.tsx

在这里面的路由关系如下:

concerts._index.tsx  =>  /concerts 
concerts.$city.tsx  =>  /concerts/:city
concerts.trending.tsx  =>  /concerts/trending
concerts.tsx 代表所有concerts.tsx的layout

3.3 _代表什么

在remixjs中,_代表不生成路由名字。

官方示例中有这样的例子:

 app/
├── routes/
│   ├── _auth.login.tsx
│   ├── _auth.register.tsx
│   ├── _auth.tsx
│   ├── _index.tsx
│   ├── concerts.$city.tsx
│   └── concerts.tsx
└── root.tsx
URLMatched RouteLayout
/app/routes/_index.tsxapp/root.tsx
/loginapp/routes/_auth.login.tsxapp/routes/_auth.tsx
/registerapp/routes/_auth.register.tsxapp/routes/_auth.tsx
/concertsapp/routes/concerts.tsxapp/root.tsx
/concerts/salt-lake-cityapp/routes/concerts.$city.tsxapp/routes/concerts.tsx

也就是带上_的文件或目录,不参与路由

四、remix-flat-routes 中的路由使用

这时候我们就有一个问题了,当我们的路由很多时,那么所有的路由文件都会在根目录下,那么文件夹会变得非常臃肿,而且路由的层级关系也不好查看。能不能像nextjs一样,通过文件夹来表示路由的层级关系呢?答案是可以的。 remix官方中虽然提供了目录的使用,但是会导致原有的路由规则都失效,只能通过,在目录下只有route.tsx会作为路由文件。

所以这时候就轮到flat-routes出场了,flat-routes是一个第三方的路由库,可以实现目录路由,同时保留原有的路由规则。

4.1 remix-flat-routes下的路由规则

只需要区分目录上是否有+,_

  • _和remixjs官方规则相同,都代表不参与路由匹配
  • +则代表改目录下有多个路由文件。
_test2+/index.tsx => 不生效
_test2+/xxx.tsx => /xxx路由

4.2 忽略目录规则_

目的只是将同一路由文件放在一个目录下,如将所有其他文件放在public下,但是本身不需要/public(需要配合+使用)

_test/*.tsx  => 404
test/index.tsx  => 只有/test路由, index.tsx代表test的路由
test/_xxx.tsx => 只有/test路由,_xxx代表test的路由
test/_index.tsx  => 只有/test路由
test/xxx.tsx  => 404,无法匹配

4.3 目录下多个路由文件+

test/_index.tsx
test/$user.tsx

这时候$user.tsx对应 /test/:user路由不会生效,需要将test目录下的路由文件名改为+开头

test+/index.tsx => /test路由
test+/xxx.tsx => /test/xxx路由
test+/_index.tsx => /test路由
test+/$user.tsx => /test/:user路由
test+/_layout.tsx  => /test路由下的layout

4.4 +_配合使用

可以实现上面说的public目录效果,也就是同时带_public+这种就是不参与路由的一个目录

_public+/rss[.xml].tsx => /rss.xml路由
_public+/sitemap[.xml].tsx => /sitemap.xml路由

如果要将同一类路由放在一个目录下,可以使用+_配合使用:

_auth+/login.tsx => /login路由
_auth+/register.tsx => /register路由
_auth+/auth.tsx => /auth路由下的layout
_auth+/auth._index.tsx => /auth路由
_posts+/posts.$slug.tsx => /posts/:slug路由
_posts+/posts.tsx => /posts路由下的layout
_posts+/posts.index.tsx => /posts路由下的index

五、注意, 关于layout

  • posts+ 这个目录下的layout似乎只能命名成_layout.tsx。
  • posts 这个目录下无法嵌套layout
  • _posts+ 这个目录下,_posts+/posts.tsx是/posts的layout
  • _posts+/posts._layout.tsx不是支持的写法

六、实战例子

定义博客以及后台的路由

.
├── routes
│   ├── admin+  => /admin前缀
│   │   ├── dashboard.tsx => /admin/dashboard
│   │   ├── _index.tsx => /admin
│   │   ├── _layout.tsx => /admin的layout
│   │   ├── test+ => /admin/test前缀
│   │   │   ├── $user.tsx => /admin/test/:user
│   │   │   └── _index.tsx  => /admin/test
│   │   └── test2  => 404
│   │       └── tsss.tsx => 404
│   ├── _auth+  => /
│   │   └── login.tsx
│   ├── _blog+ => /
│   │   ├── about.tsx
│   │   ├── post
│   │   │   └── _layout.tsx
│   │   └── posts+
│   │       ├── $slug.tsx
│   │       ├── _index.tsx
│   │       └── _layout.tsx
│   ├── _index.tsx
│   └── _public+ => /
│       └── rss[.xml].tsx
└── root.tsx

七、参考资料