vinext 0.2.0 → 1.0.0-beta.0

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.
Files changed (168) hide show
  1. package/README.md +50 -29
  2. package/dist/build/client-build-config.d.ts +13 -92
  3. package/dist/build/client-build-config.js +17 -95
  4. package/dist/build/css-url-assets.d.ts +3 -1
  5. package/dist/build/css-url-assets.js +18 -1
  6. package/dist/build/inject-pregenerated-paths.d.ts +3 -0
  7. package/dist/build/inject-pregenerated-paths.js +4 -1
  8. package/dist/build/prerender-paths.d.ts +23 -0
  9. package/dist/build/prerender-paths.js +296 -0
  10. package/dist/build/prerender-server-entry.d.ts +1 -0
  11. package/dist/build/prerender-server-entry.js +49 -0
  12. package/dist/build/prerender-server-pool.d.ts +44 -0
  13. package/dist/build/prerender-server-pool.js +194 -0
  14. package/dist/build/prerender.d.ts +12 -1
  15. package/dist/build/prerender.js +87 -23
  16. package/dist/build/run-prerender.js +2 -1
  17. package/dist/cache/cache-adapters-virtual.d.ts +7 -1
  18. package/dist/cache/cache-adapters-virtual.js +26 -2
  19. package/dist/check.d.ts +4 -6
  20. package/dist/check.js +13 -9
  21. package/dist/cli.js +34 -54
  22. package/dist/client/vinext-next-data.d.ts +4 -1
  23. package/dist/config/config-matchers.js +33 -11
  24. package/dist/config/next-config.d.ts +36 -6
  25. package/dist/config/next-config.js +17 -4
  26. package/dist/config/prerender.d.ts +11 -1
  27. package/dist/config/prerender.js +19 -1
  28. package/dist/config/tsconfig-paths.js +5 -1
  29. package/dist/entries/app-browser-entry.js +5 -1
  30. package/dist/entries/app-rsc-entry.d.ts +3 -2
  31. package/dist/entries/app-rsc-entry.js +4 -0
  32. package/dist/entries/pages-client-entry.js +14 -3
  33. package/dist/entries/pages-server-entry.js +18 -4
  34. package/dist/image/image-adapters-virtual.js +1 -0
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.js +549 -152
  37. package/dist/init-cloudflare.js +12 -3
  38. package/dist/init-platform.d.ts +10 -1
  39. package/dist/init-platform.js +78 -12
  40. package/dist/init.d.ts +11 -3
  41. package/dist/init.js +129 -31
  42. package/dist/plugins/fonts.js +1 -1
  43. package/dist/plugins/ignore-dynamic-requests.js +1 -1
  44. package/dist/plugins/og-assets.js +2 -1
  45. package/dist/plugins/optimize-imports.js +1 -1
  46. package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
  47. package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
  48. package/dist/plugins/sass.d.ts +17 -1
  49. package/dist/plugins/sass.js +74 -1
  50. package/dist/plugins/styled-jsx.d.ts +16 -0
  51. package/dist/plugins/styled-jsx.js +149 -0
  52. package/dist/routing/app-route-graph.js +22 -16
  53. package/dist/routing/file-matcher.d.ts +8 -1
  54. package/dist/routing/file-matcher.js +15 -3
  55. package/dist/server/app-browser-entry.js +44 -14
  56. package/dist/server/app-browser-navigation-controller.js +5 -2
  57. package/dist/server/app-browser-server-action-client.js +5 -3
  58. package/dist/server/app-browser-state.d.ts +1 -0
  59. package/dist/server/app-browser-state.js +1 -1
  60. package/dist/server/app-layout-param-observation.d.ts +1 -1
  61. package/dist/server/app-page-boundary.js +2 -1
  62. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  63. package/dist/server/app-page-cache-finalizer.js +3 -3
  64. package/dist/server/app-page-cache-render.d.ts +1 -1
  65. package/dist/server/app-page-cache.js +23 -6
  66. package/dist/server/app-page-dispatch.d.ts +2 -1
  67. package/dist/server/app-page-dispatch.js +27 -10
  68. package/dist/server/app-page-element-builder.js +1 -0
  69. package/dist/server/app-page-execution.js +2 -1
  70. package/dist/server/app-page-render-identity.d.ts +1 -0
  71. package/dist/server/app-page-render-identity.js +2 -1
  72. package/dist/server/app-page-render.d.ts +3 -1
  73. package/dist/server/app-page-render.js +67 -16
  74. package/dist/server/app-page-response.d.ts +7 -0
  75. package/dist/server/app-page-response.js +16 -4
  76. package/dist/server/app-page-route-wiring.js +3 -3
  77. package/dist/server/app-page-stream.d.ts +2 -1
  78. package/dist/server/app-page-stream.js +1 -1
  79. package/dist/server/app-route-handler-execution.d.ts +1 -1
  80. package/dist/server/app-route-tree-prefetch.d.ts +43 -0
  81. package/dist/server/app-route-tree-prefetch.js +187 -0
  82. package/dist/server/app-router-entry.js +1 -1
  83. package/dist/server/app-rsc-cache-busting.d.ts +2 -1
  84. package/dist/server/app-rsc-cache-busting.js +9 -5
  85. package/dist/server/app-rsc-handler.d.ts +6 -0
  86. package/dist/server/app-rsc-handler.js +88 -10
  87. package/dist/server/app-rsc-render-mode.d.ts +3 -5
  88. package/dist/server/app-rsc-render-mode.js +5 -12
  89. package/dist/server/app-rsc-request-normalization.d.ts +3 -4
  90. package/dist/server/app-rsc-request-normalization.js +4 -5
  91. package/dist/server/app-server-action-execution.js +6 -5
  92. package/dist/server/app-ssr-entry.js +1 -1
  93. package/dist/server/cache-control.d.ts +3 -1
  94. package/dist/server/cache-control.js +13 -1
  95. package/dist/server/dev-module-runner.js +1 -1
  96. package/dist/server/dev-origin-check.d.ts +2 -2
  97. package/dist/server/dev-origin-check.js +2 -2
  98. package/dist/server/dev-server.d.ts +11 -1
  99. package/dist/server/dev-server.js +82 -24
  100. package/dist/server/headers.d.ts +6 -2
  101. package/dist/server/headers.js +11 -5
  102. package/dist/server/image-optimization.d.ts +12 -1
  103. package/dist/server/image-optimization.js +13 -1
  104. package/dist/server/isr-cache.d.ts +13 -4
  105. package/dist/server/isr-cache.js +8 -4
  106. package/dist/server/pages-data-route.d.ts +4 -2
  107. package/dist/server/pages-data-route.js +18 -4
  108. package/dist/server/pages-dev-module-url.d.ts +2 -1
  109. package/dist/server/pages-dev-module-url.js +6 -3
  110. package/dist/server/pages-node-compat.d.ts +12 -1
  111. package/dist/server/pages-node-compat.js +50 -1
  112. package/dist/server/pages-page-data.d.ts +9 -0
  113. package/dist/server/pages-page-data.js +18 -10
  114. package/dist/server/pages-page-handler.js +19 -7
  115. package/dist/server/pages-page-response.d.ts +1 -0
  116. package/dist/server/pages-page-response.js +5 -4
  117. package/dist/server/pages-request-pipeline.d.ts +8 -6
  118. package/dist/server/pages-request-pipeline.js +31 -7
  119. package/dist/server/pages-router-entry.js +1 -1
  120. package/dist/server/prerender-manifest.d.ts +15 -1
  121. package/dist/server/prerender-manifest.js +29 -1
  122. package/dist/server/prod-server.d.ts +10 -7
  123. package/dist/server/prod-server.js +43 -28
  124. package/dist/server/request-pipeline.js +1 -1
  125. package/dist/server/static-file-cache.js +1 -1
  126. package/dist/shims/cache-handler.js +8 -1
  127. package/dist/shims/cache.d.ts +1 -1
  128. package/dist/shims/cache.js +3 -0
  129. package/dist/shims/cdn-cache.d.ts +2 -7
  130. package/dist/shims/cdn-cache.js +2 -14
  131. package/dist/shims/fetch-cache.d.ts +3 -1
  132. package/dist/shims/fetch-cache.js +77 -52
  133. package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
  134. package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
  135. package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -1
  136. package/dist/shims/internal/hybrid-client-route-owner.js +34 -1
  137. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +2 -1
  138. package/dist/shims/internal/pages-data-fetch-dedup.js +13 -2
  139. package/dist/shims/internal/pages-data-target.d.ts +8 -3
  140. package/dist/shims/internal/pages-data-target.js +9 -4
  141. package/dist/shims/link.d.ts +1 -1
  142. package/dist/shims/link.js +179 -42
  143. package/dist/shims/navigation.d.ts +15 -3
  144. package/dist/shims/navigation.js +202 -39
  145. package/dist/shims/request-context.js +18 -0
  146. package/dist/shims/request-state-types.d.ts +2 -2
  147. package/dist/shims/router.js +31 -15
  148. package/dist/shims/unified-request-context.d.ts +1 -1
  149. package/dist/shims/unified-request-context.js +1 -0
  150. package/dist/typegen.js +1 -1
  151. package/dist/utils/middleware-request-headers.js +1 -1
  152. package/dist/utils/project.d.ts +1 -1
  153. package/dist/utils/protocol-headers.d.ts +7 -1
  154. package/dist/utils/protocol-headers.js +7 -1
  155. package/dist/utils/vite-version.d.ts +4 -12
  156. package/dist/utils/vite-version.js +39 -21
  157. package/package.json +31 -13
  158. package/dist/cloudflare/index.d.ts +0 -3
  159. package/dist/cloudflare/index.js +0 -3
  160. package/dist/packages/cloudflare/src/cache/cdn-adapter.runtime.js +0 -102
  161. package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +0 -126
  162. package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.js +0 -435
  163. package/dist/packages/cloudflare/src/deploy-config.js +0 -150
  164. package/dist/packages/cloudflare/src/deploy-help.js +0 -55
  165. package/dist/packages/cloudflare/src/deploy.js +0 -276
  166. package/dist/packages/cloudflare/src/tpr.d.ts +0 -45
  167. package/dist/packages/cloudflare/src/tpr.js +0 -561
  168. package/dist/packages/cloudflare/src/utils/cache-control-metadata.js +0 -20
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { detectPackageManager, formatMissingCloudflarePluginError, hasWranglerConfig } from "./utils/project.js";
2
+ import { normalizePathSeparators, stripJsExtension, stripViteModuleQuery } from "./utils/path.js";
2
3
  import { normalizePathnameForRouteMatchStrict } from "./routing/utils.js";
3
4
  import { escapeRegExp } from "./utils/regex.js";
4
- import { normalizePathSeparators, stripJsExtension, stripViteModuleQuery } from "./utils/path.js";
5
5
  import { buildViteResolveExtensions, createValidFileMatcher, findFileWithExts, normalizeViteResolveExtensions } from "./routing/file-matcher.js";
6
6
  import { apiRouter, invalidateRouteCache, matchRoute, pagesRouter } from "./routing/pages-router.js";
7
7
  import { VINEXT_MW_CTX_HEADER } from "./utils/protocol-headers.js";
@@ -11,15 +11,16 @@ import { matchesRewriteSource, proxyExternalRequest } from "./config/config-matc
11
11
  import { isOpenRedirectShaped } from "./server/open-redirect.js";
