routerx: 适用于 react admin 场景的路由管理方案
基于最新的 react-router 实现的一套基于 follow 文件结构管理的路由解决方案
项目主页: https://github.com/afeiship/router-packages
背景
react-router
直至 v6 才算是一个不错的路由方案,我在开发的系统中,有一个admin
系统,期望有一个可以根据目录结构管理的路由管理方案。
原则
- 约定优于配置
- DRY
- 简洁,优雅
技术选型
- webpack
tree-dir
遍历方案
最终选择了
tree-dir
方案,因为不依赖于 webpack,说不定 vite 方案未来真成为主流了呢?目前的 tree-dir 方案,实际上是纯原生 nodejs 实现的一个路由映射方案,所以,与特定编译工具无关。
三件套
- routerx-cli: 生成
.routerrc.json
文件,供项目中routes.tsx
调用,生成 react 组件与 path 的映射 - routerx 接收 .routerc.json 作为入参,生成 react 路由表
- generator-router: 项目中常用的路由脚手架
后备机制
- 有时候,纯路径映射方案是无法满足的,所以可以 export const Routes = {} as RouterObject 方案来实现
login/__init__.tsx
示例代码/login → /
改为根路由
// 此为伪代码
export default () => {
return (
<Container className="w-full h-[100vh]">
<ReactFullImage
animation="blur"
src="https://tva1.js.work/large/e6c9d24egy1h5kk7oh4kaj21hw0u0aej.jpg"
/>
<AntdFormBuilder {...opts} onFinish={handleFinish}>
<Button className="w-full mb-4" htmlType="submit" size="large" type="primary">
<LoginOutlined />
登录
</Button>
</AntdFormBuilder>
</Container>
);
};
export const Routes = {
path: '/',
};
路由表
大体文件结构如下。
├── admin
│ ├── __init__.tsx
│ ├── index.tsx
│ ├── options
│ └── users
├── login
│ ├── __init__.tsx
│ └── _misc.tsx
└── routes.tsx
import routerx from '@jswork/routerx';
const routerRC = require('./.routerc.json');
const req = (item) => require(`.${item}`);
export default routerx(routerRC, req);
约定
__init__.tsx
: resources 模块的容器页(container/frame),用__init__
是为了让这个排第一个,不同于 py里的__init__.py
作用。index.tsx
: 对于路由的index:true
,也是一般模块的 list 页add.tsx
: 添加页面edit.tsx
: 编辑页面xyz.tsx
: 其它功能页面,会自动路由_misc.tsx
: 以_
开头的页面,会自动忽略,并不会加入路由
没有 routerx
未使用
routerx
的代码如下,这还是几个模块,如果后续模块增加,这个文件会越来越大。
export default [
{
path: '/',
element: <LoginFrame /> /* __init__ */,
},
{
path: '/admin',
element: <AdminFrame /> /* __init__ */,
children: [
{
index: true,
element: <AdminIndex /> /* index */,
},
{
path: 'users',
element: <UsersFrame /> /* __init__ */,
children: [
{
index: true,
element: <UsersIndex />,
},
{
path: 'add',
element: <UsersAdd />,
},
],
},
],
},
];
路由使用
import { useRoutes } from 'react-router-dom';
import routes from '@/modules/routes';
function App() {
return useRoutes(routes);
}
export default App;
工具
后面有脚手架生成示例图。
# generate a resource<users>
yo @jswork/router --resource users
# defautls
yo @jswork/router --resource users --routes_dir=src/modules/admin
参考


