vite-plugin-ra-pages
Version:
Vite plugin to automatically generate routes for React-Admin based on folder structure.
191 lines (144 loc) • 5.34 kB
Markdown
> Vite plugin to automatically generate routes for React-Admin from a folder structure
- 📁 Scans the `src/pages` folder (you can configure another path).
- 🧠 Interprets structures like `users/Index.jsx` as a resource.
- 🧠 Interprets structures like `posts/[id]/edit/Page.jsx` as a path.
- ⚛️ Automatically generates React-Admin routes using `<Resource />` and nested `<Route />`.
- 🧩 Uses individual wrappers per component to avoid `cloneElement` bugs in React-Admin.
- 🚀 Exports a pre-mounted `RAAdmin` component ready to use.
```bash
yarn add -D vite-plugin-ra-pages
```
In your `vite.config.js`:
```js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import raPages from "vite-plugin-ra-pages";
export default defineConfig({
plugins: [
react(),
raPages({
// Default
// root: process.cwd(),
// pageDir: "src/pages",
// cacheDir: ".ra",
// aliasPage: "ra-pages.jsx",
}),
],
});
```
The plugin interprets the folder structure like this:
- `Page.jsx` represents a page
- `Index.jsx` represents a main list and is assumed to be the `list` component inside a `<Resource>`, marking the entire folder as a resource
```
src/pages/
│ Page.jsx // Dashboard
├───posts
│ │ Index.jsx // Resource posts
│ ├───create/Page.jsx
│ ├───notify/Page.jsx
│ └───[id]
│ ├───confirm/Page.jsx
│ ├───docs/Page.jsx
│ ├───edit/Page.jsx
│ ├───notify/Page.jsx
│ ├───report/Page.jsx
│ └───show/Page.jsx
├───profile // Custom Routes
│ ├───config/Page.jsx
│ └───info/Page.jsx
└───users // Resource posts (list, create, edit, show)
│ Index.jsx
├───create/Page.jsx
└───[id]
├───edit/Page.jsx
└───show/Page.jsx
```
This tree is automatically turned into a complete `RAAdmin` like this:
```tsx
import { Admin, Resource } from "react-admin";
import { Route } from "react-router-dom";
const RAAdmin = (props) => {
return (
<Admin dashboard={R_3.default} {...props}>
<Resource
name="users"
icon={R_1_1.Icon}
options={R_1_1.Options}
list={R_1_1Wrapper}
create={R_1_2Wrapper}
show={R_1_3Wrapper}
edit={R_1_4Wrapper}
/>
<Resource
name="posts"
icon={R_2_1.Icon}
options={R_2_1.Options}
list={R_2_1Wrapper}
create={R_2_2Wrapper}
show={R_2_3Wrapper}
edit={R_2_4Wrapper}
>
<Route path=":id/report" element={<R_2_5Wrapper />} />
<Route path=":id/notify" element={<R_2_6Wrapper />} />
<Route path=":id/docs" element={<R_2_7Wrapper />} />
<Route path=":id/confirm" element={<R_2_8Wrapper />} />
<Route path="notify" element={<R_2_9Wrapper />} />
</Resource>
<Route path="profile/info" element={<R_4.default />} />
<Route path="profile/config" element={<R_5.default />} />
</Admin>
);
};
export default RAAdmin;
```
The `Index.jsx` file, when detected as a resource list, also defines the Icon and Options:
```jsx
import { Badge } from "@mui/icons-material";
import { ListGuesser } from "react-admin";
export default () => <ListGuesser />;
export const Icon = Badge;
export const Options = {
label: "Post Index",
};
```
React-Admin performs a `cloneElement` of the components defined as `list`, `edit`, `create`, `show`. This can break Hot Module Replacement (HMR), which prevents hot reloading during development.
To solve this, the plugin automatically generates _wrapper_ components for each of these elements. These wrappers ensure that the original components can reload without errors or loss of state.
```jsx
const R_1_1Wrapper = (props) => <R_1_1.default {...props} />;
const R_1_2Wrapper = (props) => <R_1_2.default {...props} />;
const R_1_3Wrapper = (props) => <R_1_3.default {...props} />;
const R_1_4Wrapper = (props) => <R_1_4.default {...props} />;
```
The `RAAdmin` component is automatically generated. It includes:
- All resources
- Nested subroutes
- Dashboard if `src/pages/Page.jsx` exists
You can import it like this:
```jsx
import RAAdmin from 'ra-pages.jsx';
function App() {
return <RAAdmin dataProvider={...} authProvider={...} />;
}
```
The plugin scans the folder tree under `src/pages` (or the directory you configure) and generates an intermediate module in `cacheDir` (default is `.ra/ra-pages.jsx`). This intermediate file contains the `RAAdmin` component and all necessary imports, including the wrappers that fix the `cloneElement` issue in React-Admin.
This file is automatically referenced via the alias `ra-pages.jsx`, so you can import it directly without worrying about its real location:
```js
import RAAdmin from "ra-pages.jsx";
```
The file is regenerated automatically when changes are detected in the `src/pages` file tree.
- React-Admin v4 or higher
- Vite
MIT