12
12
  import { filterInternalHeaders, normalizeTrailingSlash } from "./server/request-pipeline.js";
13
13
  import { findMiddlewareFile, isProxyFile, runMiddleware } from "./server/middleware.js";
14
+ import { extractMiddlewareMatcherConfig, hasExportedName } from "./build/report.js";
14
15
  import { generateServerEntry } from "./entries/pages-server-entry.js";
15
- import { extractMiddlewareMatcherConfig } from "./build/report.js";
16
16
  import { generateClientEntry } from "./entries/pages-client-entry.js";
17
17
  import { appRouteGraph, appRouter, invalidateAppRouteCache, matchAppRoute } from "./routing/app-router.js";
18
18
  import { findInstrumentationClientFile, findInstrumentationFile, runInstrumentation } from "./server/instrumentation.js";
19
19
  import { isUnknownRecord } from "./utils/record.js";
20
20
  import { logRequest, now } from "./server/request-log.js";
21
- import { resolvePagesI18nRequest } from "./server/pages-i18n.js";
22
- import { isNextDataPathname, parseNextDataPathname } from "./server/pages-data-route.js";
21
+ import { resolvePagesI18nRequest, stripI18nLocaleForApiRoute } from "./server/pages-i18n.js";
22
+ import { isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname } from "./server/pages-data-route.js";
23
+ import { resolveAssetsDir } from "./utils/asset-prefix.js";
23
24
  import { createSSRHandler } from "./server/dev-server.js";
24
25
  import { handleApiRoute } from "./server/api-handler.js";
25
26
  import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, resolveDevImageRedirect } from "./server/image-optimization.js";
@@ -30,15 +31,13 @@ import { createDirectRunner } from "./server/dev-module-runner.js";
30
31
  import { validateDevRequest } from "./server/dev-origin-check.js";
31
32
  import { generateRscEntry } from "./entries/app-rsc-entry.js";
32
33
  import { generateSsrEntry } from "./entries/app-ssr-entry.js";
33
- import { VIRTUAL_CACHE_ADAPTERS, generateCacheAdaptersModule } from "./cache/cache-adapters-virtual.js";
34
+ import { VINEXT_CACHE_CONFIG_PLUGIN_PROPERTY, VIRTUAL_CACHE_ADAPTERS, generateCacheAdaptersModule } from "./cache/cache-adapters-virtual.js";
34
35
  import { VIRTUAL_IMAGE_ADAPTERS, generateImageAdaptersModule } from "./image/image-adapters-virtual.js";
35
36
  import { generateBrowserEntry, isLinkPrefetchRoute, toDocumentOnlyAppRoute, toLinkPrefetchRoute } from "./entries/app-browser-entry.js";
36
37
  import { collectRouteClassificationManifest } from "./build/route-classification-manifest.js";
37
38
  import { planRouteClassificationInjection } from "./build/route-classification-injector.js";
38
39
  import { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } from "./shims/constants.js";
39
- import { resolveAssetsDir } from "./utils/asset-prefix.js";
40
40
  import { RESOLVED_VIRTUAL_GOOGLE_FONTS, VIRTUAL_GOOGLE_FONTS, createGoogleFontsPlugin, createLocalFontsPlugin, generateGoogleFontsVirtualModule, parseStaticObjectLiteral } from "./plugins/fonts.js";
41
- import { getDepOptimizeNodeEnvOptions, getViteMajorVersion, serializeViteDefine } from "./utils/vite-version.js";
42
41
  import { createRscCompatibilityId, findNextConfigPath, loadNextConfig, resolveNextConfig, resolveNextConfigInput } from "./config/next-config.js";
43
42
  import { mergeServerExternalPackages } from "./config/server-external-packages.js";
44
43
  import { precompressAssets } from "./build/precompress.js";
@@ -55,7 +54,9 @@ import { clientReferenceDedupPlugin } from "./plugins/client-reference-dedup.js"
55
54
  import { dataUrlCssPlugin } from "./plugins/css-data-url.js";
56
55
  import { createCssModuleImportCompatibilityPlugin } from "./plugins/css-module-imports.js";
57
56
  import { createRscClientReferenceLoadersPlugin } from "./plugins/rsc-client-reference-loaders.js";
57
+ import { createRscReferenceValidationNormalizerPlugin } from "./plugins/rsc-reference-validation-normalizer.js";
58
58
  import { createInstrumentationClientTransformPlugin } from "./plugins/instrumentation-client.js";
59
+ import { createStyledJsxPlugin } from "./plugins/styled-jsx.js";
59
60
  import { INSTRUMENTATION_CLIENT_EMPTY_MODULE, generateInstrumentationClientInjectModule } from "./client/instrumentation-client-inject.js";
60
61
  import { createMiddlewareServerOnlyPlugin } from "./plugins/middleware-server-only.js";
61
62
  import { validateMiddlewareModuleExports } from "./plugins/middleware-export-validation.js";
@@ -70,9 +71,9 @@ import { VINEXT_CLIENT_ENTRY_MANIFEST } from "./utils/client-entry-manifest.js";
70
71
  import { computeClientRuntimeMetadata } from "./utils/client-runtime-metadata.js";
71
72
  import { PAGES_CLIENT_ASSETS_MODULE, buildPagesClientAssetsModule, setPagesClientAssetsBuildMetadata, takePagesClientAssetsBuildMetadata, writePagesClientAssetsModuleIfMissing } from "./build/pages-client-assets-module.js";
72
73
  import { resolvePostcssStringPlugins } from "./plugins/postcss.js";
73
- import { buildSassPreprocessorOptions, createSassAwareFileSystemLoader, createSassTildeImporter } from "./plugins/sass.js";
74
- import { createClientAssetFileNames, createClientCodeSplittingConfig, createClientFileNameConfig, createClientManualChunks, createClientOutputConfig, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfigForVite, withBuildBundlerOptions } from "./build/client-build-config.js";
75
74
  import { markCssUrlAssetReferences, restoreDedupedCssAssetReferences } from "./build/css-url-assets.js";
75
+ import { buildSassPreprocessorOptions, createSassAwareFileSystemLoader, createSassCssUrlAssetImporter, createSassTildeImporter } from "./plugins/sass.js";
76
+ import { createClientAssetFileNames, createClientCodeSplittingConfig, createClientFileNameConfig, createClientManualChunks, createRscFrameworkChunkOutputConfig, getBuildBundlerOptions, getClientTreeshakeConfig, withBuildBundlerOptions } from "./build/client-build-config.js";
76
77
  import { hasExportAllCandidate, stripServerExports, validatePageExports } from "./plugins/strip-server-exports.js";
77
78
  import { removeConsoleCalls } from "./plugins/remove-console.js";
78
79
  import { createImportMetaUrlPlugin } from "./plugins/import-meta-url.js";
@@ -83,17 +84,30 @@ import { getTypeofWindowReplacement, replaceTypeofWindow } from "./plugins/typeo
83
84
  import { hasMdxFiles } from "./utils/mdx-scan.js";
84
85
  import { scanPublicFileRoutes } from "./utils/public-routes.js";
85
86
  import { createIgnoreDynamicRequestsPlugin } from "./plugins/ignore-dynamic-requests.js";
86
- import { VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY, normalizeVinextPrerenderConfig } from "./config/prerender.js";
87
+ import { assertSupportedViteVersion, getDepOptimizeNodeEnvOptions, serializeViteDefine } from "./utils/vite-version.js";
88
+ import { VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY, VINEXT_ROUTE_ROOT_CONFIG_PLUGIN_PROPERTY, normalizeVinextPrerenderConfig } from "./config/prerender.js";
87
89
  import { staticExportApp, staticExportPages } from "./build/static-export.js";
88
90
  import { createRequire } from "node:module";
89
91
  import fs from "node:fs";
90
92
  import path from "node:path";
91
- import { loadEnv, parseAst, transformWithOxc } from "vite";
93
+ import { createLogger, loadEnv, parseAst, transformWithOxc } from "vite";
92
94
  import { pathToFileURL } from "node:url";
93
95
  import { createHash, randomBytes, randomUUID } from "node:crypto";
94
96
  import commonjs from "vite-plugin-commonjs";
95
97
  import MagicString from "magic-string";
96
98
  //#region src/index.ts
99
+ const PAGES_CLOUDFLARE_WORKER_OPTIMIZE_DEPS_EXCLUDE = Object.freeze(["vinext/server/fetch-handler", "vinext/server/pages-router-entry"]);
100
+ const PAGES_CLOUDFLARE_WORKER_OPTIMIZE_DEPS_INCLUDE = Object.freeze([
101
+ "react",
102
+ "react-dom",
103
+ "react-dom/server.edge",
104
+ "react/jsx-runtime",
105
+ "react/jsx-dev-runtime",
106
+ "use-sync-external-store/with-selector"
107
+ ]);
108
+ const OPTIONAL_OPTIMIZE_DEPS_WARNING_RE = /Failed to resolve dependency: .*use-sync-external-store\/with-selector.*present in .* 'optimizeDeps\.include'/;
109
+ const VINEXT_FILTERED_OPTIMIZE_DEPS_WARN = Symbol.for("vinext.filteredOptimizeDepsWarn");
110
+ const ANSI_ESCAPE_RE = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
97
111
  installSocketErrorBackstop();
98
112
  function getCacheDirPrefix(cacheDir) {
99
113
  const normalizedCacheDir = normalizePathSeparators(cacheDir);
@@ -145,11 +159,6 @@ function resolveOptionalDependency(projectRoot, specifier) {
145
159
  } catch {}
146
160
  return null;
147
161
  }
