@troyio/vite-file-router 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/index.js +18 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -108,6 +108,12 @@ Catch-all segments such as `[...slug]` become `*`. Parenthesized directories
|
|
|
108
108
|
are route groups; they organize files and can have their own page, layout,
|
|
109
109
|
loading files, loaders, and actions, but their names do not add a URL segment.
|
|
110
110
|
|
|
111
|
+
Directories whose names start with an underscore, such as `_components` or
|
|
112
|
+
`_utils`, are private folders. The plugin skips them and everything nested
|
|
113
|
+
inside them, so you can colocate components, hooks, and helpers next to the
|
|
114
|
+
routes that use them without creating routes. A `_components/page.tsx` file is
|
|
115
|
+
never routed.
|
|
116
|
+
|
|
111
117
|
### Layouts
|
|
112
118
|
|
|
113
119
|
The plugin adapts React Router's matched child route to a `children` prop. A
|
|
@@ -178,6 +184,23 @@ when a descendant URL matches. An action runs only when its route is selected
|
|
|
178
184
|
as the submission target; a parent action does not automatically handle
|
|
179
185
|
submissions targeting child routes.
|
|
180
186
|
|
|
187
|
+
A loader module may also export `shouldRevalidate(args)` to control the route's
|
|
188
|
+
React Router `shouldRevalidate` option. It receives the same arguments as
|
|
189
|
+
`shouldRevalidate` and must synchronously return a boolean:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import type { LoaderFunctionArgs, ShouldRevalidateFunctionArgs } from "react-router";
|
|
193
|
+
|
|
194
|
+
export function shouldRevalidate({ nextUrl, defaultShouldRevalidate }: ShouldRevalidateFunctionArgs) {
|
|
195
|
+
if (nextUrl.searchParams.get("refresh") === "never") return false;
|
|
196
|
+
return defaultShouldRevalidate;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export async function loader({ request }: LoaderFunctionArgs) {
|
|
200
|
+
return getDashboardData(request);
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
181
204
|
Use a loader to redirect users who should not enter a protected route subtree.
|
|
182
205
|
For example, `src/pages/dashboard/loader.ts` can guard `/dashboard` and all of
|
|
183
206
|
its nested pages:
|
package/dist/index.js
CHANGED
|
@@ -53,6 +53,7 @@ function scan(directory, conventions = DEFAULT_CONVENTIONS) {
|
|
|
53
53
|
for (const entry of entries) {
|
|
54
54
|
const file = path.join(directory, entry.name);
|
|
55
55
|
if (entry.isDirectory()) {
|
|
56
|
+
if (entry.name.startsWith("_")) continue;
|
|
56
57
|
node.children.push(scan(file, conventions));
|
|
57
58
|
continue;
|
|
58
59
|
}
|
|
@@ -132,9 +133,19 @@ function generateImport(file, projectRoot) {
|
|
|
132
133
|
Component: (await import(${JSON.stringify(getImportPath(file, projectRoot))})).default
|
|
133
134
|
})`;
|
|
134
135
|
}
|
|
135
|
-
function generateRouteLazy(node, projectRoot, includeLayout) {
|
|
136
|
+
function generateRouteLazy(node, projectRoot, includeLayout, includeLoader) {
|
|
136
137
|
const properties = [];
|
|
137
138
|
if (includeLayout && node.layout) properties.push(`Component: withOutlet((await import(${JSON.stringify(getImportPath(node.layout, projectRoot))})).default)`);
|
|
139
|
+
if (includeLoader && node.loader) return `async () => {
|
|
140
|
+
const loaderModule = await import(${JSON.stringify(getImportPath(node.loader, projectRoot))});
|
|
141
|
+
return {
|
|
142
|
+
loader: loaderModule.loader,
|
|
143
|
+
...(typeof loaderModule.shouldRevalidate === "function"
|
|
144
|
+
? { shouldRevalidate: loaderModule.shouldRevalidate }
|
|
145
|
+
: {}),
|
|
146
|
+
${properties.join(",\n ")}
|
|
147
|
+
};
|
|
148
|
+
}`;
|
|
138
149
|
return `async () => ({ ${properties.join(", ")} })`;
|
|
139
150
|
}
|
|
140
151
|
function generateLazyComponent(file, projectRoot) {
|
|
@@ -143,8 +154,8 @@ function generateLazyComponent(file, projectRoot) {
|
|
|
143
154
|
function generateLazyLayout(file, projectRoot) {
|
|
144
155
|
return `lazy(() => import(${JSON.stringify(getImportPath(file, projectRoot))}).then(({ default: Layout }) => ({ default: withOutlet(Layout) })))`;
|
|
145
156
|
}
|
|
146
|
-
function generateDataHandler(file,
|
|
147
|
-
return `async (args) => (await import(${JSON.stringify(getImportPath(file, projectRoot))}))
|
|
157
|
+
function generateDataHandler(file, projectRoot) {
|
|
158
|
+
return `async (args) => (await import(${JSON.stringify(getImportPath(file, projectRoot))})).action(args)`;
|
|
148
159
|
}
|
|
149
160
|
function getRouteId(directory, projectRoot) {
|
|
150
161
|
return `file-route:${path.relative(projectRoot, directory).split(path.sep).join("/") || "."}`;
|
|
@@ -159,8 +170,7 @@ function generateNode(node, root, context, inheritedBoundary) {
|
|
|
159
170
|
context.hasErrorBoundaries = true;
|
|
160
171
|
route.ErrorBoundary = `createErrorBoundary(${generateLazyComponent(node.error, context.projectRoot)})`;
|
|
161
172
|
}
|
|
162
|
-
if (node.
|
|
163
|
-
if (node.action) route.action = generateDataHandler(node.action, "action", context.projectRoot);
|
|
173
|
+
if (node.action) route.action = generateDataHandler(node.action, context.projectRoot);
|
|
164
174
|
let loadingComponent;
|
|
165
175
|
if (node.loading) {
|
|
166
176
|
loadingComponent = genSafeVariableName(`Loading${context.nextLoadingId++}`);
|
|
@@ -173,17 +183,17 @@ function generateNode(node, root, context, inheritedBoundary) {
|
|
|
173
183
|
} else if (node.layout) {
|
|
174
184
|
if (hasBoundary) route.Component = generateLazyLayout(node.layout, context.projectRoot);
|
|
175
185
|
}
|
|
176
|
-
if (node.layout && !hasBoundary) route.lazy = generateRouteLazy(node, context.projectRoot,
|
|
186
|
+
if (node.layout && !hasBoundary || node.loader) route.lazy = generateRouteLazy(node, context.projectRoot, Boolean(node.layout && !hasBoundary), Boolean(node.loader));
|
|
177
187
|
const children = [];
|
|
178
188
|
if (node.page) {
|
|
179
189
|
const page = hasBoundary ? {
|
|
180
190
|
index: "true",
|
|
181
191
|
Component: generateLazyComponent(node.page, context.projectRoot),
|
|
182
|
-
...node.action ? { action: generateDataHandler(node.action,
|
|
192
|
+
...node.action ? { action: generateDataHandler(node.action, context.projectRoot) } : {}
|
|
183
193
|
} : {
|
|
184
194
|
index: "true",
|
|
185
195
|
lazy: generateImport(node.page, context.projectRoot),
|
|
186
|
-
...node.action ? { action: generateDataHandler(node.action,
|
|
196
|
+
...node.action ? { action: generateDataHandler(node.action, context.projectRoot) } : {}
|
|
187
197
|
};
|
|
188
198
|
children.push(genObjectFromRaw(page));
|
|
189
199
|
}
|