@react-router/dev 0.0.0-experimental-4996fbe2b → 0.0.0-experimental-ecd35cd60
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/bin.js +2 -0
- package/dist/cli/commands.js +1 -1
- package/dist/cli/detectPackageManager.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/run.js +1 -1
- package/dist/cli/useJavascript.js +1 -1
- package/dist/cli.js +1 -2
- package/dist/colors.js +1 -1
- package/dist/config/defaults/entry.server.node.tsx +12 -97
- package/dist/config/findConfig.js +1 -1
- package/dist/config/flatRoutes.js +1 -1
- package/dist/config/format.js +1 -1
- package/dist/config/routes.js +1 -1
- package/dist/config.js +1 -1
- package/dist/index.js +1 -1
- package/dist/invariant.js +1 -1
- package/dist/vite/babel.js +1 -1
- package/dist/vite/build.js +1 -1
- package/dist/vite/define-route.d.ts +4 -1
- package/dist/vite/define-route.js +49 -14
- package/dist/vite/dev.js +1 -1
- package/dist/vite/import-vite-esm-sync.js +1 -1
- package/dist/vite/index.js +1 -1
- package/dist/vite/node-adapter.js +1 -1
- package/dist/vite/plugin.js +61 -21
- package/dist/vite/profiler.js +1 -1
- package/dist/vite/remove-exports.js +1 -1
- package/dist/vite/resolve-file-url.js +1 -1
- package/dist/vite/styles.js +1 -1
- package/dist/vite/vmod.js +1 -1
- package/package.json +9 -7
package/bin.js
ADDED
package/dist/cli/commands.js
CHANGED
package/dist/cli/index.js
CHANGED
package/dist/cli/run.js
CHANGED
package/dist/cli.js
CHANGED
package/dist/colors.js
CHANGED
|
@@ -3,7 +3,8 @@ import { PassThrough } from "node:stream";
|
|
|
3
3
|
import type { AppLoadContext, EntryContext } from "react-router";
|
|
4
4
|
import { createReadableStreamFromReadable } from "@react-router/node";
|
|
5
5
|
import { ServerRouter } from "react-router";
|
|
6
|
-
import
|
|
6
|
+
import { isbot } from "isbot";
|
|
7
|
+
import type { RenderToPipeableStreamOptions } from "react-dom/server";
|
|
7
8
|
import { renderToPipeableStream } from "react-dom/server";
|
|
8
9
|
|
|
9
10
|
const ABORT_DELAY = 5_000;
|
|
@@ -12,114 +13,28 @@ export default function handleRequest(
|
|
|
12
13
|
request: Request,
|
|
13
14
|
responseStatusCode: number,
|
|
14
15
|
responseHeaders: Headers,
|
|
15
|
-
|
|
16
|
+
routerContext: EntryContext,
|
|
16
17
|
loadContext: AppLoadContext
|
|
17
|
-
) {
|
|
18
|
-
let prohibitOutOfOrderStreaming =
|
|
19
|
-
isBotRequest(request.headers.get("user-agent")) || remixContext.isSpaMode;
|
|
20
|
-
|
|
21
|
-
return prohibitOutOfOrderStreaming
|
|
22
|
-
? handleBotRequest(
|
|
23
|
-
request,
|
|
24
|
-
responseStatusCode,
|
|
25
|
-
responseHeaders,
|
|
26
|
-
remixContext
|
|
27
|
-
)
|
|
28
|
-
: handleBrowserRequest(
|
|
29
|
-
request,
|
|
30
|
-
responseStatusCode,
|
|
31
|
-
responseHeaders,
|
|
32
|
-
remixContext
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// We have some Remix apps in the wild already running with isbot@3 so we need
|
|
37
|
-
// to maintain backwards compatibility even though we want new apps to use
|
|
38
|
-
// isbot@4. That way, we can ship this as a minor Semver update to @react-router/dev.
|
|
39
|
-
function isBotRequest(userAgent: string | null) {
|
|
40
|
-
if (!userAgent) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// isbot >= 3.8.0, >4
|
|
45
|
-
if ("isbot" in isbotModule && typeof isbotModule.isbot === "function") {
|
|
46
|
-
return isbotModule.isbot(userAgent);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// isbot < 3.8.0
|
|
50
|
-
if ("default" in isbotModule && typeof isbotModule.default === "function") {
|
|
51
|
-
return isbotModule.default(userAgent);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function handleBotRequest(
|
|
58
|
-
request: Request,
|
|
59
|
-
responseStatusCode: number,
|
|
60
|
-
responseHeaders: Headers,
|
|
61
|
-
remixContext: EntryContext
|
|
62
18
|
) {
|
|
63
19
|
return new Promise((resolve, reject) => {
|
|
64
20
|
let shellRendered = false;
|
|
65
|
-
|
|
66
|
-
<ServerRouter
|
|
67
|
-
context={remixContext}
|
|
68
|
-
url={request.url}
|
|
69
|
-
abortDelay={ABORT_DELAY}
|
|
70
|
-
/>,
|
|
71
|
-
{
|
|
72
|
-
onAllReady() {
|
|
73
|
-
shellRendered = true;
|
|
74
|
-
const body = new PassThrough();
|
|
75
|
-
const stream = createReadableStreamFromReadable(body);
|
|
76
|
-
|
|
77
|
-
responseHeaders.set("Content-Type", "text/html");
|
|
78
|
-
|
|
79
|
-
resolve(
|
|
80
|
-
new Response(stream, {
|
|
81
|
-
headers: responseHeaders,
|
|
82
|
-
status: responseStatusCode,
|
|
83
|
-
})
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
pipe(body);
|
|
87
|
-
},
|
|
88
|
-
onShellError(error: unknown) {
|
|
89
|
-
reject(error);
|
|
90
|
-
},
|
|
91
|
-
onError(error: unknown) {
|
|
92
|
-
responseStatusCode = 500;
|
|
93
|
-
// Log streaming rendering errors from inside the shell. Don't log
|
|
94
|
-
// errors encountered during initial shell rendering since they'll
|
|
95
|
-
// reject and get logged in handleDocumentRequest.
|
|
96
|
-
if (shellRendered) {
|
|
97
|
-
console.error(error);
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
}
|
|
101
|
-
);
|
|
21
|
+
let userAgent = request.headers.get("user-agent");
|
|
102
22
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
23
|
+
// Ensure requests from bots and SPA Mode renders wait for all content to load before responding
|
|
24
|
+
// https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation
|
|
25
|
+
let readyOption: keyof RenderToPipeableStreamOptions =
|
|
26
|
+
(userAgent && isbot(userAgent)) || routerContext.isSpaMode
|
|
27
|
+
? "onAllReady"
|
|
28
|
+
: "onShellReady";
|
|
106
29
|
|
|
107
|
-
function handleBrowserRequest(
|
|
108
|
-
request: Request,
|
|
109
|
-
responseStatusCode: number,
|
|
110
|
-
responseHeaders: Headers,
|
|
111
|
-
remixContext: EntryContext
|
|
112
|
-
) {
|
|
113
|
-
return new Promise((resolve, reject) => {
|
|
114
|
-
let shellRendered = false;
|
|
115
30
|
const { pipe, abort } = renderToPipeableStream(
|
|
116
31
|
<ServerRouter
|
|
117
|
-
context={
|
|
32
|
+
context={routerContext}
|
|
118
33
|
url={request.url}
|
|
119
34
|
abortDelay={ABORT_DELAY}
|
|
120
35
|
/>,
|
|
121
36
|
{
|
|
122
|
-
|
|
37
|
+
[readyOption]() {
|
|
123
38
|
shellRendered = true;
|
|
124
39
|
const body = new PassThrough();
|
|
125
40
|
const stream = createReadableStreamFromReadable(body);
|
package/dist/config/format.js
CHANGED
package/dist/config/routes.js
CHANGED
package/dist/config.js
CHANGED
package/dist/index.js
CHANGED
package/dist/invariant.js
CHANGED
package/dist/vite/babel.js
CHANGED
package/dist/vite/build.js
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
export declare function transform(code: string
|
|
1
|
+
export declare function transform(code: string, id: string, options?: {
|
|
2
|
+
ssr?: boolean;
|
|
3
|
+
}): string | import("@babel/generator").GeneratorResult;
|
|
4
|
+
export declare function parseFields(code: string): string[];
|
|
2
5
|
export declare function assertNotImported(code: string): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v0.0.0-experimental-
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-ecd35cd60
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
14
14
|
|
|
15
15
|
var babel$1 = require('@babel/core');
|
|
16
|
+
var babelDeadCodeElimination = require('babel-dead-code-elimination');
|
|
16
17
|
var babel = require('./babel.js');
|
|
17
18
|
var t = require('@babel/types');
|
|
18
19
|
var parser = require('@babel/parser');
|
|
@@ -38,23 +39,41 @@ function _interopNamespace(e) {
|
|
|
38
39
|
var babel__namespace = /*#__PURE__*/_interopNamespace(babel$1);
|
|
39
40
|
var t__namespace = /*#__PURE__*/_interopNamespace(t);
|
|
40
41
|
|
|
41
|
-
function transform(code) {
|
|
42
|
+
function transform(code, id, options = {}) {
|
|
43
|
+
if (options !== null && options !== void 0 && options.ssr) return code;
|
|
42
44
|
let ast = parse(code);
|
|
45
|
+
let refs = babelDeadCodeElimination.findReferencedIdentifiers(ast);
|
|
46
|
+
let markedForRemoval = [];
|
|
47
|
+
assertDefineRouteOnlyAfterExportDefault(ast);
|
|
43
48
|
babel.traverse(ast, {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
throw path.buildCodeFrameError("`defineRoute` must be a function call immediately after `export default`");
|
|
49
|
+
ExportDefaultDeclaration(path) {
|
|
50
|
+
let analysis = analyzeRouteExport(path);
|
|
51
|
+
for (let [key, fieldPath] of Object.entries(analysis)) {
|
|
52
|
+
if (["headers", "serverLoader", "serverAction"].includes(key)) {
|
|
53
|
+
if (!fieldPath) continue;
|
|
54
|
+
markedForRemoval.push(fieldPath);
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
|
-
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
markedForRemoval.forEach(path => path.remove());
|
|
60
|
+
babelDeadCodeElimination.deadCodeElimination(ast, refs);
|
|
61
|
+
return babel.generate(ast, {
|
|
62
|
+
sourceMaps: true,
|
|
63
|
+
sourceFileName: id
|
|
64
|
+
}, code);
|
|
65
|
+
}
|
|
66
|
+
function parseFields(code) {
|
|
67
|
+
let fields = [];
|
|
68
|
+
let ast = parse(code);
|
|
69
|
+
assertDefineRouteOnlyAfterExportDefault(ast);
|
|
70
|
+
babel.traverse(ast, {
|
|
54
71
|
ExportDefaultDeclaration(path) {
|
|
55
|
-
analyzeRouteExport(path);
|
|
72
|
+
let analysis = analyzeRouteExport(path);
|
|
73
|
+
fields = Object.keys(analysis);
|
|
56
74
|
}
|
|
57
75
|
});
|
|
76
|
+
return fields;
|
|
58
77
|
}
|
|
59
78
|
function analyzeRouteExport(path) {
|
|
60
79
|
let route = path.node.declaration;
|
|
@@ -82,6 +101,7 @@ function analyzeRouteExport(path) {
|
|
|
82
101
|
throw path.get("declaration").buildCodeFrameError("Default export of a route module must be either a literal object or a call to `defineRoute`");
|
|
83
102
|
}
|
|
84
103
|
function analyzeRoute(path) {
|
|
104
|
+
let analysis = {};
|
|
85
105
|
for (let [i, property] of path.node.properties.entries()) {
|
|
86
106
|
// spread: defineRoute({ ...dynamic })
|
|
87
107
|
if (!t__namespace.isObjectProperty(property) && !t__namespace.isObjectMethod(property)) {
|
|
@@ -109,10 +129,10 @@ function analyzeRoute(path) {
|
|
|
109
129
|
throw elementPath.buildCodeFrameError("Route param must be a literal string");
|
|
110
130
|
}
|
|
111
131
|
}
|
|
112
|
-
continue;
|
|
113
132
|
}
|
|
133
|
+
analysis[key] = propertyPath;
|
|
114
134
|
}
|
|
115
|
-
|
|
135
|
+
return analysis;
|
|
116
136
|
}
|
|
117
137
|
function assertNotImported(code) {
|
|
118
138
|
let ast = parse(code);
|
|
@@ -142,6 +162,20 @@ function parse(source) {
|
|
|
142
162
|
});
|
|
143
163
|
return ast;
|
|
144
164
|
}
|
|
165
|
+
function assertDefineRouteOnlyAfterExportDefault(ast) {
|
|
166
|
+
babel.traverse(ast, {
|
|
167
|
+
Identifier(path) {
|
|
168
|
+
if (!isDefineRoute(path)) return;
|
|
169
|
+
if (t__namespace.isImportSpecifier(path.parent)) return;
|
|
170
|
+
if (!t__namespace.isCallExpression(path.parent)) {
|
|
171
|
+
throw path.buildCodeFrameError("`defineRoute` must be a function call immediately after `export default`");
|
|
172
|
+
}
|
|
173
|
+
if (!t__namespace.isExportDefaultDeclaration(path.parentPath.parent)) {
|
|
174
|
+
throw path.buildCodeFrameError("`defineRoute` must be a function call immediately after `export default`");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
145
179
|
function isDefineRoute(path) {
|
|
146
180
|
if (!t__namespace.isIdentifier(path.node)) return false;
|
|
147
181
|
let binding = path.scope.getBinding(path.node.name);
|
|
@@ -169,4 +203,5 @@ function isCanonicallyImportedAs(binding, {
|
|
|
169
203
|
}
|
|
170
204
|
|
|
171
205
|
exports.assertNotImported = assertNotImported;
|
|
206
|
+
exports.parseFields = parseFields;
|
|
172
207
|
exports.transform = transform;
|
package/dist/vite/dev.js
CHANGED
package/dist/vite/index.js
CHANGED
package/dist/vite/plugin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v0.0.0-experimental-
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-ecd35cd60
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -108,11 +108,11 @@ async function loadPluginContext({
|
|
|
108
108
|
}
|
|
109
109
|
const SERVER_ONLY_ROUTE_EXPORTS = ["loader", "action", "headers"];
|
|
110
110
|
const CLIENT_ROUTE_EXPORTS = ["clientAction", "clientLoader", "default", "ErrorBoundary", "handle", "HydrateFallback", "Layout", "links", "meta", "shouldRevalidate"];
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
// Each route gets its own virtual module marked with an entry query string
|
|
112
|
+
const ROUTE_ENTRY_QUERY_STRING = "?route-entry=1";
|
|
113
|
+
const isRouteEntry = id => {
|
|
114
|
+
return id.endsWith(ROUTE_ENTRY_QUERY_STRING);
|
|
115
|
+
};
|
|
116
116
|
let serverBuildId = vmod.id("server-build");
|
|
117
117
|
let serverManifestId = vmod.id("server-manifest");
|
|
118
118
|
let browserManifestId = vmod.id("browser-manifest");
|
|
@@ -140,7 +140,7 @@ const getHash = (source, maxLength) => {
|
|
|
140
140
|
const resolveChunk = (ctx, viteManifest, absoluteFilePath) => {
|
|
141
141
|
let vite = importViteEsmSync.importViteEsmSync();
|
|
142
142
|
let rootRelativeFilePath = vite.normalizePath(path__namespace.relative(ctx.rootDirectory, absoluteFilePath));
|
|
143
|
-
let entryChunk = viteManifest[rootRelativeFilePath +
|
|
143
|
+
let entryChunk = viteManifest[rootRelativeFilePath + ROUTE_ENTRY_QUERY_STRING] ?? viteManifest[rootRelativeFilePath];
|
|
144
144
|
if (!entryChunk) {
|
|
145
145
|
let knownManifestKeys = Object.keys(viteManifest).map(key => '"' + key + '"').join(", ");
|
|
146
146
|
throw new Error(`No manifest entry found for "${rootRelativeFilePath}". Known manifest keys: ${knownManifestKeys}`);
|
|
@@ -195,6 +195,20 @@ const getRouteManifestModuleExports = async (viteChildCompiler, ctx) => {
|
|
|
195
195
|
return Object.fromEntries(entries);
|
|
196
196
|
};
|
|
197
197
|
const getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
|
|
198
|
+
let routePath = path__namespace.resolve(ctx.reactRouterConfig.appDirectory, routeFile);
|
|
199
|
+
let code = await ((readRouteFile === null || readRouteFile === void 0 ? void 0 : readRouteFile()) ?? fse__namespace.readFile(routePath, "utf-8"));
|
|
200
|
+
if (!code.includes("defineRoute")) {
|
|
201
|
+
return _getRouteModuleExports(viteChildCompiler, ctx, routeFile, readRouteFile);
|
|
202
|
+
}
|
|
203
|
+
let renameFields = ["Component", "serverLoader", "actionLoader"];
|
|
204
|
+
let fields = defineRoute.parseFields(code);
|
|
205
|
+
let exports = fields.filter(exportName => !renameFields.includes(exportName));
|
|
206
|
+
if (fields.includes("Component")) exports.push("default");
|
|
207
|
+
if (fields.includes("serverLoader")) exports.push("loader");
|
|
208
|
+
if (fields.includes("serverAction")) exports.push("action");
|
|
209
|
+
return exports;
|
|
210
|
+
};
|
|
211
|
+
const _getRouteModuleExports = async (viteChildCompiler, ctx, routeFile, readRouteFile) => {
|
|
198
212
|
if (!viteChildCompiler) {
|
|
199
213
|
throw new Error("Vite child compiler not found");
|
|
200
214
|
}
|
|
@@ -320,7 +334,7 @@ const reactRouterVitePlugin = _config => {
|
|
|
320
334
|
import * as entryServer from ${JSON.stringify(resolveFileUrl.resolveFileUrl(ctx, ctx.entryServerFilePath))};
|
|
321
335
|
${Object.keys(routes).map((key, index) => {
|
|
322
336
|
let route = routes[key];
|
|
323
|
-
return `import * as route${index} from ${JSON.stringify(resolveFileUrl.resolveFileUrl(ctx, resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)))};`;
|
|
337
|
+
return `import * as route${index} from ${JSON.stringify(resolveFileUrl.resolveFileUrl(ctx, resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)) + ROUTE_ENTRY_QUERY_STRING)};`;
|
|
324
338
|
}).join("\n")}
|
|
325
339
|
export { default as assets } from ${JSON.stringify(serverManifestId)};
|
|
326
340
|
export const assetsBuildDirectory = ${JSON.stringify(path__namespace.relative(ctx.rootDirectory, getClientBuildDirectory(ctx.reactRouterConfig)))};
|
|
@@ -434,7 +448,7 @@ const reactRouterVitePlugin = _config => {
|
|
|
434
448
|
path: route.path,
|
|
435
449
|
index: route.index,
|
|
436
450
|
caseSensitive: route.caseSensitive,
|
|
437
|
-
module: path__namespace.posix.join(ctx.publicPath, `${resolveFileUrl.resolveFileUrl(ctx, resolveRelativeRouteFilePath(route, ctx.reactRouterConfig))}`),
|
|
451
|
+
module: path__namespace.posix.join(ctx.publicPath, `${resolveFileUrl.resolveFileUrl(ctx, resolveRelativeRouteFilePath(route, ctx.reactRouterConfig))}${ROUTE_ENTRY_QUERY_STRING}`),
|
|
438
452
|
hasAction: sourceExports.includes("action"),
|
|
439
453
|
hasLoader: sourceExports.includes("loader"),
|
|
440
454
|
hasClientAction: sourceExports.includes("clientAction"),
|
|
@@ -540,7 +554,7 @@ const reactRouterVitePlugin = _config => {
|
|
|
540
554
|
rollupOptions: {
|
|
541
555
|
...baseRollupOptions,
|
|
542
556
|
preserveEntrySignatures: "exports-only",
|
|
543
|
-
input: [ctx.entryClientFilePath, ...Object.values(ctx.reactRouterConfig.routes).map(route => `${path__namespace.resolve(ctx.reactRouterConfig.appDirectory, route.file)}${
|
|
557
|
+
input: [ctx.entryClientFilePath, ...Object.values(ctx.reactRouterConfig.routes).map(route => `${path__namespace.resolve(ctx.reactRouterConfig.appDirectory, route.file)}${ROUTE_ENTRY_QUERY_STRING}`)]
|
|
544
558
|
}
|
|
545
559
|
} : {
|
|
546
560
|
// We move SSR-only assets to client assets. Note that the
|
|
@@ -637,13 +651,6 @@ const reactRouterVitePlugin = _config => {
|
|
|
637
651
|
if (styles.isCssModulesFile(id)) {
|
|
638
652
|
cssModulesManifest[id] = code;
|
|
639
653
|
}
|
|
640
|
-
if (id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING)) {
|
|
641
|
-
let routeModuleId = id.replace(BUILD_CLIENT_ROUTE_QUERY_STRING, "");
|
|
642
|
-
let sourceExports = await getRouteModuleExports(viteChildCompiler, ctx, routeModuleId);
|
|
643
|
-
let routeFileName = path__namespace.basename(routeModuleId);
|
|
644
|
-
let clientExports = sourceExports.filter(exportName => CLIENT_ROUTE_EXPORTS.includes(exportName)).join(", ");
|
|
645
|
-
return `export { ${clientExports} } from "./${routeFileName}";`;
|
|
646
|
-
}
|
|
647
654
|
},
|
|
648
655
|
buildStart() {
|
|
649
656
|
invariant["default"](viteConfig);
|
|
@@ -770,6 +777,34 @@ const reactRouterVitePlugin = _config => {
|
|
|
770
777
|
var _viteChildCompiler;
|
|
771
778
|
await ((_viteChildCompiler = viteChildCompiler) === null || _viteChildCompiler === void 0 ? void 0 : _viteChildCompiler.close());
|
|
772
779
|
}
|
|
780
|
+
}, {
|
|
781
|
+
name: "react-router-route-entry",
|
|
782
|
+
enforce: "pre",
|
|
783
|
+
async transform(code, id, options) {
|
|
784
|
+
if (!isRouteEntry(id)) return;
|
|
785
|
+
let routeModuleId = id.replace(ROUTE_ENTRY_QUERY_STRING, "");
|
|
786
|
+
let routeFileName = path__namespace.basename(routeModuleId);
|
|
787
|
+
if (!code.includes("defineRoute")) {
|
|
788
|
+
let sourceExports = await getRouteModuleExports(viteChildCompiler, ctx, routeModuleId);
|
|
789
|
+
let reexports = sourceExports.filter(exportName => (options === null || options === void 0 ? void 0 : options.ssr) && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS.includes(exportName)).join(", ");
|
|
790
|
+
return `export { ${reexports} } from "./${routeFileName}";`;
|
|
791
|
+
}
|
|
792
|
+
let renameFields = ["Component", "serverLoader", "serverAction"];
|
|
793
|
+
let fields = defineRoute.parseFields(code);
|
|
794
|
+
let reexports = fields.filter(exportName => !renameFields.includes(exportName)).filter(exportName => (options === null || options === void 0 ? void 0 : options.ssr) && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS.includes(exportName)).map(reexport => `export const ${reexport} = route.${reexport};`);
|
|
795
|
+
let content = `import route from "./${routeFileName}";`;
|
|
796
|
+
if (fields.includes("Component")) {
|
|
797
|
+
content += `\n` + [`import { createElement } from "react";`, `import { useParams, useLoaderData, useActionData } from "react-router";`, `export default function Route() {`, ` let params = useParams();`, ` let loaderData = useLoaderData();`, ` let actionData = useActionData();`, ` return createElement(route.Component, { params, loaderData, actionData });`, `}`].join("\n");
|
|
798
|
+
}
|
|
799
|
+
if (options !== null && options !== void 0 && options.ssr && fields.includes("serverLoader")) {
|
|
800
|
+
content += `\nexport const loader = route.serverLoader;`;
|
|
801
|
+
}
|
|
802
|
+
if (options !== null && options !== void 0 && options.ssr && fields.includes("serverAction")) {
|
|
803
|
+
content += `\nexport const action = route.serverAction;`;
|
|
804
|
+
}
|
|
805
|
+
content += "\n" + reexports.join("\n");
|
|
806
|
+
return content;
|
|
807
|
+
}
|
|
773
808
|
}, {
|
|
774
809
|
name: "react-router-virtual-modules",
|
|
775
810
|
enforce: "pre",
|
|
@@ -807,13 +842,13 @@ const reactRouterVitePlugin = _config => {
|
|
|
807
842
|
enforce: "pre",
|
|
808
843
|
async transform(code, id, options) {
|
|
809
844
|
if (options !== null && options !== void 0 && options.ssr) return;
|
|
810
|
-
if (
|
|
845
|
+
if (!code.includes("defineRoute")) return; // temporary back compat, remove once old style routes are unsupported
|
|
846
|
+
if (id.endsWith(ROUTE_ENTRY_QUERY_STRING)) return;
|
|
811
847
|
let route = getRoute(ctx.reactRouterConfig, id);
|
|
812
848
|
if (!route && code.includes("defineRoute")) {
|
|
813
849
|
return defineRoute.assertNotImported(code);
|
|
814
850
|
}
|
|
815
|
-
|
|
816
|
-
defineRoute.transform(code);
|
|
851
|
+
return defineRoute.transform(code, id, options);
|
|
817
852
|
}
|
|
818
853
|
}, {
|
|
819
854
|
name: "react-router-dot-server",
|
|
@@ -928,6 +963,11 @@ const reactRouterVitePlugin = _config => {
|
|
|
928
963
|
let isJSX = filepath.endsWith("x");
|
|
929
964
|
let useFastRefresh = !ssr && (isJSX || code.includes(devRuntime));
|
|
930
965
|
if (!useFastRefresh) return;
|
|
966
|
+
if (isRouteEntry(id)) {
|
|
967
|
+
return {
|
|
968
|
+
code: addRefreshWrapper(ctx.reactRouterConfig, code, id)
|
|
969
|
+
};
|
|
970
|
+
}
|
|
931
971
|
let result = await babel__default["default"].transformAsync(code, {
|
|
932
972
|
babelrc: false,
|
|
933
973
|
configFile: false,
|
|
@@ -996,7 +1036,7 @@ function isEqualJson(v1, v2) {
|
|
|
996
1036
|
}
|
|
997
1037
|
function addRefreshWrapper(reactRouterConfig, code, id) {
|
|
998
1038
|
let route = getRoute(reactRouterConfig, id);
|
|
999
|
-
let acceptExports = route ? ["clientAction", "clientLoader", "handle", "meta", "links", "shouldRevalidate"] : [];
|
|
1039
|
+
let acceptExports = route || isRouteEntry(id) ? ["clientAction", "clientLoader", "handle", "meta", "links", "shouldRevalidate"] : [];
|
|
1000
1040
|
return REACT_REFRESH_HEADER.replaceAll("__SOURCE__", JSON.stringify(id)) + code + REACT_REFRESH_FOOTER.replaceAll("__SOURCE__", JSON.stringify(id)).replaceAll("__ACCEPT_EXPORTS__", JSON.stringify(acceptExports)).replaceAll("__ROUTE_ID__", JSON.stringify(route === null || route === void 0 ? void 0 : route.id));
|
|
1001
1041
|
}
|
|
1002
1042
|
const REACT_REFRESH_HEADER = `
|
package/dist/vite/profiler.js
CHANGED
package/dist/vite/styles.js
CHANGED
package/dist/vite/vmod.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-router/dev",
|
|
3
|
-
"version": "0.0.0-experimental-
|
|
3
|
+
"version": "0.0.0-experimental-ecd35cd60",
|
|
4
4
|
"description": "Dev tools and CLI for React Router",
|
|
5
5
|
"homepage": "https://reactrouter.com",
|
|
6
6
|
"bugs": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"main": "dist/index.js",
|
|
16
16
|
"typings": "dist/index.d.ts",
|
|
17
17
|
"bin": {
|
|
18
|
-
"react-router": "
|
|
18
|
+
"react-router": "bin.js"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@babel/core": "^7.21.8",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"@babel/types": "^7.22.5",
|
|
29
29
|
"@npmcli/package-json": "^4.0.1",
|
|
30
30
|
"arg": "^5.0.1",
|
|
31
|
+
"babel-dead-code-elimination": "^1.0.6",
|
|
31
32
|
"chalk": "^4.1.2",
|
|
32
33
|
"es-module-lexer": "^1.3.1",
|
|
33
34
|
"exit-hook": "2.2.1",
|
|
@@ -42,7 +43,7 @@
|
|
|
42
43
|
"react-refresh": "^0.14.0",
|
|
43
44
|
"semver": "^7.3.7",
|
|
44
45
|
"set-cookie-parser": "^2.6.0",
|
|
45
|
-
"@react-router/node": "0.0.0-experimental-
|
|
46
|
+
"@react-router/node": "0.0.0-experimental-ecd35cd60"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@types/babel__core": "^7.20.5",
|
|
@@ -66,14 +67,14 @@
|
|
|
66
67
|
"strip-ansi": "^6.0.1",
|
|
67
68
|
"tiny-invariant": "^1.2.0",
|
|
68
69
|
"vite": "^5.1.0",
|
|
69
|
-
"
|
|
70
|
-
"react-router": "
|
|
70
|
+
"react-router": "^0.0.0-experimental-ecd35cd60",
|
|
71
|
+
"@react-router/serve": "0.0.0-experimental-ecd35cd60"
|
|
71
72
|
},
|
|
72
73
|
"peerDependencies": {
|
|
73
74
|
"typescript": "^5.1.0",
|
|
74
75
|
"vite": "^5.1.0",
|
|
75
|
-
"@react-router/serve": "^0.0.0-experimental-
|
|
76
|
-
"react-router": "^0.0.0-experimental-
|
|
76
|
+
"@react-router/serve": "^0.0.0-experimental-ecd35cd60",
|
|
77
|
+
"react-router": "^0.0.0-experimental-ecd35cd60"
|
|
77
78
|
},
|
|
78
79
|
"peerDependenciesMeta": {
|
|
79
80
|
"@react-router/serve": {
|
|
@@ -88,6 +89,7 @@
|
|
|
88
89
|
},
|
|
89
90
|
"files": [
|
|
90
91
|
"dist/",
|
|
92
|
+
"bin.js",
|
|
91
93
|
"CHANGELOG.md",
|
|
92
94
|
"LICENSE.md",
|
|
93
95
|
"README.md"
|