148
- async function loadVite7TsconfigPathsPlugin(projectRoot) {
149
- const resolvedPath = resolveOptionalDependency(projectRoot, "vite-tsconfig-paths");
150
- if (!resolvedPath) throw new Error("[vinext] Vite 7 requires the optional peer dependency vite-tsconfig-paths for tsconfig path alias support. Install vite-tsconfig-paths or upgrade to Vite 8.");
151
- return (await import(pathToFileURL(resolvedPath).href)).default();
152
- }
153
162
  function resolveShimModulePath(shimsDir, moduleName) {
154
163
  for (const ext of [
155
164
  ".ts",
@@ -172,6 +181,122 @@ function isVinextOgShimImporter(importer) {
172
181
  function toRelativeFileEntry(root, absPath) {
173
182
  return path.relative(root, absPath).split(path.sep).join("/");
174
183
  }
184
+ const DEV_PAGES_CLIENT_ENTRY = "/@id/__x00__virtual:vinext-client-entry";
185
+ const STYLESHEET_IMPORT_RE = /\.(?:css|scss|sass)$/i;
186
+ const STYLESHEET_FILE_RE = /\.(?:css|scss|sass)$/i;
187
+ const SCRIPT_IMPORT_RE = /\.(?:[cm]?[jt]sx?)$/i;
188
+ const GLOBAL_NOT_FOUND_CSS_QUERY = "?vinext-global-not-found-css";
189
+ function toMagicStringTransformResult(output) {
190
+ return {
191
+ code: output.toString(),
192
+ map: output.generateMap({ hires: "boundary" })
193
+ };
194
+ }
195
+ function parserLanguageForScript(id) {
196
+ const cleanId = stripViteModuleQuery(id).toLowerCase();
197
+ return cleanId.endsWith(".ts") || cleanId.endsWith(".mts") || cleanId.endsWith(".cts") ? "ts" : "tsx";
198
+ }
199
+ function isStylesheetSpecifier(specifier) {
200
+ if (specifier.includes("?") || specifier.includes("#")) return false;
201
+ return STYLESHEET_IMPORT_RE.test(specifier.toLowerCase());
202
+ }
203
+ function isMdxModuleId(id) {
204
+ return stripViteModuleQuery(id).toLowerCase().endsWith(".mdx");
205
+ }
206
+ function isolateMdxStylesheetImports(code) {
207
+ const importRe = /(^|[;\n])(\s*import\s*)(["'])([^"'\n;]+)(\3)/g;
208
+ let output = null;
209
+ for (const match of code.matchAll(importRe)) {
210
+ const specifier = match[4];
211
+ if (!isStylesheetSpecifier(specifier)) continue;
212
+ const specifierStart = match.index + match[1].length + match[2].length + match[3].length;
213
+ const specifierEnd = specifierStart + specifier.length;
214
+ output ??= new MagicString(code);
215
+ output.overwrite(specifierStart, specifierEnd, specifier + GLOBAL_NOT_FOUND_CSS_QUERY);
216
+ }
217
+ return output ? toMagicStringTransformResult(output) : null;
218
+ }
219
+ function isolateGlobalNotFoundStylesheetImports(code, id) {
220
+ if (isMdxModuleId(id)) return isolateMdxStylesheetImports(code);
221
+ let ast;
222
+ try {
223
+ ast = parseAst(code, { lang: parserLanguageForScript(id) });
224
+ } catch {
225
+ return null;
226
+ }
227
+ let output = null;
228
+ for (const statement of ast.body) {
229
+ if (statement.type !== "ImportDeclaration" || statement.importKind === "type") continue;
230
+ if (statement.specifiers && statement.specifiers.length > 0) continue;
231
+ if (statement.attributes && statement.attributes.length > 0) continue;
232
+ const source = statement.source;
233
+ const specifier = source?.value;
234
+ if (typeof specifier !== "string" || !isStylesheetSpecifier(specifier)) continue;
235
+ const range = source;
236
+ if (typeof range.start !== "number" || typeof range.end !== "number") continue;
237
+ output ??= new MagicString(code);
238
+ output.overwrite(range.start, range.end, JSON.stringify(specifier + GLOBAL_NOT_FOUND_CSS_QUERY));
239
+ }
240
+ return output ? toMagicStringTransformResult(output) : null;
241
+ }
242
+ function isScriptModuleId(id) {
243
+ return SCRIPT_IMPORT_RE.test(stripViteModuleQuery(id).toLowerCase());
244
+ }
245
+ function skipCommonjsForLocalCjs(id) {
246
+ const cleanId = normalizePathSeparators(stripViteModuleQuery(id));
247
+ return /\.c[jt]s$/i.test(cleanId) && !cleanId.includes("node_modules") ? false : void 0;
248
+ }
249
+ function hasOnlyTypeSpecifiers(statement) {
250
+ return statement.specifiers !== void 0 && statement.specifiers.length > 0 && statement.specifiers.every((specifier) => specifier.importKind === "type" || specifier.exportKind === "type");
251
+ }
252
+ function resolvedStylesheetToDevManifestAsset(root, resolvedId) {
253
+ const cleanId = stripViteModuleQuery(resolvedId);
254
+ if (!path.isAbsolute(cleanId)) return null;
255
+ const rootForRelative = tryRealpathSync(root) ?? root;
256
+ const fileForRelative = tryRealpathSync(cleanId) ?? cleanId;
257
+ const relativePath = path.relative(rootForRelative, fileForRelative);
258
+ if (relativePath !== "" && !relativePath.startsWith("..") && !path.isAbsolute(relativePath)) return normalizePathSeparators(relativePath);
259
+ return `@fs/${normalizePathSeparators(cleanId).replace(/^\/+/, "")}`;
260
+ }
261
+ async function collectDevPagesAppStylesheetAssets(root, appFilePath, resolve) {
262
+ const stylesheetAssets = [];
263
+ const seenAssets = /* @__PURE__ */ new Set();
264
+ const seenModules = /* @__PURE__ */ new Set();
265
+ async function visitModule(modulePath) {
266
+ const cleanModulePath = stripViteModuleQuery(modulePath);
267
+ if (!path.isAbsolute(cleanModulePath) || !fs.existsSync(cleanModulePath)) return;
268
+ if (seenModules.has(cleanModulePath)) return;
269
+ seenModules.add(cleanModulePath);
270
+ let ast;
271
+ try {
272
+ ast = parseAst(fs.readFileSync(cleanModulePath, "utf-8"), { lang: parserLanguageForScript(cleanModulePath) });
273
+ } catch {
274
+ return;
275
+ }
276
+ for (const statement of ast.body) {
277
+ if (statement.type !== "ImportDeclaration" && statement.type !== "ExportNamedDeclaration" && statement.type !== "ExportAllDeclaration") continue;
278
+ if (statement.importKind === "type") continue;
279
+ if (statement.exportKind === "type") continue;
280
+ if (hasOnlyTypeSpecifiers(statement)) continue;
281
+ if (statement.attributes && statement.attributes.length > 0) continue;
282
+ const specifier = statement.source?.value;
283
+ if (typeof specifier !== "string") continue;
284
+ const resolved = await resolve(specifier, cleanModulePath, { skipSelf: true });
285
+ if (!resolved?.id) continue;
286
+ if (isStylesheetSpecifier(specifier)) {
287
+ const asset = resolvedStylesheetToDevManifestAsset(root, resolved.id);
288
+ if (!asset || seenAssets.has(asset)) continue;
289
+ seenAssets.add(asset);
290
+ stylesheetAssets.push(asset);
291
+ continue;
292
+ }
293
+ if (specifier.includes("?") || specifier.includes("#")) continue;
294
+ if (isScriptModuleId(resolved.id)) await visitModule(resolved.id);
295
+ }
296
+ }
297
+ await visitModule(appFilePath);
298
+ return stylesheetAssets;
299
+ }
175
300
  const TSCONFIG_FILES = ["tsconfig.json", "jsconfig.json"];
176
301
  function resolveTsconfigPathCandidate(candidate) {
177
302
  const candidates = candidate.endsWith(".json") ? [candidate] : [
@@ -306,19 +431,115 @@ function getVinextVersion() {
306
431
  }
307
432
  return _vinextVersionCache;
308
433
  }
434
+ function mergeStringArrayValues(value, additions) {
435
+ return [...new Set([...value === void 0 ? [] : Array.isArray(value) ? value : [value], ...additions])];
436
+ }
437
+ function stripAnsi(value) {
438
+ return value.replace(ANSI_ESCAPE_RE, "");
439
+ }
440
+ function suppressOptionalOptimizeDepsWarnings(logger) {
441
+ const marker = logger;
442
+ if (marker[VINEXT_FILTERED_OPTIMIZE_DEPS_WARN]) return;
443
+ const warn = logger.warn.bind(logger);
444
+ logger.warn = (msg, options) => {
445
+ if (OPTIONAL_OPTIMIZE_DEPS_WARNING_RE.test(stripAnsi(msg))) return;
446
+ warn(msg, options);
447
+ };
448
+ marker[VINEXT_FILTERED_OPTIMIZE_DEPS_WARN] = true;
449
+ }
309
450
  const _tsconfigAliasCache = /* @__PURE__ */ new Map();
451
+ /**
452
+ * Order materialized tsconfig path aliases by descending prefix length.
453
+ *
454
+ * TypeScript (and Next.js) match `paths` patterns by longest matched prefix,
455
+ * regardless of declaration order, while Vite's alias plugin picks the first
456
+ * matching entry. Overlapping patterns like `@/*` + `@/public/*` must
457
+ * therefore be materialized longest-first or the general pattern shadows the
458
+ * specific one (`@/public/foo.svg` would resolve into `src/public/`).
459
+ */
460
+ function sortTsconfigAliasesBySpecificity(aliases) {
461
+ return Object.fromEntries(Object.entries(aliases).sort((a, b) => b[0].length - a[0].length));
462
+ }
310
463
  function resolveTsconfigAliases(projectRoot) {
311
464
  if (_tsconfigAliasCache.has(projectRoot)) return _tsconfigAliasCache.get(projectRoot);
312
465
  let aliases = {};
313
466
  for (const name of TSCONFIG_FILES) {
314
467
  const candidate = path.join(projectRoot, name);
315
468
  if (!fs.existsSync(candidate)) continue;
316
- aliases = loadTsconfigPathAliases(candidate, projectRoot);
469
+ aliases = sortTsconfigAliasesBySpecificity(loadTsconfigPathAliases(candidate, projectRoot));
317
470
  break;
318
471
  }
319
472
  _tsconfigAliasCache.set(projectRoot, aliases);
320
473
  return aliases;
321
474
  }
475
+ /**
476
+ * Stylesheet importer contexts as seen by Vite's internal CSS resolvers.
477
+ *
478
+ * Vite resolves CSS `@import`/`composes`/`url()` specifiers through a
479
+ * dedicated resolver container that only runs the alias plugin plus Vite's
480
+ * own resolver — user plugins never participate. The importer is either the
481
+ * stylesheet's own path (sass, CSS modules `composes`, url() rewriting) or a
482
+ * synthetic `<basedir>/*` (postcss-import, less).
483
+ */
484
+ const STYLESHEET_IMPORTER_RE = /\.(?:css|scss|sass|less|styl|stylus|pcss|sss)$/i;
485
+ function isStylesheetImporter(importer) {
486
+ if (!importer) return false;
487
+ if (importer.endsWith("/*") || importer.endsWith("\\*")) return true;
488
+ return STYLESHEET_IMPORTER_RE.test(stripViteModuleQuery(importer));
489
+ }
490
+ /**
491
+ * Alias resolver for tsconfig-derived path aliases that keeps them out of
492
+ * stylesheet resolution.
493
+ *
494
+ * TypeScript `paths` never apply to CSS in Next.js — `@import` specifiers in
495
+ * stylesheets use standard bundler resolution, including package.json
496
+ * `exports` maps. A blind prefix-replacement alias breaks that: with
497
+ * `"@scope/ui/*": ["../../packages/ui/src/*"]` in tsconfig, an
498
+ * `@import "@scope/ui/globals.css"` whose real target is `exports`-mapped
499
+ * gets rewritten to a nonexistent source path and fails with ENOENT.
500
+ *
501
+ * Returning `null` for stylesheet importers makes the alias plugin fall
502
+ * through, so Vite's own resolver handles the original specifier. JS/TS
503
+ * importers keep the default alias behavior (Next.js applies `paths` there,
504
+ * including for `import "@/styles/globals.css"` from a layout), and Vite's
505
+ * glob/dynamic-import transforms — which require blind prefix replacement
506
+ * because their patterns never exist on disk — keep working.
507
+ */
508
+ const tsconfigAliasCustomResolver = async function(updatedId, importer, options) {
509
+ if (isStylesheetImporter(importer)) return null;
510
+ return await this.resolve(updatedId, importer, {
511
+ ...options,
512
+ skipSelf: true
513
+ }) ?? { id: updatedId };
514
+ };
515
+ /**
516
+ * Convert the merged alias map into Vite alias entries, attaching the
517
+ * stylesheet-scoping resolver to entries that came from tsconfig `paths`.
518
+ * Array order preserves the map's first-match ordering.
519
+ */
520
+ function buildResolveAliasEntries(aliasMap, tsconfigPathAliases) {
521
+ return Object.entries(aliasMap).map(([find, replacement]) => tsconfigPathAliases[find] === replacement ? {
522
+ find,
523
+ replacement,
524
+ customResolver: tsconfigAliasCustomResolver
525
+ } : {
526
+ find,
527
+ replacement
528
+ });
529
+ }
530
+ const ALIAS_CUSTOM_RESOLVER_DEPRECATION_RE = /`resolve\.alias` contains an alias with `customResolver` option/;
531
+ const VINEXT_FILTERED_ALIAS_DEPRECATION_WARN = Symbol.for("vinext.filteredAliasDeprecationWarn");
532
+ function suppressAliasCustomResolverDeprecationWarning(logger) {
533
+ const marker = logger;
534
+ if (marker[VINEXT_FILTERED_ALIAS_DEPRECATION_WARN]) return logger;
535
+ const warn = logger.warn.bind(logger);
536
+ logger.warn = (msg, warnOptions) => {
537
+ if (ALIAS_CUSTOM_RESOLVER_DEPRECATION_RE.test(stripAnsi(msg))) return;
538
+ warn(msg, warnOptions);
539
+ };
540
+ marker[VINEXT_FILTERED_ALIAS_DEPRECATION_WARN] = true;
541
+ return logger;
542
+ }
322
543
  const VIRTUAL_WORKER_ENTRY = "virtual:vinext-worker-entry";
323
544
  const RESOLVED_WORKER_ENTRY = "\0virtual:vinext-worker-entry";
324
545
  const VIRTUAL_SERVER_ENTRY = "virtual:vinext-server-entry";
@@ -455,22 +676,19 @@ const _reactServerShims = new Map([
455
676
  ["next/error", "error"],
456
677
  ["next/error.js", "error"]
457
678
  ]);
458
- const clientManualChunks = createClientManualChunks(_shimsDir);
459
- const clientCodeSplittingConfig = createClientCodeSplittingConfig(clientManualChunks);
460
- const appClientManualChunks = createClientManualChunks(_shimsDir, true);
461
- const appClientCodeSplittingConfig = createClientCodeSplittingConfig(appClientManualChunks);
462
- function getClientOutputConfigForVite(viteMajorVersion, assetsDir, preserveAppRouteBoundaries = false) {
463
- const manualChunks = preserveAppRouteBoundaries ? appClientManualChunks : clientManualChunks;
679
+ const clientCodeSplittingConfig = createClientCodeSplittingConfig(createClientManualChunks(_shimsDir));
680
+ const appClientCodeSplittingConfig = createClientCodeSplittingConfig(createClientManualChunks(_shimsDir, true));
681
+ function getClientOutputConfig(assetsDir, preserveAppRouteBoundaries = false) {
464
682
  const codeSplitting = preserveAppRouteBoundaries ? appClientCodeSplittingConfig : clientCodeSplittingConfig;
465
- return viteMajorVersion >= 8 ? {
683
+ return {
466
684
  ...createClientFileNameConfig(assetsDir),
467
685
  assetFileNames: createClientAssetFileNames(assetsDir),
468
686
  codeSplitting
469
- } : createClientOutputConfig(manualChunks, assetsDir);
687
+ };
470
688
  }
471
689
  function vinext(options = {}) {
690
+ assertSupportedViteVersion();
472
691
  const prerenderConfig = normalizeVinextPrerenderConfig(options.prerender);
473
- const viteMajorVersion = getViteMajorVersion();
474
692
  let root;
475
693
  let pagesDir;
476
694
  let canonicalPagesDir;
@@ -483,10 +701,13 @@ function vinext(options = {}) {
483
701
  let instrumentationPath = null;
484
702
  let instrumentationClientPath = null;
485
703
  let clientInjectModule = null;
704
+ let globalNotFoundCssIsolationPath = null;
486
705
  let clientAssetsInlineLimit = 0;
487
706
  let hasCloudflarePlugin = false;
488
707
  let warnedInlineNextConfigOverride = false;
489
708
  let hasNitroPlugin = false;
709
+ let isServeCommand = false;
710
+ let pagesOptimizeEntries = [];
490
711
  const pagesClientAssetsOutputDirs = /* @__PURE__ */ new Set();
491
712
  let pagesClientAssetsModule = null;
492
713
  let rscCompatibilityId;
@@ -625,11 +846,27 @@ function vinext(options = {}) {
625
846
  return mdxDelegatePromise;
626
847
  }
627
848
  const plugins = [
628
- ...viteMajorVersion >= 8 ? [] : [loadVite7TsconfigPathsPlugin(earlyBaseDir)],
849
+ createStyledJsxPlugin(earlyBaseDir),
629
850
  reactPluginPromise,
630
851
  createIgnoreDynamicRequestsPlugin(() => nextConfig?.turbopackTranspilePackages ?? []),
631
- commonjs(),
632
- ...viteMajorVersion >= 8 ? [{
852
+ commonjs({ filter: skipCommonjsForLocalCjs }),
853
+ {
854
+ name: "vinext:global-not-found-css-isolation",
855
+ apply: "build",
856
+ enforce: "pre",
857
+ transform: {
858
+ filter: {
859
+ id: /(?:^|[/\\])global-not-found(?:\.[^./?\\]+)+(?:\?.*)?$/,
860
+ code: /\.(?:css|scss|sass)['"]/
861
+ },
862
+ handler(code, id) {
863
+ const cleanId = normalizePathSeparators(stripViteModuleQuery(id));
864
+ if (!globalNotFoundCssIsolationPath || canonicalize(cleanId) !== canonicalize(globalNotFoundCssIsolationPath)) return null;
865
+ return isolateGlobalNotFoundStylesheetImports(code, cleanId);
866
+ }
867
+ }
868
+ },
869
+ {
633
870
  name: "vinext:jsx-in-js",
634
871
  enforce: "pre",
635
872
  transform: {
@@ -652,7 +889,7 @@ function vinext(options = {}) {
652
889
  };
653
890
  }
654
891
  }
655
- }] : [],
892
+ },
656
893
  createMiddlewareServerOnlyPlugin({
657
894
  getMiddlewarePath: () => middlewarePath,
658
895
  getCanonicalMiddlewarePath: () => middlewarePath ? tryRealpathSync(middlewarePath) ?? middlewarePath : null,
@@ -668,12 +905,20 @@ function vinext(options = {}) {
668
905
  name: "vinext:config",
669
906
  enforce: "pre",
670
907
  [VINEXT_PRERENDER_CONFIG_PLUGIN_PROPERTY]: prerenderConfig,
908
+ [VINEXT_ROUTE_ROOT_CONFIG_PLUGIN_PROPERTY]: {
909
+ appDir: options.appDir,
910
+ disableAppRouter: options.disableAppRouter,
911
+ rscOutDir: options.rscOutDir,
912
+ ssrOutDir: options.ssrOutDir
913
+ },
914
+ [VINEXT_CACHE_CONFIG_PLUGIN_PROPERTY]: options.cache ?? null,
671
915
  async config(config, env) {
916
+ isServeCommand = env.command === "serve";
672
917
  root = normalizePathSeparators(config.root ?? process.cwd());
673
- const userResolve = config.resolve;
674
- const shouldEnableNativeTsconfigPaths = viteMajorVersion >= 8 && userResolve?.tsconfigPaths === void 0;
918
+ const shouldEnableNativeTsconfigPaths = config.resolve?.tsconfigPaths === void 0;
675
919
  const tsconfigPathAliases = resolveTsconfigAliases(root);
676
920
  const swcHelpersAlias = resolveSwcHelpersAlias(root);
921
+ if (Object.keys(tsconfigPathAliases).length > 0) config.customLogger = suppressAliasCustomResolverDeprecationWarning(config.customLogger ?? createLogger(config.logLevel, { allowClearScreen: config.clearScreen }));
677
922
  const mode = env?.mode ?? "development";
678
923
  const dotenvVars = loadEnv(mode, config.envDir ?? root, "");
679
924
  for (const [key, value] of Object.entries(dotenvVars)) if (process.env[key] === void 0) process.env[key] = value;
@@ -721,6 +966,7 @@ function vinext(options = {}) {
721
966
  rscCompatibilityId = sharedRscCompatibilityId && sharedRscCompatibilityId.length > 0 ? sharedRscCompatibilityId : createRscCompatibilityId(nextConfig);
722
967
  }
723
968
  fileMatcher = createValidFileMatcher(nextConfig.pageExtensions);
969
+ globalNotFoundCssIsolationPath = env?.command === "build" && nextConfig.globalNotFound ? findFileWithExts(appDir, "global-not-found", fileMatcher) : null;
724
970
  instrumentationPath = findInstrumentationFile(root, fileMatcher);
725
971
  instrumentationClientPath = findInstrumentationClientFile(root, fileMatcher);
726
972
  const middlewareConventionDir = canonicalize(baseDir) === canonicalize(path.posix.join(root, "src")) ? path.posix.join(root, "src") : root;
@@ -885,7 +1131,7 @@ function vinext(options = {}) {
885
1131
  ],
886
1132
  assetsDir: clientAssetsDir,
887
1133
  ...!isSSR && !hasClientBuildEnvironment ? { assetsInlineLimit: clientAssetsInlineLimit } : {},
888
- ...withBuildBundlerOptions(viteMajorVersion, {
1134
+ ...withBuildBundlerOptions({
889
1135
  onwarn: (() => {
890
1136
  const userOnwarn = getBuildBundlerOptions(config.build)?.onwarn;
891
1137
  return (warning, defaultHandler) => {
@@ -896,8 +1142,8 @@ function vinext(options = {}) {
896
1142
  else defaultHandler(warning);
897
1143
  };
898
1144
  })(),
899
- ...!isSSR && !isMultiEnv ? { treeshake: getClientTreeshakeConfigForVite(viteMajorVersion) } : {},
900
- ...!isSSR && !isMultiEnv ? { output: getClientOutputConfigForVite(viteMajorVersion, clientAssetsDir) } : {}
1145
+ ...!isSSR && !isMultiEnv ? { treeshake: getClientTreeshakeConfig() } : {},
1146
+ ...!isSSR && !isMultiEnv ? { output: getClientOutputConfig(clientAssetsDir) } : {}
901
1147
  })
902
1148
  },
903
1149
  server: {
@@ -919,13 +1165,13 @@ function vinext(options = {}) {
919
1165
  noExternal: true
920
1166
  } },
921
1167
  resolve: {
922
- alias: {
1168
+ alias: buildResolveAliasEntries({
923
1169
  ...swcHelpersAlias ? { "@swc/helpers/_": swcHelpersAlias } : {},
924
1170
  ...tsconfigPathAliases,
925
1171
  ...nextConfig.aliases,
926
1172
  ...nextShimMap,
927
1173
  "vinext/server/pages-client-assets": _pagesClientAssetsPath
928
- },
1174
+ }, tsconfigPathAliases),
929
1175
  dedupe: [
930
1176
  "react",
931
1177
  "react-dom",
@@ -934,7 +1180,10 @@ function vinext(options = {}) {
934
1180
  ],
935
1181
  ...shouldEnableNativeTsconfigPaths ? { tsconfigPaths: true } : {}
936
1182
  },
937
- ...viteMajorVersion >= 8 ? { oxc: { jsx: { runtime: "automatic" } } } : { esbuild: { jsx: "automatic" } },
1183
+ oxc: {
1184
+ jsx: { runtime: "automatic" },
1185
+ typescript: { onlyRemoveTypeImports: false }
1186
+ },
938
1187
  define: defines,
939
1188
  ...nextConfig.basePath ? { base: nextConfig.basePath + "/" } : {},
940
1189
  ...nextConfig.assetPrefix || nextConfig.deploymentId ? { experimental: { renderBuiltUrl: (filename, context) => renderVinextBuiltUrl(filename, nextConfig.assetPrefix, nextConfig.deploymentId, context.hostType) } } : {},
@@ -949,9 +1198,19 @@ function vinext(options = {}) {
949
1198
  ...postcssOverride ? { postcss: postcssOverride } : {},
950
1199
  preprocessorOptions: (() => {
951
1200
  const tildeImporter = createSassTildeImporter(root);
1201
+ const cssUrlAssetImporter = env.command === "build" ? createSassCssUrlAssetImporter() : null;
1202
+ const userAdditionalData = sassPreprocessorOptions?.additionalData;
952
1203
  const baseOpts = {
953
1204
  ...sassPreprocessorOptions,
954
- importers: [tildeImporter, ...sassPreprocessorOptions?.importers ?? []]
1205
+ ...cssUrlAssetImporter ? { additionalData: async (source, filename) => {
1206
+ const withUserData = typeof userAdditionalData === "function" ? await userAdditionalData(source, filename) : typeof userAdditionalData === "string" ? `${userAdditionalData}${source}` : source;
1207
+ return cssUrlAssetImporter.rewriteImports(withUserData, filename);
1208
+ } } : {},
1209
+ importers: [
1210
+ tildeImporter,
1211
+ ...cssUrlAssetImporter ? [cssUrlAssetImporter] : [],
1212
+ ...sassPreprocessorOptions?.importers ?? []
1213
+ ]
955
1214
  };
956
1215
  return {
957
1216
  scss: baseOpts,
@@ -972,7 +1231,7 @@ function vinext(options = {}) {
972
1231
  if (shimBase !== void 0) return resolveShimModulePath(shimsDir, shimBase);
973
1232
  }
974
1233
  };
975
- const depOptimizeNodeEnvOptions = getDepOptimizeNodeEnvOptions(viteMajorVersion, nodeEnvDefine);
1234
+ const depOptimizeNodeEnvOptions = getDepOptimizeNodeEnvOptions(nodeEnvDefine);
976
1235
  viteConfig.optimizeDeps = {
977
1236
  exclude: mergeOptimizeDepsExclude(incomingExclude, VINEXT_OPTIMIZE_DEPS_EXCLUDE, ["@tailwindcss/oxide"]),
978
1237
  ...incomingInclude.length > 0 ? { include: incomingInclude } : {},
@@ -982,7 +1241,7 @@ function vinext(options = {}) {
982
1241
  plugins: [depOptimizeAliasPlugin]
983
1242
  }
984
1243
  };
985
- const pagesOptimizeEntries = !hasAppDir ? [...hasPagesDir ? [toRelativeFileEntry(root, pagesDir) + "/**/*.{tsx,ts,jsx,js}"] : [], ...[instrumentationPath, instrumentationClientPath].flatMap((entry) => entry ? [toRelativeFileEntry(root, entry)] : [])] : [];
1244
+ pagesOptimizeEntries = !hasAppDir ? [...hasPagesDir ? [toRelativeFileEntry(root, pagesDir) + "/**/*.{tsx,ts,jsx,js}"] : [], ...[instrumentationPath, instrumentationClientPath].flatMap((entry) => entry ? [toRelativeFileEntry(root, entry)] : [])] : [];
986
1245
  if (hasAppDir) {
987
1246
  const appEntries = [`${path.relative(root, appDir)}/**/*.{tsx,ts,jsx,js}`];
988
1247
  const explicitInstrumentationEntries = [instrumentationPath, instrumentationClientPath].flatMap((entry) => entry ? [toRelativeFileEntry(root, entry)] : []);
@@ -1009,9 +1268,9 @@ function vinext(options = {}) {
1009
1268
  },
1010
1269
  build: {
1011
1270
  outDir: options.rscOutDir ?? "dist/server",
1012
- ...withBuildBundlerOptions(viteMajorVersion, {
1271
+ ...withBuildBundlerOptions({
1013
1272
  input: { index: VIRTUAL_RSC_ENTRY },
1014
- output: createRscFrameworkChunkOutputConfig(viteMajorVersion)
1273
+ output: createRscFrameworkChunkOutputConfig()
1015
1274
  })
1016
1275
  }
1017
1276
  },
@@ -1031,7 +1290,7 @@ function vinext(options = {}) {
1031
1290
  },
1032
1291
  build: {
1033
1292
  outDir: options.ssrOutDir ?? "dist/server/ssr",
1034
- ...withBuildBundlerOptions(viteMajorVersion, { input: { index: VIRTUAL_APP_SSR_ENTRY } })
1293
+ ...withBuildBundlerOptions({ input: { index: VIRTUAL_APP_SSR_ENTRY } })
1035
1294
  }
1036
1295
  },
1037
1296
  client: {
@@ -1046,47 +1305,54 @@ function vinext(options = {}) {
1046
1305
  "react-dom/client",
1047
1306
  "react/jsx-runtime",
1048
1307
  "react/jsx-dev-runtime"
1049
- ])]
1308
+ ])],
1309
+ ...depOptimizeNodeEnvOptions
1050
1310
  },
1051
1311
  build: {
1052
1312
  manifest: true,
1053
1313
  ...hasPagesDir ? { ssrManifest: true } : {},
1054
1314
  assetsInlineLimit: clientAssetsInlineLimit,
1055
- ...withBuildBundlerOptions(viteMajorVersion, {
1315
+ ...withBuildBundlerOptions({
1056
1316
  input: appClientInput,
1057
- output: getClientOutputConfigForVite(viteMajorVersion, clientAssetsDir, true),
1058
- treeshake: getClientTreeshakeConfigForVite(viteMajorVersion)
1317
+ output: getClientOutputConfig(clientAssetsDir, true),
1318
+ treeshake: getClientTreeshakeConfig()
1059
1319
  })
1060
1320
  }
1061
1321
  }
1062
1322
  };
1063
1323
  } else if (hasCloudflarePlugin) viteConfig.environments = { client: {
1064
1324
  consumer: "client",
1065
- optimizeDeps: pagesOptimizeEntries.length > 0 ? { entries: pagesOptimizeEntries } : void 0,
1325
+ optimizeDeps: {
1326
+ ...pagesOptimizeEntries.length > 0 ? { entries: pagesOptimizeEntries } : {},
1327
+ ...depOptimizeNodeEnvOptions
1328
+ },
1066
1329
  build: {
1067
1330
  manifest: true,
1068
1331
  ssrManifest: true,
1069
1332
  assetsInlineLimit: clientAssetsInlineLimit,
1070
- ...withBuildBundlerOptions(viteMajorVersion, {
1333
+ ...withBuildBundlerOptions({
1071
1334
  input: { index: VIRTUAL_CLIENT_ENTRY },
1072
- output: getClientOutputConfigForVite(viteMajorVersion, clientAssetsDir),
1073
- treeshake: getClientTreeshakeConfigForVite(viteMajorVersion)
1335
+ output: getClientOutputConfig(clientAssetsDir),
1336
+ treeshake: getClientTreeshakeConfig()
1074
1337
  })
1075
1338
  }
1076
1339
  } };
1077
1340
  else if (shouldInjectPlainPagesEnvironments) viteConfig.environments = {
1078
1341
  client: {
1079
1342
  consumer: "client",
1080
- optimizeDeps: pagesOptimizeEntries.length > 0 ? { entries: pagesOptimizeEntries } : void 0,
1343
+ optimizeDeps: {
1344
+ ...pagesOptimizeEntries.length > 0 ? { entries: pagesOptimizeEntries } : {},
1345
+ ...depOptimizeNodeEnvOptions
1346
+ },
1081
1347
  build: {
1082
1348
  outDir: "dist/client",
1083
1349
  manifest: true,
1084
1350
  ssrManifest: true,
1085
1351
  assetsInlineLimit: clientAssetsInlineLimit,
1086
- ...withBuildBundlerOptions(viteMajorVersion, {
1352
+ ...withBuildBundlerOptions({
1087
1353
  input: { index: VIRTUAL_CLIENT_ENTRY },
1088
- output: getClientOutputConfigForVite(viteMajorVersion, clientAssetsDir),
1089
- treeshake: getClientTreeshakeConfigForVite(viteMajorVersion)
1354
+ output: getClientOutputConfig(clientAssetsDir),
1355
+ treeshake: getClientTreeshakeConfig()
1090
1356
  })
1091
1357
  }
1092
1358
  },
@@ -1107,7 +1373,7 @@ function vinext(options = {}) {
1107
1373
  },
1108
1374
  build: {
1109
1375
  outDir: "dist/server",
1110
- ...withBuildBundlerOptions(viteMajorVersion, {
1376
+ ...withBuildBundlerOptions({
1111
1377
  input: { index: VIRTUAL_SERVER_ENTRY },
1112
1378
  output: { entryFileNames: "entry.js" }
1113
1379
  })
@@ -1121,6 +1387,12 @@ function vinext(options = {}) {
1121
1387
  return viteConfig;
1122
1388
  },
1123
1389
  configEnvironment(name, config) {
1390
+ if (isServeCommand && hasCloudflarePlugin && hasPagesDir && !hasAppDir && name !== "client") {
1391
+ config.optimizeDeps ??= {};
1392
+ config.optimizeDeps.entries = mergeStringArrayValues(config.optimizeDeps.entries, pagesOptimizeEntries);
1393
+ config.optimizeDeps.include = mergeStringArrayValues(config.optimizeDeps.include, PAGES_CLOUDFLARE_WORKER_OPTIMIZE_DEPS_INCLUDE);
1394
+ config.optimizeDeps.exclude = mergeOptimizeDepsExclude(config.optimizeDeps.exclude ?? [], VINEXT_OPTIMIZE_DEPS_EXCLUDE, PAGES_CLOUDFLARE_WORKER_OPTIMIZE_DEPS_EXCLUDE);
1395
+ }
1124
1396
  const configuredExtensions = name === "client" ? nextConfig.resolveExtensions : nextConfig.serverResolveExtensions;
1125
1397
  const extensions = configuredExtensions === null ? buildViteResolveExtensions(nextConfig.pageExtensions, config.resolve?.extensions) : normalizeViteResolveExtensions(configuredExtensions);
1126
1398
  config.resolve ??= {};
@@ -1130,6 +1402,7 @@ function vinext(options = {}) {
1130
1402
  async configResolved(config) {
1131
1403
  const cacheDirPrefix = getCacheDirPrefix(config.cacheDir);
1132
1404
  typeofWindowIdFilter.exclude = new RegExp(`^${escapeRegExp(cacheDirPrefix)}`);
1405
+ if (isServeCommand && hasCloudflarePlugin && hasPagesDir && !hasAppDir) suppressOptionalOptimizeDepsWarnings(config.logger);
1133
1406
  sassComposesLoader.setResolvedConfig(config);
1134
1407
  if (config.command === "build" && hasAppDir && hasPagesDir) {
1135
1408
  const [appRoutes, pageRoutes, apiRoutes] = await Promise.all([
@@ -1203,78 +1476,94 @@ function vinext(options = {}) {
1203
1476
  if (reactServerShim !== void 0) return resolveShimModulePath(_shimsDir, this.environment?.name === "rsc" ? `${reactServerShim}.react-server` : reactServerShim);
1204
1477
  }
1205
1478
  },
1206
- async load(id) {
1207
- if (id === RESOLVED_WORKER_ENTRY) return `export { default } from ${JSON.stringify(hasAppDir ? "vinext/server/app-router-entry" : "vinext/server/pages-router-entry")};`;
1208
- if (id === RESOLVED_SERVER_ENTRY) return await generateServerEntry$1();
1209
- if (id === RESOLVED_CLIENT_ENTRY) return await generateClientEntry$1();
1210
- if (id === RESOLVED_PAGES_CLIENT_ASSETS) return "export default { clientEntry: '/@id/__x00__virtual:vinext-client-entry' };";
1211
- if (id === RESOLVED_RSC_ENTRY && hasAppDir) {
1212
- const routes = await appRouter(appDir, nextConfig?.pageExtensions, fileMatcher);
1213
- const metaRoutes = scanMetadataFiles(appDir);
1214
- const hasServerActions = await resolveHasServerActions(this.environment.config);
1215
- const globalErrorPath = findFileWithExts(appDir, "global-error", fileMatcher);
1216
- const globalNotFoundPath = nextConfig?.globalNotFound ? findFileWithExts(appDir, "global-not-found", fileMatcher) : null;
1217
- rscClassificationManifest = collectRouteClassificationManifest(routes);
1218
- return generateRscEntry(appDir, routes, middlewarePath, metaRoutes, globalErrorPath, nextConfig?.basePath, nextConfig?.trailingSlash, {
1219
- redirects: nextConfig?.redirects,
1220
- rewrites: nextConfig?.rewrites,
1221
- headers: nextConfig?.headers,
1222
- allowedOrigins: nextConfig?.serverActionsAllowedOrigins,
1223
- allowedDevOrigins: nextConfig?.allowedDevOrigins,
1224
- bodySizeLimit: nextConfig?.serverActionsBodySizeLimit,
1225
- bodySizeLimitLabel: nextConfig?.serverActionsBodySizeLimitLabel,
1226
- htmlLimitedBots: nextConfig?.htmlLimitedBots,
1227
- clientTraceMetadata: nextConfig?.clientTraceMetadata,
1228
- assetPrefix: nextConfig?.assetPrefix,
1229
- expireTime: nextConfig?.expireTime,
1230
- reactMaxHeadersLength: nextConfig?.reactMaxHeadersLength,
1231
- cacheMaxMemorySize: nextConfig?.cacheMaxMemorySize,
1232
- inlineCss: nextConfig?.inlineCss,
1233
- globalNotFound: nextConfig?.globalNotFound,
1234
- cacheComponents: nextConfig?.cacheComponents,
1235
- hasServerActions,
1236
- i18n: nextConfig?.i18n,
1237
- imageConfig: {
1238
- deviceSizes: nextConfig?.images?.deviceSizes,
1239
- imageSizes: nextConfig?.images?.imageSizes,
1240
- qualities: nextConfig?.images?.qualities,
1241
- dangerouslyAllowSVG: nextConfig?.images?.dangerouslyAllowSVG,
1242
- dangerouslyAllowLocalIP: nextConfig?.images?.dangerouslyAllowLocalIP,
1243
- contentDispositionType: nextConfig?.images?.contentDispositionType,
1244
- contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy
1245
- },
1246
- hasPagesDir,
1247
- publicFiles: scanPublicFileRoutes(root),
1248
- globalNotFoundPath,
1249
- draftModeSecret
1250
- }, instrumentationPath);
1251
- }
1252
- if (id === RESOLVED_ROOT_PARAMS) return generateRootParamsModule((hasAppDir ? await appRouter(appDir, nextConfig?.pageExtensions, fileMatcher) : []).flatMap((route) => route.rootParamNames ?? []));
1253
- if (id === RESOLVED_CACHE_ADAPTERS) return generateCacheAdaptersModule(options.cache);
1254
- if (id === RESOLVED_IMAGE_ADAPTERS) return generateImageAdaptersModule(options.images);
1255
- if (id === RESOLVED_APP_SSR_ENTRY && hasAppDir) return generateSsrEntry(hasPagesDir);
1256
- if (id === RESOLVED_APP_BROWSER_ENTRY && hasAppDir) {
1257
- const graph = await appRouteGraph(appDir, nextConfig?.pageExtensions, fileMatcher);
1258
- const pagesPrefetchRoutes = hasPagesDir ? [...(await pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher)).map((route) => ({
1259
- canPrefetchLoadingShell: false,
1260
- isDynamic: route.isDynamic,
1261
- patternParts: [...route.patternParts]
1262
- })), ...(await apiRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher)).map((route) => ({
1263
- canPrefetchLoadingShell: false,
1264
- documentOnly: true,
1265
- isDynamic: route.isDynamic,
1266
- patternParts: [...route.patternParts]
1267
- }))] : [];
1268
- return generateBrowserEntry(graph.routes, graph.routeManifest, pagesPrefetchRoutes, nextConfig.rewrites);
1269
- }
1270
- if (id === RESOLVED_APP_CAPABILITIES && hasAppDir) {
1271
- const hasServerActions = await resolveHasServerActions(this.environment.config);
1272
- return `
1479
+ load: {
1480
+ filter: { id: /virtual:vinext-/ },
1481
+ async handler(id) {
1482
+ if (id === RESOLVED_WORKER_ENTRY) return `export { default } from ${JSON.stringify(hasAppDir ? "vinext/server/app-router-entry" : "vinext/server/pages-router-entry")};`;
1483
+ if (id === RESOLVED_SERVER_ENTRY) return await generateServerEntry$1();
1484
+ if (id === RESOLVED_CLIENT_ENTRY) return await generateClientEntry$1();
1485
+ if (id === RESOLVED_PAGES_CLIENT_ASSETS) {
1486
+ const metadata = { clientEntry: DEV_PAGES_CLIENT_ENTRY };
1487
+ const ssrManifest = {};
1488
+ const appFilePath = findFileWithExts(pagesDir, "_app", fileMatcher);
1489
+ const pagesRoutes = await pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);
1490
+ const moduleFilePaths = [...appFilePath ? [appFilePath] : [], ...pagesRoutes.map((route) => route.filePath)];
1491
+ for (const moduleFilePath of moduleFilePaths) {
1492
+ const stylesheetAssets = await collectDevPagesAppStylesheetAssets(root, moduleFilePath, this.resolve.bind(this));
1493
+ if (stylesheetAssets.length > 0) ssrManifest[normalizePathSeparators(moduleFilePath)] = stylesheetAssets;
1494
+ }
1495
+ if (Object.keys(ssrManifest).length > 0) metadata.ssrManifest = ssrManifest;
1496
+ return `export default ${JSON.stringify(metadata)};`;
1497
+ }
1498
+ if (id === RESOLVED_RSC_ENTRY && hasAppDir) {
1499
+ const routes = await appRouter(appDir, nextConfig?.pageExtensions, fileMatcher);
1500
+ const metaRoutes = scanMetadataFiles(appDir);
1501
+ const hasServerActions = await resolveHasServerActions(this.environment.config);
1502
+ const globalErrorPath = findFileWithExts(appDir, "global-error", fileMatcher);
1503
+ const globalNotFoundPath = nextConfig?.globalNotFound ? findFileWithExts(appDir, "global-not-found", fileMatcher) : null;
1504
+ rscClassificationManifest = collectRouteClassificationManifest(routes);
1505
+ return generateRscEntry(appDir, routes, middlewarePath, metaRoutes, globalErrorPath, nextConfig?.basePath, nextConfig?.trailingSlash, {
1506
+ redirects: nextConfig?.redirects,
1507
+ rewrites: nextConfig?.rewrites,
1508
+ headers: nextConfig?.headers,
1509
+ allowedOrigins: nextConfig?.serverActionsAllowedOrigins,
1510
+ allowedDevOrigins: nextConfig?.allowedDevOrigins,
1511
+ bodySizeLimit: nextConfig?.serverActionsBodySizeLimit,
1512
+ bodySizeLimitLabel: nextConfig?.serverActionsBodySizeLimitLabel,
1513
+ htmlLimitedBots: nextConfig?.htmlLimitedBots,
1514
+ clientTraceMetadata: nextConfig?.clientTraceMetadata,
1515
+ assetPrefix: nextConfig?.assetPrefix,
1516
+ expireTime: nextConfig?.expireTime,
1517
+ reactMaxHeadersLength: nextConfig?.reactMaxHeadersLength,
1518
+ cacheMaxMemorySize: nextConfig?.cacheMaxMemorySize,
1519
+ inlineCss: nextConfig?.inlineCss,
1520
+ globalNotFound: nextConfig?.globalNotFound,
1521
+ cacheComponents: nextConfig?.cacheComponents,
1522
+ prefetchInlining: nextConfig?.prefetchInlining,
1523
+ hasServerActions,
1524
+ i18n: nextConfig?.i18n,
1525
+ imageConfig: {
1526
+ deviceSizes: nextConfig?.images?.deviceSizes,
1527
+ imageSizes: nextConfig?.images?.imageSizes,
1528
+ qualities: nextConfig?.images?.qualities,
1529
+ dangerouslyAllowSVG: nextConfig?.images?.dangerouslyAllowSVG,
1530
+ dangerouslyAllowLocalIP: nextConfig?.images?.dangerouslyAllowLocalIP,
1531
+ contentDispositionType: nextConfig?.images?.contentDispositionType,
1532
+ contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy
1533
+ },
1534
+ hasPagesDir,
1535
+ publicFiles: scanPublicFileRoutes(root),
1536
+ globalNotFoundPath,
1537
+ draftModeSecret
1538
+ }, instrumentationPath);
1539
+ }
1540
+ if (id === RESOLVED_ROOT_PARAMS) return generateRootParamsModule((hasAppDir ? await appRouter(appDir, nextConfig?.pageExtensions, fileMatcher) : []).flatMap((route) => route.rootParamNames ?? []));
1541
+ if (id === RESOLVED_CACHE_ADAPTERS) return generateCacheAdaptersModule(options.cache);
1542
+ if (id === RESOLVED_IMAGE_ADAPTERS) return generateImageAdaptersModule(options.images);
1543
+ if (id === RESOLVED_APP_SSR_ENTRY && hasAppDir) return generateSsrEntry(hasPagesDir);
1544
+ if (id === RESOLVED_APP_BROWSER_ENTRY && hasAppDir) {
1545
+ const graph = await appRouteGraph(appDir, nextConfig?.pageExtensions, fileMatcher);
1546
+ const pagesPrefetchRoutes = hasPagesDir ? [...(await pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher)).map((route) => ({
1547
+ canPrefetchLoadingShell: false,
1548
+ isDynamic: route.isDynamic,
1549
+ patternParts: [...route.patternParts]
1550
+ })), ...(await apiRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher)).map((route) => ({
1551
+ canPrefetchLoadingShell: false,
1552
+ documentOnly: true,
1553
+ isDynamic: route.isDynamic,
1554
+ patternParts: [...route.patternParts]
1555
+ }))] : [];
1556
+ return generateBrowserEntry(graph.routes, graph.routeManifest, pagesPrefetchRoutes, nextConfig.rewrites);
1557
+ }
1558
+ if (id === RESOLVED_APP_CAPABILITIES && hasAppDir) {
1559
+ const hasServerActions = await resolveHasServerActions(this.environment.config);
1560
+ return `
1273
1561
  export const hasServerActions = ${JSON.stringify(hasServerActions)};
1274
1562
  export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.stringify(_appBrowserServerActionClientPath)})` : "null"};
1275
1563
  `;
1564
+ }
1565
+ if (id.startsWith("\0virtual:vinext-google-fonts?")) return generateGoogleFontsVirtualModule(id, _fontGoogleShimPath);
1276
1566
  }
1277
- if (id.startsWith("\0virtual:vinext-google-fonts?")) return generateGoogleFontsVirtualModule(id, _fontGoogleShimPath);
1278
1567
  },
1279
1568
  // @vitejs/plugin-rsc runs the RSC environment build in two phases:
1280
1569
  renderChunk: {
@@ -1360,7 +1649,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1360
1649
  if (!hasAppDir || name !== "rsc" && name !== "ssr") return null;
1361
1650
  const output = getBuildBundlerOptions(config.build)?.output;
1362
1651
  if (Array.isArray(output) || output?.assetFileNames !== void 0) return null;
1363
- return { build: { ...withBuildBundlerOptions(viteMajorVersion, { output: { assetFileNames: createClientAssetFileNames(resolveAssetsDir(nextConfig.assetPrefix ?? "")) } }) } };
1652
+ return { build: { ...withBuildBundlerOptions({ output: { assetFileNames: createClientAssetFileNames(resolveAssetsDir(nextConfig.assetPrefix ?? "")) } }) } };
1364
1653
  }
1365
1654
  },
1366
1655
  {
@@ -1410,13 +1699,19 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1410
1699
  {
1411
1700
  name: "vinext:instrumentation-client-inject",
1412
1701
  enforce: "pre",
1413
- resolveId(id) {
1414
- if (id !== VIRTUAL_INSTRUMENTATION_CLIENT) return null;
1415
- return clientInjectModule !== null ? RESOLVED_INSTRUMENTATION_CLIENT : null;
1702
+ resolveId: {
1703
+ filter: { id: /^private-next-instrumentation-client$/ },
1704
+ handler(id) {
1705
+ if (id !== VIRTUAL_INSTRUMENTATION_CLIENT) return null;
1706
+ return clientInjectModule !== null ? RESOLVED_INSTRUMENTATION_CLIENT : null;
1707
+ }
1416
1708
  },
1417
- load(id) {
1418
- if (id !== RESOLVED_INSTRUMENTATION_CLIENT) return null;
1419
- return clientInjectModule;
1709
+ load: {
1710
+ filter: { id: /private-next-instrumentation-client\.mjs$/ },
1711
+ handler(id) {
1712
+ if (id !== RESOLVED_INSTRUMENTATION_CLIENT) return null;
1713
+ return clientInjectModule;
1714
+ }
1420
1715
  }
1421
1716
  },
1422
1717
  ...options.experimental?.clientReferenceDedup ? [clientReferenceDedupPlugin()] : [],
@@ -1447,17 +1742,23 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1447
1742
  {
1448
1743
  name: "vinext:react-canary",
1449
1744
  enforce: "pre",
1450
- resolveId(id) {
1451
- if (id === "virtual:vinext-react-canary") return "\0virtual:vinext-react-canary";
1745
+ resolveId: {
1746
+ filter: { id: /^virtual:vinext-react-canary$/ },
1747
+ handler(id) {
1748
+ if (id === "virtual:vinext-react-canary") return "\0virtual:vinext-react-canary";
1749
+ }
1452
1750
  },
1453
- load(id) {
1454
- if (id === "\0virtual:vinext-react-canary") return [
1455
- `export * from "react";`,
1456
- `export { default } from "react";`,
1457
- `import * as _React from "react";`,
1458
- `export const ViewTransition = _React.ViewTransition || function ViewTransition({ children }) { return children; };`,
1459
- `export const addTransitionType = _React.addTransitionType || function addTransitionType() {};`
1460
- ].join("\n");
1751
+ load: {
1752
+ filter: { id: /^\u0000virtual:vinext-react-canary$/ },
1753
+ handler(id) {
1754
+ if (id === "\0virtual:vinext-react-canary") return [
1755
+ `export * from "react";`,
1756
+ `export { default } from "react";`,
1757
+ `import * as _React from "react";`,
1758
+ `export const ViewTransition = _React.ViewTransition || function ViewTransition({ children }) { return children; };`,
1759
+ `export const addTransitionType = _React.addTransitionType || function addTransitionType() {};`
1760
+ ].join("\n");
1761
+ }
1461
1762
  },
1462
1763
  transform: {
1463
1764
  filter: {
@@ -1478,7 +1779,32 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1478
1779
  {
1479
1780
  name: "vinext:pages-router",
1480
1781
  hotUpdate(options) {
1481
- if (!hasPagesDir || hasAppDir) return;
1782
+ if (!hasPagesDir) return;
1783
+ const isPagesAppFile = (filePath) => {
1784
+ const relativePath = normalizePathSeparators(path.relative(pagesDir, filePath));
1785
+ return !relativePath.includes("/") && relativePath.startsWith("_app.") && fileMatcher.extensionRegex.test(filePath);
1786
+ };
1787
+ const isPotentialPagesAssetGraphScript = (filePath) => {
1788
+ const cleanPath = stripViteModuleQuery(filePath);
1789
+ if (!path.isAbsolute(cleanPath)) return false;
1790
+ if (!isScriptModuleId(cleanPath) || cleanPath.endsWith(".d.ts")) return false;
1791
+ const relativeRootPath = normalizePathSeparators(path.relative(root, cleanPath));
1792
+ if (relativeRootPath.startsWith("..") || path.isAbsolute(relativeRootPath)) return false;
1793
+ if (relativeRootPath.includes("/node_modules/") || relativeRootPath.startsWith("node_modules/")) return false;
1794
+ const relativeAppPath = normalizePathSeparators(path.relative(appDir, cleanPath));
1795
+ return relativeAppPath.startsWith("..") || path.isAbsolute(relativeAppPath);
1796
+ };
1797
+ const pagesAppChanged = isPagesAppFile(options.file);
1798
+ const pagesAssetGraphScriptChanged = isPotentialPagesAssetGraphScript(options.file);
1799
+ if (pagesAppChanged || STYLESHEET_FILE_RE.test(options.file) || pagesAssetGraphScriptChanged) for (const env of Object.values(options.server.environments)) {
1800
+ const mod = env.moduleGraph.getModuleById(RESOLVED_PAGES_CLIENT_ASSETS);
1801
+ if (mod) env.moduleGraph.invalidateModule(mod);
1802
+ }
1803
+ if (pagesAppChanged || !hasAppDir && pagesAssetGraphScriptChanged) {
1804
+ options.server.ws.send({ type: "full-reload" });
1805
+ return [];
1806
+ }
1807
+ if (hasAppDir) return;
1482
1808
  if (options.file.startsWith(pagesDir) && fileMatcher.extensionRegex.test(options.file)) {
1483
1809
  options.server.environments.client.hot.send({ type: "full-reload" });
1484
1810
  return [];
@@ -1531,6 +1857,14 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1531
1857
  }
1532
1858
  pagesRunner?.clearCache();
1533
1859
  }
1860
+ function invalidatePagesClientAssetsModule(reloadDocument = false) {
1861
+ for (const env of Object.values(server.environments)) {
1862
+ const mod = env.moduleGraph.getModuleById(RESOLVED_PAGES_CLIENT_ASSETS);
1863
+ if (mod) env.moduleGraph.invalidateModule(mod);
1864
+ }
1865
+ pagesRunner?.clearCache();
1866
+ if (reloadDocument) server.ws.send({ type: "full-reload" });
1867
+ }
1534
1868
  function invalidateAppRoutingModules() {
1535
1869
  invalidateAppRouteCache();
1536
1870
  invalidateMetadataFileCache();
@@ -1578,6 +1912,20 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1578
1912
  }
1579
1913
  let appRouteTypeGeneration = null;
1580
1914
  let appRouteTypeGenerationPending = false;
1915
+ function isPagesAppFile(filePath) {
1916
+ const relativePath = normalizePathSeparators(path.relative(pagesDir, filePath));
1917
+ return !relativePath.includes("/") && relativePath.startsWith("_app.") && fileMatcher.extensionRegex.test(filePath);
1918
+ }
1919
+ function isPotentialPagesAssetGraphScript(filePath) {
1920
+ const cleanPath = stripViteModuleQuery(filePath);
1921
+ if (!path.isAbsolute(cleanPath)) return false;
1922
+ if (!isScriptModuleId(cleanPath) || cleanPath.endsWith(".d.ts")) return false;
1923
+ const relativeRootPath = normalizePathSeparators(path.relative(root, cleanPath));
1924
+ if (relativeRootPath.startsWith("..") || path.isAbsolute(relativeRootPath)) return false;
1925
+ if (relativeRootPath.includes("/node_modules/") || relativeRootPath.startsWith("node_modules/")) return false;
1926
+ const relativeAppPath = normalizePathSeparators(path.relative(appDir, cleanPath));
1927
+ return relativeAppPath.startsWith("..") || path.isAbsolute(relativeAppPath);
1928
+ }
1581
1929
  function warnRouteTypeGenerationFailure(error) {
1582
1930
  server.config.logger.warn(`[vinext] Failed to regenerate route types: ${error instanceof Error ? error.message : String(error)}`);
1583
1931
  }
@@ -1606,6 +1954,9 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1606
1954
  });
1607
1955
  server.watcher.on("add", (filePath) => {
1608
1956
  let routeChanged = false;
1957
+ const pagesAppChanged = isPagesAppFile(filePath);
1958
+ const pagesAssetGraphScriptChanged = isPotentialPagesAssetGraphScript(filePath);
1959
+ if (hasPagesDir && (pagesAppChanged || STYLESHEET_FILE_RE.test(filePath) || pagesAssetGraphScriptChanged)) invalidatePagesClientAssetsModule(pagesAppChanged || !hasAppDir && pagesAssetGraphScriptChanged);
1609
1960
  if (hasPagesDir && filePath.startsWith(pagesDir) && pageExtensions.test(filePath)) {
1610
1961
  invalidateRouteCache(pagesDir);
1611
1962
  routeChanged = true;
@@ -1621,8 +1972,16 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1621
1972
  revalidateHybridRoutes();
1622
1973
  }
1623
1974
  });
1975
+ server.watcher.on("change", (filePath) => {
1976
+ const pagesAppChanged = isPagesAppFile(filePath);
1977
+ const pagesAssetGraphScriptChanged = isPotentialPagesAssetGraphScript(filePath);
1978
+ if (hasPagesDir && (pagesAppChanged || STYLESHEET_FILE_RE.test(filePath) || pagesAssetGraphScriptChanged)) invalidatePagesClientAssetsModule(pagesAppChanged || !hasAppDir && pagesAssetGraphScriptChanged);
1979
+ });
1624
1980
  server.watcher.on("unlink", (filePath) => {
1625
1981
  let routeChanged = false;
1982
+ const pagesAppChanged = isPagesAppFile(filePath);
1983
+ const pagesAssetGraphScriptChanged = isPotentialPagesAssetGraphScript(filePath);
1984
+ if (hasPagesDir && (pagesAppChanged || STYLESHEET_FILE_RE.test(filePath) || pagesAssetGraphScriptChanged)) invalidatePagesClientAssetsModule(pagesAppChanged || !hasAppDir && pagesAssetGraphScriptChanged);
1626
1985
  if (hasPagesDir && filePath.startsWith(pagesDir) && pageExtensions.test(filePath)) {
1627
1986
  invalidateRouteCache(pagesDir);
1628
1987
  routeChanged = true;
@@ -1774,8 +2133,11 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1774
2133
  res.end("Forbidden");
1775
2134
  return;
1776
2135
  }
2136
+ const requestHost = (Array.isArray(req.headers.host) ? req.headers.host[0] : req.headers.host) || "localhost";
2137
+ const requestOrigin = `http://${requestHost}`;
2138
+ const getUrlHostname = (requestUrl) => new URL(requestUrl).hostname;
1777
2139
  if (isImageOptimizationPath(url.split("?")[0])) {
1778
- const encodedLocation = resolveDevImageRedirect(new URL(url, `http://${req.headers.host || "localhost"}`), [...nextConfig.images?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...nextConfig.images?.imageSizes ?? DEFAULT_IMAGE_SIZES], nextConfig.images?.qualities);
2140
+ const encodedLocation = resolveDevImageRedirect(new URL(url, requestOrigin), [...nextConfig.images?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...nextConfig.images?.imageSizes ?? DEFAULT_IMAGE_SIZES], nextConfig.images?.qualities);
1779
2141
  if (!encodedLocation) {
1780
2142
  res.writeHead(400);
1781
2143
  res.end("Invalid image optimization parameters");
@@ -1806,6 +2168,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1806
2168
  const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
1807
2169
  url = pathname + qs;
1808
2170
  }
2171
+ const capturedMiddlewarePath = middlewarePath;
1809
2172
  const bp = nextConfig?.basePath ?? "";
1810
2173
  if (bp && pathname.startsWith(bp)) {
1811
2174
  const stripped = pathname.slice(bp.length) || "/";
@@ -1830,8 +2193,9 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1830
2193
  if (dataMatch) {
1831
2194
  isDataReq = true;
1832
2195
  const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
1833
- url = dataMatch.pagePathname + qs;
1834
- pathname = dataMatch.pagePathname;
2196
+ const pagePathname = normalizeNextDataPagePathname(dataMatch.pagePathname, capturedMiddlewarePath !== null && nextConfig?.trailingSlash === true);
2197
+ url = pagePathname + qs;
2198
+ pathname = pagePathname;
1835
2199
  req.url = url;
1836
2200
  } else {
1837
2201
  const deploymentId = process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID;
@@ -1850,13 +2214,21 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1850
2214
  basePath: bp,
1851
2215
  hadBasePath: true
1852
2216
  }));
1853
- if (pathname.includes(".") && !pathname.endsWith(".html") && !filePathMatchesRewrite) return next();
2217
+ const isFilePathRequest = pathname.includes(".") && !pathname.endsWith(".html");
2218
+ let filePathMatchesPagesRoute = false;
2219
+ const requestHostname = getUrlHostname(requestOrigin);
2220
+ if (isFilePathRequest && !filePathMatchesRewrite) {
2221
+ const [pageRoutes, apiRoutes] = await Promise.all([pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher), apiRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher)]);
2222
+ const pageRouteUrl = nextConfig?.i18n ? resolvePagesI18nRequest(pathname, nextConfig.i18n, req.headers, requestHostname, bp, nextConfig.trailingSlash ?? false).url : pathname;
2223
+ const apiRouteUrl = stripI18nLocaleForApiRoute(pathname, nextConfig?.i18n ?? null);
2224
+ filePathMatchesPagesRoute = matchRoute(pageRouteUrl, pageRoutes) !== null || matchRoute(apiRouteUrl, apiRoutes) !== null;
2225
+ }
2226
+ if (isFilePathRequest && !filePathMatchesRewrite && !filePathMatchesPagesRoute) return next();
1854
2227
  const rawHeaders = new Headers(Object.fromEntries(Object.entries(req.headers).filter(([k, v]) => v !== void 0 && !k.startsWith(":")).map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : String(v)])));
1855
2228
  const isDataRequest = isDataReq;
1856
2229
  const nodeRequestHeaders = filterInternalHeaders(rawHeaders);
1857
2230
  for (const header of INTERNAL_HEADERS) delete req.headers[header];
1858
2231
  for (const header of VINEXT_INTERNAL_HEADERS) delete req.headers[header];
1859
- const requestOrigin = `http://${req.headers.host || "localhost"}`;
1860
2232
  const method = req.method ?? "GET";
1861
2233
  const webRequest = new Request(new URL(url, requestOrigin), {
1862
2234
  method,
@@ -1866,10 +2238,9 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1866
2238
  for (const key of Object.keys(req.headers)) delete req.headers[key];
1867
2239
  for (const [key, value] of nextRequestHeaders) req.headers[key] = value;
1868
2240
  };
1869
- const capturedMiddlewarePath = middlewarePath;
1870
2241
  const devRunMiddlewareAdapter = capturedMiddlewarePath ? async (_request, _ctx, opts) => {
1871
2242
  const rawProto = process.env.VINEXT_TRUST_PROXY === "1" || (process.env.VINEXT_TRUSTED_HOSTS ?? "").split(",").some((h) => h.trim()) ? String(req.headers["x-forwarded-proto"] || "").split(",")[0].trim() : "";
1872
- const mwOrigin = `${rawProto === "https" || rawProto === "http" ? rawProto : "http"}://${req.headers.host || "localhost"}`;
2243
+ const mwOrigin = `${rawProto === "https" || rawProto === "http" ? rawProto : "http"}://${requestHost}`;
1873
2244
  const middlewareRequest = new Request(new URL(url, mwOrigin), {
1874
2245
  method: req.method,
1875
2246
  headers: nodeRequestHeaders
@@ -1890,6 +2261,18 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1890
2261
  return result;
1891
2262
  } : null;
1892
2263
  const devPageRoutes = await pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);
2264
+ const devPageRouteDataKinds = /* @__PURE__ */ new Map();
2265
+ const classifyDevPageRoute = (route) => {
2266
+ const cached = devPageRouteDataKinds.get(route.filePath);
2267
+ if (cached) return cached;
2268
+ let dataKind = "none";
2269
+ try {
2270
+ const source = fs.readFileSync(route.filePath, "utf8");
2271
+ dataKind = hasExportedName(source, "getStaticProps") ? "static" : hasExportedName(source, "getServerSideProps") ? "server" : "none";
2272
+ } catch {}
2273
+ devPageRouteDataKinds.set(route.filePath, dataKind);
2274
+ return dataKind;
2275
+ };
1893
2276
  const pipelineResult = await runPagesRequest(webRequest, {
1894
2277
  basePath: bp,
1895
2278
  trailingSlash: nextConfig?.trailingSlash ?? false,
@@ -1908,8 +2291,9 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1908
2291
  rawSearch: url.includes("?") ? url.slice(url.indexOf("?")) : "",
1909
2292
  runMiddleware: devRunMiddlewareAdapter,
1910
2293
  matchPageRoute: (resolvedPathname, request) => {
1911
- const m = matchRoute(nextConfig?.i18n ? resolvePagesI18nRequest(resolvedPathname, nextConfig.i18n, request.headers, new URL(request.url).hostname, bp, nextConfig.trailingSlash ?? false).url : resolvedPathname, devPageRoutes);
2294
+ const m = matchRoute(nextConfig?.i18n ? resolvePagesI18nRequest(resolvedPathname, nextConfig.i18n, request.headers, getUrlHostname(request.url), bp, nextConfig.trailingSlash ?? false).url : resolvedPathname, devPageRoutes);
1912
2295
  return m ? { route: {
2296
+ dataKind: classifyDevPageRoute(m.route),
1913
2297
  isDynamic: m.route.isDynamic,
1914
2298
  pattern: m.route.pattern
1915
2299
  } } : null;
@@ -1980,7 +2364,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
1980
2364
  }
1981
2365
  if (!cachedSSRHandler || cachedSSRHandler.routes !== routes) cachedSSRHandler = {
1982
2366
  routes,
1983
- handler: createSSRHandler(server, getPagesRunner(), routes, pagesDir, nextConfig?.i18n, fileMatcher, nextConfig?.basePath ?? "", nextConfig?.trailingSlash ?? false, middlewarePath !== null, (nextConfig?.rewrites.beforeFiles.length ?? 0) > 0 || (nextConfig?.rewrites.afterFiles.length ?? 0) > 0 || (nextConfig?.rewrites.fallback.length ?? 0) > 0, nextConfig?.clientTraceMetadata, nextConfig?.htmlLimitedBots)
2367
+ handler: createSSRHandler(server, getPagesRunner(), routes, pagesDir, nextConfig?.i18n, fileMatcher, nextConfig?.basePath ?? "", nextConfig?.trailingSlash ?? false, middlewarePath !== null, (nextConfig?.rewrites.beforeFiles.length ?? 0) > 0 || (nextConfig?.rewrites.afterFiles.length ?? 0) > 0 || (nextConfig?.rewrites.fallback.length ?? 0) > 0, nextConfig?.clientTraceMetadata, nextConfig?.htmlLimitedBots, nextConfig?.reactStrictMode === true)
1984
2368
  };
1985
2369
  flushStagedHeaders();
1986
2370
  flushRequestHeaders();
@@ -2114,6 +2498,18 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
2114
2498
  return { define: serverDefines };
2115
2499
  }
2116
2500
  },
2501
+ {
2502
+ name: "vinext:client-global-define",
2503
+ configEnvironment(name) {
2504
+ if (name !== "client") return null;
2505
+ if (Object.hasOwn(nextConfig.compilerDefine, "global")) return null;
2506
+ const define = { global: "globalThis" };
2507
+ return {
2508
+ define,
2509
+ optimizeDeps: { rolldownOptions: { transform: { define } } }
2510
+ };
2511
+ }
2512
+ },
2117
2513
  {
2118
2514
  name: "vinext:image-imports",
2119
2515
  enforce: "pre",
@@ -2692,6 +3088,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
2692
3088
  ];
2693
3089
  if (rscPluginPromise) {
2694
3090
  plugins.push(rscPluginPromise);
3091
+ plugins.push(createRscReferenceValidationNormalizerPlugin());
2695
3092
  plugins.push(createRscClientReferenceLoadersPlugin());
2696
3093
  }
2697
3094
  return plugins;