Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions packages/vinext/src/cloudflare/tpr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { spawn, type ChildProcess } from "node:child_process";

// ─── Types ───────────────────────────────────────────────────────────────────
Expand Down Expand Up @@ -608,8 +607,7 @@ async function prerenderRoutes(
* to the current module (works whether vinext is installed or linked).
*/
function startLocalServer(root: string, port: number): ChildProcess {
const thisDir = fileURLToPath(new URL(".", import.meta.url));
const prodServerPath = path.resolve(thisDir, "..", "server", "prod-server.js");
const prodServerPath = path.resolve(import.meta.dirname, "..", "server", "prod-server.js");
const outDir = path.join(root, "dist");

// Escape backslashes for Windows paths inside the JS string
Expand Down
82 changes: 35 additions & 47 deletions packages/vinext/src/entries/app-rsc-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Previously housed in server/app-dev-server.ts.
*/
import fs from "node:fs";
import { fileURLToPath } from "node:url";
import { resolveEntryPath } from "./runtime-entry-module.js";
import type {
NextHeader,
NextI18nConfig,
Expand All @@ -29,52 +29,40 @@ import { isProxyFile } from "../server/middleware.js";
// Pre-computed absolute paths for generated-code imports. The virtual RSC
// entry can't use relative imports (it has no real file location), so we
// resolve these at code-generation time and embed them as absolute paths.
const configMatchersPath = fileURLToPath(
new URL("../config/config-matchers.js", import.meta.url),
).replace(/\\/g, "/");
const requestPipelinePath = fileURLToPath(
new URL("../server/request-pipeline.js", import.meta.url),
).replace(/\\/g, "/");
const requestContextShimPath = fileURLToPath(
new URL("../shims/request-context.js", import.meta.url),
).replace(/\\/g, "/");
const normalizePathModulePath = fileURLToPath(
new URL("../server/normalize-path.js", import.meta.url),
).replace(/\\/g, "/");
const appRouteHandlerRuntimePath = fileURLToPath(
new URL("../server/app-route-handler-runtime.js", import.meta.url),
).replace(/\\/g, "/");
const appRouteHandlerPolicyPath = fileURLToPath(
new URL("../server/app-route-handler-policy.js", import.meta.url),
).replace(/\\/g, "/");
const appRouteHandlerExecutionPath = fileURLToPath(
new URL("../server/app-route-handler-execution.js", import.meta.url),
).replace(/\\/g, "/");
const appRouteHandlerCachePath = fileURLToPath(
new URL("../server/app-route-handler-cache.js", import.meta.url),
).replace(/\\/g, "/");
const appPageCachePath = fileURLToPath(
new URL("../server/app-page-cache.js", import.meta.url),
).replace(/\\/g, "/");
const appPageExecutionPath = fileURLToPath(
new URL("../server/app-page-execution.js", import.meta.url),
).replace(/\\/g, "/");
const appPageBoundaryRenderPath = fileURLToPath(
new URL("../server/app-page-boundary-render.js", import.meta.url),
).replace(/\\/g, "/");
const appPageRenderPath = fileURLToPath(
new URL("../server/app-page-render.js", import.meta.url),
).replace(/\\/g, "/");
const appPageRequestPath = fileURLToPath(
new URL("../server/app-page-request.js", import.meta.url),
).replace(/\\/g, "/");
const appRouteHandlerResponsePath = fileURLToPath(
new URL("../server/app-route-handler-response.js", import.meta.url),
).replace(/\\/g, "/");
const routeTriePath = fileURLToPath(new URL("../routing/route-trie.js", import.meta.url)).replace(
/\\/g,
"/",
const configMatchersPath = resolveEntryPath("../config/config-matchers.js", import.meta.url);
const requestPipelinePath = resolveEntryPath("../server/request-pipeline.js", import.meta.url);
const requestContextShimPath = resolveEntryPath("../shims/request-context.js", import.meta.url);
const normalizePathModulePath = resolveEntryPath("../server/normalize-path.js", import.meta.url);
const appRouteHandlerRuntimePath = resolveEntryPath(
"../server/app-route-handler-runtime.js",
import.meta.url,
);
const appRouteHandlerPolicyPath = resolveEntryPath(
"../server/app-route-handler-policy.js",
import.meta.url,
);
const appRouteHandlerExecutionPath = resolveEntryPath(
"../server/app-route-handler-execution.js",
import.meta.url,
);
const appRouteHandlerCachePath = resolveEntryPath(
"../server/app-route-handler-cache.js",
import.meta.url,
);
const appPageCachePath = resolveEntryPath("../server/app-page-cache.js", import.meta.url);
const appPageExecutionPath = resolveEntryPath("../server/app-page-execution.js", import.meta.url);
const appPageBoundaryRenderPath = resolveEntryPath(
"../server/app-page-boundary-render.js",
import.meta.url,
);
const appPageRenderPath = resolveEntryPath("../server/app-page-render.js", import.meta.url);
const appPageRequestPath = resolveEntryPath("../server/app-page-request.js", import.meta.url);
const appRouteHandlerResponsePath = resolveEntryPath(
"../server/app-route-handler-response.js",
import.meta.url,
);
const routeTriePath = resolveEntryPath("../routing/route-trie.js", import.meta.url);
const metadataRoutesPath = resolveEntryPath("../server/metadata-routes.js", import.meta.url);

/**
* Resolved config options relevant to App Router request handling.
Expand Down Expand Up @@ -358,7 +346,7 @@ import { LayoutSegmentProvider } from "vinext/layout-segment-context";
import { MetadataHead, mergeMetadata, resolveModuleMetadata, ViewportHead, mergeViewport, resolveModuleViewport } from "vinext/metadata";
${middlewarePath ? `import * as middlewareModule from ${JSON.stringify(middlewarePath.replace(/\\/g, "/"))};` : ""}
${instrumentationPath ? `import * as _instrumentation from ${JSON.stringify(instrumentationPath.replace(/\\/g, "/"))};` : ""}
${effectiveMetaRoutes.length > 0 ? `import { sitemapToXml, robotsToText, manifestToJson } from ${JSON.stringify(fileURLToPath(new URL("../server/metadata-routes.js", import.meta.url)).replace(/\\/g, "/"))};` : ""}
${effectiveMetaRoutes.length > 0 ? `import { sitemapToXml, robotsToText, manifestToJson } from ${JSON.stringify(metadataRoutesPath)};` : ""}
import { requestContextFromRequest, normalizeHost, matchRedirect, matchRewrite, matchHeaders, isExternalUrl, proxyExternalRequest, sanitizeDestination } from ${JSON.stringify(configMatchersPath)};
import { decodePathParams as __decodePathParams } from ${JSON.stringify(normalizePathModulePath)};
import { validateCsrfOrigin, validateImageUrl, guardProtocolRelativeUrl, hasBasePath, stripBasePath, normalizeTrailingSlash, processMiddlewareHeaders } from ${JSON.stringify(requestPipelinePath)};
Expand Down
42 changes: 12 additions & 30 deletions packages/vinext/src/entries/pages-server-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
*
* Extracted from index.ts.
*/
import path from "node:path";
import { fileURLToPath } from "node:url";
import { resolveEntryPath } from "./runtime-entry-module.js";
import { pagesRouter, apiRouter, type Route } from "../routing/pages-router.js";
import { createValidFileMatcher } from "../routing/file-matcher.js";
import { type ResolvedNextConfig } from "../config/next-config.js";
Expand All @@ -21,34 +20,17 @@ import {
} from "../server/middleware-codegen.js";
import { findFileWithExts } from "./pages-entry-helpers.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const _requestContextShimPath = fileURLToPath(
new URL("../shims/request-context.js", import.meta.url),
).replace(/\\/g, "/");
const _routeTriePath = fileURLToPath(new URL("../routing/route-trie.js", import.meta.url)).replace(
/\\/g,
"/",
);
const _pagesI18nPath = fileURLToPath(new URL("../server/pages-i18n.js", import.meta.url)).replace(
/\\/g,
"/",
);
const _pagesPageResponsePath = fileURLToPath(
new URL("../server/pages-page-response.js", import.meta.url),
).replace(/\\/g, "/");
const _pagesPageDataPath = fileURLToPath(
new URL("../server/pages-page-data.js", import.meta.url),
).replace(/\\/g, "/");
const _pagesNodeCompatPath = fileURLToPath(
new URL("../server/pages-node-compat.js", import.meta.url),
).replace(/\\/g, "/");
const _pagesApiRoutePath = fileURLToPath(
new URL("../server/pages-api-route.js", import.meta.url),
).replace(/\\/g, "/");
const _isrCachePath = fileURLToPath(new URL("../server/isr-cache.js", import.meta.url)).replace(
/\\/g,
"/",
const _requestContextShimPath = resolveEntryPath("../shims/request-context.js", import.meta.url);
const _routeTriePath = resolveEntryPath("../routing/route-trie.js", import.meta.url);
const _pagesI18nPath = resolveEntryPath("../server/pages-i18n.js", import.meta.url);
const _pagesPageResponsePath = resolveEntryPath(
"../server/pages-page-response.js",
import.meta.url,
);
const _pagesPageDataPath = resolveEntryPath("../server/pages-page-data.js", import.meta.url);
const _pagesNodeCompatPath = resolveEntryPath("../server/pages-node-compat.js", import.meta.url);
const _pagesApiRoutePath = resolveEntryPath("../server/pages-api-route.js", import.meta.url);
const _isrCachePath = resolveEntryPath("../server/isr-cache.js", import.meta.url);

/**
* Generate the virtual SSR server entry module.
Expand Down Expand Up @@ -291,7 +273,7 @@ import { setI18nContext } from "vinext/i18n-context";
import { safeJsonStringify } from "vinext/html";
import { getSSRFontLinks as _getSSRFontLinks, getSSRFontStyles as _getSSRFontStylesGoogle, getSSRFontPreloads as _getSSRFontPreloadsGoogle } from "next/font/google";
import { getSSRFontStyles as _getSSRFontStylesLocal, getSSRFontPreloads as _getSSRFontPreloadsLocal } from "next/font/local";
import { sanitizeDestination as sanitizeDestinationLocal } from ${JSON.stringify(path.resolve(__dirname, "../config/config-matchers.js").replace(/\\/g, "/"))};
import { sanitizeDestination as sanitizeDestinationLocal } from ${JSON.stringify(resolveEntryPath("../config/config-matchers.js", import.meta.url))};
import { runWithExecutionContext as _runWithExecutionContext, getRequestExecutionContext as _getRequestExecutionContext } from ${JSON.stringify(_requestContextShimPath)};
import { buildRouteTrie as _buildRouteTrie, trieMatch as _trieMatch } from ${JSON.stringify(_routeTriePath)};
import { reportRequestError as _reportRequestError } from "vinext/instrumentation";
Expand Down
21 changes: 18 additions & 3 deletions packages/vinext/src/entries/runtime-entry-module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import fs from "node:fs";
import { fileURLToPath } from "node:url";

/**
* Resolve a sibling module path relative to a caller's `import.meta.url`,
* returning a forward-slash path safe for embedding in generated code.
*
* This is the single place that owns the
* `fileURLToPath(new URL(rel, base)).replace(/\\/g, "/")` idiom so callers
* don't duplicate it.
*
* @param rel - Relative path to the target module (e.g. `"../server/foo.js"`)
* @param base - The caller's `import.meta.url`
*/
export function resolveEntryPath(rel: string, base: string): string {
return fileURLToPath(new URL(rel, base)).replace(/\\/g, "/");
}

/**
* Resolve a real runtime module for a virtual entry generator.
*
Expand All @@ -11,11 +26,11 @@ import { fileURLToPath } from "node:url";
*/
export function resolveRuntimeEntryModule(name: string): string {
for (const ext of [".ts", ".js", ".mts", ".mjs"]) {
const filePath = fileURLToPath(new URL(`../server/${name}${ext}`, import.meta.url));
const filePath = resolveEntryPath(`../server/${name}${ext}`, import.meta.url);
if (fs.existsSync(filePath)) {
return filePath.replace(/\\/g, "/");
return filePath;
}
}

return fileURLToPath(new URL(`../server/${name}.js`, import.meta.url)).replace(/\\/g, "/");
return resolveEntryPath(`../server/${name}.js`, import.meta.url);
}
4 changes: 2 additions & 2 deletions packages/vinext/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ import tsconfigPaths from "vite-tsconfig-paths";
import type { Options as VitePluginReactOptions } from "@vitejs/plugin-react";
import MagicString from "magic-string";
import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { pathToFileURL } from "node:url";
import { createRequire } from "node:module";
import fs from "node:fs";
import { randomBytes } from "node:crypto";
import commonjs from "vite-plugin-commonjs";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const __dirname = import.meta.dirname;
type VitePluginReactModule = typeof import("@vitejs/plugin-react");

function resolveOptionalDependency(projectRoot: string, specifier: string): string | null {
Expand Down
Loading