vinext 1.4.1 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/build/action-owner-manifest.js +1 -0
- package/dist/build/prerender-paths.d.ts +11 -1
- package/dist/build/prerender-paths.js +36 -10
- package/dist/check.js +1 -1
- package/dist/cli.js +1 -1
- package/dist/client/dev-error-overlay.d.ts +2 -1
- package/dist/client/dev-error-overlay.js +8 -3
- package/dist/config/config-matchers.js +8 -4
- package/dist/config/destination-params.js +5 -2
- package/dist/config/next-config.d.ts +25 -1
- package/dist/config/next-config.js +31 -1
- package/dist/entries/app-rsc-entry.js +65 -30
- package/dist/entries/app-rsc-manifest.js +4 -0
- package/dist/entries/pages-server-entry.js +19 -4
- package/dist/index.js +37 -37
- package/dist/init-cloudflare.js +18 -2
- package/dist/init-platform.js +2 -2
- package/dist/init.js +42 -5
- package/dist/plugins/css-target.d.ts +18 -0
- package/dist/plugins/css-target.js +93 -0
- package/dist/routing/app-route-graph.d.ts +10 -0
- package/dist/routing/app-route-graph.js +15 -1
- package/dist/server/api-handler.d.ts +2 -0
- package/dist/server/api-handler.js +10 -8
- package/dist/server/app-action-forwarding.js +3 -1
- package/dist/server/app-browser-entry.js +37 -41
- package/dist/server/app-browser-error.d.ts +1 -1
- package/dist/server/app-browser-error.js +13 -4
- package/dist/server/app-browser-supplemental-refresh.d.ts +13 -0
- package/dist/server/app-browser-supplemental-refresh.js +36 -4
- package/dist/server/app-elements.d.ts +3 -0
- package/dist/server/app-elements.js +14 -1
- package/dist/server/app-fallback-renderer.js +2 -2
- package/dist/server/app-middleware.d.ts +2 -0
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.d.ts +12 -1
- package/dist/server/app-optimistic-routing.js +38 -16
- package/dist/server/app-page-boundary-render.js +4 -2
- package/dist/server/app-page-cache-render.js +1 -1
- package/dist/server/app-page-dispatch.d.ts +11 -1
- package/dist/server/app-page-dispatch.js +78 -31
- package/dist/server/app-page-element-builder.d.ts +11 -20
- package/dist/server/app-page-element-builder.js +39 -50
- package/dist/server/app-page-intercept-segment-config.d.ts +56 -0
- package/dist/server/app-page-intercept-segment-config.js +90 -0
- package/dist/server/app-page-navigation-params.d.ts +23 -0
- package/dist/server/app-page-navigation-params.js +49 -0
- package/dist/server/app-page-render.d.ts +5 -2
- package/dist/server/app-page-render.js +17 -3
- package/dist/server/app-page-request.d.ts +24 -2
- package/dist/server/app-page-request.js +10 -10
- package/dist/server/app-page-route-wiring.d.ts +17 -5
- package/dist/server/app-page-route-wiring.js +19 -13
- package/dist/server/app-page-segment-plan.js +9 -1
- package/dist/server/app-page-segment-state.d.ts +9 -0
- package/dist/server/app-page-segment-state.js +54 -1
- package/dist/server/app-pages-bridge.d.ts +6 -0
- package/dist/server/app-pages-bridge.js +8 -3
- package/dist/server/app-request-stage-independent-entry.js +2 -3
- package/dist/server/app-response-stage-entry.js +1 -0
- package/dist/server/app-route-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.js +2 -3
- package/dist/server/app-rsc-cache-busting.d.ts +8 -0
- package/dist/server/app-rsc-cache-busting.js +13 -1
- package/dist/server/app-rsc-combined-handler.js +2 -1
- package/dist/server/app-rsc-handler.d.ts +14 -1
- package/dist/server/app-rsc-handler.js +111 -62
- package/dist/server/app-rsc-response-finalizer.d.ts +18 -3
- package/dist/server/app-rsc-response-finalizer.js +61 -7
- package/dist/server/app-rsc-route-matching.d.ts +14 -0
- package/dist/server/app-rsc-route-matching.js +42 -18
- package/dist/server/app-server-action-execution.js +16 -10
- package/dist/server/app-ssr-entry.js +8 -0
- package/dist/server/cache-control.d.ts +2 -0
- package/dist/server/cache-control.js +3 -1
- package/dist/server/config-headers.d.ts +7 -0
- package/dist/server/config-headers.js +20 -1
- package/dist/server/image-animation.d.ts +9 -0
- package/dist/server/image-animation.js +118 -0
- package/dist/server/image-local-patterns.d.ts +21 -0
- package/dist/server/image-local-patterns.js +59 -0
- package/dist/server/image-optimization.d.ts +48 -27
- package/dist/server/image-optimization.js +316 -22
- package/dist/server/image-source-reader.d.ts +34 -0
- package/dist/server/image-source-reader.js +126 -0
- package/dist/server/metadata-route-response.d.ts +6 -1
- package/dist/server/metadata-route-response.js +46 -10
- package/dist/server/middleware-matcher.d.ts +1 -0
- package/dist/server/middleware-matcher.js +1 -1
- package/dist/server/middleware-runtime.d.ts +5 -0
- package/dist/server/middleware-runtime.js +48 -15
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +2 -1
- package/dist/server/nitro-public-files-plugin.js +20 -8
- package/dist/server/nitro-request-target-plugin.d.ts +17 -0
- package/dist/server/nitro-request-target-plugin.js +22 -0
- package/dist/server/open-redirect.d.ts +2 -1
- package/dist/server/open-redirect.js +2 -1
- package/dist/server/pages-client-assets.d.ts +1 -0
- package/dist/server/pages-data-route.d.ts +5 -1
- package/dist/server/pages-data-route.js +14 -6
- package/dist/server/pages-i18n.d.ts +7 -0
- package/dist/server/pages-i18n.js +14 -1
- package/dist/server/pages-node-compat.js +7 -3
- package/dist/server/pages-page-handler.js +4 -4
- package/dist/server/pages-request-pipeline.d.ts +9 -0
- package/dist/server/pages-request-pipeline.js +35 -15
- package/dist/server/pages-request-stage-entry.js +8 -2
- package/dist/server/pages-router-entry.js +3 -0
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +64 -62
- package/dist/server/request-pipeline.d.ts +5 -0
- package/dist/server/request-pipeline.js +11 -1
- package/dist/server/response-stage-cacheability.d.ts +7 -0
- package/dist/server/response-stage-cacheability.js +6 -5
- package/dist/server/srvx-middleware-origin.d.ts +13 -0
- package/dist/server/srvx-middleware-origin.js +19 -0
- package/dist/server/srvx-request-target.d.ts +12 -0
- package/dist/server/srvx-request-target.js +20 -0
- package/dist/server/static-file-cache.js +10 -22
- package/dist/server/worker-image-optimization.d.ts +10 -3
- package/dist/server/worker-image-optimization.js +43 -9
- package/dist/server/worker-revalidation-context.js +1 -0
- package/dist/server/worker-utils.d.ts +8 -0
- package/dist/server/worker-utils.js +19 -2
- package/dist/shims/error-boundary.d.ts +6 -2
- package/dist/shims/error-boundary.js +4 -2
- package/dist/shims/image-props.d.ts +6 -0
- package/dist/shims/image-props.js +39 -3
- package/dist/shims/image.js +3 -3
- package/dist/shims/request-context.d.ts +3 -1
- package/dist/shims/slot.d.ts +3 -0
- package/dist/shims/slot.js +67 -9
- package/dist/shims/url-utils.js +6 -1
- package/dist/utils/base-path.d.ts +7 -0
- package/dist/utils/base-path.js +11 -1
- package/dist/utils/client-entry-manifest.d.ts +5 -0
- package/dist/utils/client-entry-manifest.js +1 -0
- package/dist/utils/client-runtime-metadata.d.ts +5 -0
- package/dist/utils/client-runtime-metadata.js +33 -7
- package/package.json +1 -1
|
@@ -104,10 +104,13 @@ async function generatePagesRequestEntry(pagesDir, nextConfig, fileMatcher, midd
|
|
|
104
104
|
deviceSizes: nextConfig?.images?.deviceSizes,
|
|
105
105
|
imageSizes: nextConfig?.images?.imageSizes,
|
|
106
106
|
qualities: nextConfig?.images?.qualities,
|
|
107
|
+
localPatterns: nextConfig?.images?.localPatterns,
|
|
107
108
|
dangerouslyAllowSVG: nextConfig?.images?.dangerouslyAllowSVG,
|
|
108
109
|
dangerouslyAllowLocalIP: nextConfig?.images?.dangerouslyAllowLocalIP,
|
|
109
110
|
contentDispositionType: nextConfig?.images?.contentDispositionType,
|
|
110
|
-
contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy
|
|
111
|
+
contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy,
|
|
112
|
+
minimumCacheTTL: nextConfig?.images?.minimumCacheTTL,
|
|
113
|
+
maximumResponseBody: nextConfig?.images?.maximumResponseBody
|
|
111
114
|
}
|
|
112
115
|
});
|
|
113
116
|
const instrumentationImportCode = instrumentationPath ? `import * as _instrumentation from ${JSON.stringify(instrumentationPath)};
|
|
@@ -134,6 +137,7 @@ export function __ensureInstrumentation(ctx) {
|
|
|
134
137
|
isProxy: ${JSON.stringify(isProxyFile(middlewarePath))},
|
|
135
138
|
module: middlewareModule,
|
|
136
139
|
request,
|
|
140
|
+
restoreLocaleRootTrailingSlash: options?.restoreLocaleRootTrailingSlash === true,
|
|
137
141
|
skipTrailingSlashRedirect: vinextConfig.skipTrailingSlashRedirect,
|
|
138
142
|
trailingSlash: vinextConfig.trailingSlash,
|
|
139
143
|
});
|
|
@@ -164,11 +168,14 @@ export const vinextConfig = ${vinextConfigJson};
|
|
|
164
168
|
export const publicFiles = new Set(${JSON.stringify(publicFiles)});
|
|
165
169
|
export const clientBuildFiles = new Set(__pagesClientAssets.clientBuildFiles ?? []);
|
|
166
170
|
|
|
171
|
+
// The Worker request stage strips basePath before calling this, so the data
|
|
172
|
+
// path must not lose it again: with basePath "/docs", "/docs/docs/_next/data/..."
|
|
173
|
+
// is the page path "/docs/_next/data/...", not a data request.
|
|
167
174
|
export function normalizeDataRequest(request) {
|
|
168
175
|
return __normalizePagesDataRequest(
|
|
169
176
|
request,
|
|
170
177
|
buildId,
|
|
171
|
-
|
|
178
|
+
"",
|
|
172
179
|
__shouldAddTrailingSlashToPagesDataPath(
|
|
173
180
|
hasMiddleware,
|
|
174
181
|
vinextConfig.trailingSlash,
|
|
@@ -281,10 +288,13 @@ async function generateServerEntry(pagesDir, nextConfig, fileMatcher, middleware
|
|
|
281
288
|
deviceSizes: nextConfig?.images?.deviceSizes,
|
|
282
289
|
imageSizes: nextConfig?.images?.imageSizes,
|
|
283
290
|
qualities: nextConfig?.images?.qualities,
|
|
291
|
+
localPatterns: nextConfig?.images?.localPatterns,
|
|
284
292
|
dangerouslyAllowSVG: nextConfig?.images?.dangerouslyAllowSVG,
|
|
285
293
|
dangerouslyAllowLocalIP: nextConfig?.images?.dangerouslyAllowLocalIP,
|
|
286
294
|
contentDispositionType: nextConfig?.images?.contentDispositionType,
|
|
287
|
-
contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy
|
|
295
|
+
contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy,
|
|
296
|
+
minimumCacheTTL: nextConfig?.images?.minimumCacheTTL,
|
|
297
|
+
maximumResponseBody: nextConfig?.images?.maximumResponseBody
|
|
288
298
|
}
|
|
289
299
|
});
|
|
290
300
|
const instrumentationImportCode = instrumentationPath ? `import * as _instrumentation from ${JSON.stringify(instrumentationPath)};
|
|
@@ -331,6 +341,7 @@ export async function runMiddleware(request, ctx, options) {
|
|
|
331
341
|
isProxy: ${JSON.stringify(isProxyFile(middlewarePath))},
|
|
332
342
|
module: middlewareModule,
|
|
333
343
|
request,
|
|
344
|
+
restoreLocaleRootTrailingSlash: options?.restoreLocaleRootTrailingSlash === true,
|
|
334
345
|
skipTrailingSlashRedirect: vinextConfig.skipTrailingSlashRedirect,
|
|
335
346
|
trailingSlash: vinextConfig.trailingSlash,
|
|
336
347
|
});
|
|
@@ -398,11 +409,14 @@ export const buildId = ${buildIdJson};
|
|
|
398
409
|
// Per-build capability used by Worker entries to authorize remote path
|
|
399
410
|
// discovery. It is never included in responses or exposed to user modules.
|
|
400
411
|
export const prerenderSecret = ${JSON.stringify(prerenderSecret ?? null)};
|
|
412
|
+
// The Worker request stage strips basePath before calling this, so the data
|
|
413
|
+
// path must not lose it again: with basePath "/docs", "/docs/docs/_next/data/..."
|
|
414
|
+
// is the page path "/docs/_next/data/...", not a data request.
|
|
401
415
|
export function normalizeDataRequest(request) {
|
|
402
416
|
return __normalizePagesDataRequest(
|
|
403
417
|
request,
|
|
404
418
|
buildId,
|
|
405
|
-
|
|
419
|
+
"",
|
|
406
420
|
__shouldAddTrailingSlashToPagesDataPath(
|
|
407
421
|
hasMiddleware,
|
|
408
422
|
vinextConfig.trailingSlash,
|
|
@@ -437,6 +451,7 @@ export const pageRoutes = [
|
|
|
437
451
|
${pageRouteEntries.join(",\n")}
|
|
438
452
|
];
|
|
439
453
|
export const publicFiles = new Set(${JSON.stringify(publicFiles)});
|
|
454
|
+
export const clientBuildFiles = new Set(__pagesClientAssets.clientBuildFiles ?? []);
|
|
440
455
|
const _pageRouteTrie = _buildRouteTrie(pageRoutes);
|
|
441
456
|
const _errorPageRoute = {
|
|
442
457
|
pattern: "/_error",
|
package/dist/index.js
CHANGED
|
@@ -14,12 +14,12 @@ import { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } from "./shims/consta
|
|
|
14
14
|
import { serializeCacheLifeProfiles } from "./utils/cache-life-profiles.js";
|
|
15
15
|
import { VINEXT_MW_CTX_HEADER } from "./utils/protocol-headers.js";
|
|
16
16
|
import { encodeMiddlewareRequestHeaders } from "./utils/middleware-request-headers.js";
|
|
17
|
-
import { hasBasePath, stripBasePath } from "./utils/base-path.js";
|
|
17
|
+
import { hasBasePath, restoreBasePath, stripBasePath } from "./utils/base-path.js";
|
|
18
18
|
import { INTERNAL_HEADERS, NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_TIMING_HEADER } from "./server/headers.js";
|
|
19
19
|
import { methodNotAllowedResponse, notFoundStaticAssetResponse } from "./server/http-error-responses.js";
|
|
20
20
|
import { isOpenRedirectShaped, sendRepeatedSlashRedirect } from "./server/open-redirect.js";
|
|
21
21
|
import { canonicalizeRequestUrlPathname, filterInternalHeaders, normalizeTrailingSlash } from "./server/request-pipeline.js";
|
|
22
|
-
import {
|
|
22
|
+
import { proxyExternalRequest } from "./config/config-matchers.js";
|
|
23
23
|
import { omitUnusedBuildSourcemap } from "./plugins/transform-result.js";
|
|
24
24
|
import { assetPrefixPathname, isNextStaticPath, resolveAssetsDir } from "./utils/asset-prefix.js";
|
|
25
25
|
import { RESOLVED_VIRTUAL_GOOGLE_FONTS, VIRTUAL_GOOGLE_FONTS, createGoogleFontsPlugin, createLocalFontsPlugin, generateGoogleFontsVirtualModule, parseStaticObjectLiteral } from "./plugins/fonts.js";
|
|
@@ -31,7 +31,7 @@ import { apiRouter, invalidateRouteCache, matchRoute, pagesRouter } from "./rout
|
|
|
31
31
|
import { resolveRuntimeEntryModule } from "./entries/runtime-entry-module.js";
|
|
32
32
|
import { normalizePath as normalizePath$1 } from "./server/normalize-path.js";
|
|
33
33
|
import { validateMiddlewareMatcherPatterns } from "./server/middleware-matcher-pattern.js";
|
|
34
|
-
import { resolvePagesI18nRequest, shouldRestoreLocaleRootTrailingSlash
|
|
34
|
+
import { resolvePagesI18nRequest, shouldRestoreLocaleRootTrailingSlash } from "./server/pages-i18n.js";
|
|
35
35
|
import { encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath } from "./server/pages-data-route.js";
|
|
36
36
|
import { findInstrumentationClientFile, findInstrumentationFile, runInstrumentation } from "./server/instrumentation.js";
|
|
37
37
|
import { findMiddlewareFile, isProxyFile, runMiddleware } from "./server/middleware.js";
|
|
@@ -78,6 +78,7 @@ import { readTrustedRevalidationHostname } from "./server/revalidation-host.js";
|
|
|
78
78
|
import { sealForwardedMiddlewareContext } from "./server/forwarded-middleware-context.js";
|
|
79
79
|
import { installDevStackSourcemapMiddleware } from "./server/dev-stack-sourcemap.js";
|
|
80
80
|
import { traceFrameworkRequest } from "./server/request-tracing.js";
|
|
81
|
+
import { publicFileRouteKey } from "./utils/public-file-path.js";
|
|
81
82
|
import { runPagesRequest } from "./server/pages-request-pipeline.js";
|
|
82
83
|
import { pagesRouteHasPriorityOverAppRoute, validateHybridRouteConflicts } from "./server/hybrid-route-priority.js";
|
|
83
84
|
import { hasReactCompilerPlugin, isReactCompilerPlugin, isReactCompilerRequested, reactCompilerUnsupportedMessage } from "./utils/react-compiler-support.js";
|
|
@@ -89,6 +90,7 @@ import { createClientCompileHintsPlugin } from "./plugins/client-compile-hints.j
|
|
|
89
90
|
import { clientReferenceDedupPlugin } from "./plugins/client-reference-dedup.js";
|
|
90
91
|
import { dataUrlCssPlugin } from "./plugins/css-data-url.js";
|
|
91
92
|
import { createCssModuleImportCompatibilityPlugin } from "./plugins/css-module-imports.js";
|
|
93
|
+
import { createCssTargetPlugin } from "./plugins/css-target.js";
|
|
92
94
|
import { createWorkerImageImportsPlugin } from "./plugins/worker-image-imports.js";
|
|
93
95
|
import { assertClientOutDirIsSeparate, createClientAssetFileNames, createClientCodeSplittingConfig, createClientManualChunks, createClientOutputFileNameDefaults, createMultiStageChunkFileNames, createMultiStageCodeSplittingConfig, createRscFrameworkChunkOutputConfig, createWorkerFileNames, findUnsupportedClientOutputFileNames, getBuildBundlerOptions, getClientTreeshakeConfig, getOutputFileNames, withBuildBundlerOptions } from "./build/client-build-config.js";
|
|
94
96
|
import { createRouteClientReferencesFallbackPlugin, createRscClientReferenceLoadersPlugin } from "./plugins/rsc-client-reference-loaders.js";
|
|
@@ -133,7 +135,6 @@ import { createExtensionlessDynamicImportPlugin } from "./plugins/extensionless-
|
|
|
133
135
|
import { createWasmModuleImportPlugin } from "./plugins/wasm-module-import.js";
|
|
134
136
|
import { consumerEnvironmentConditionFilter, getTypeofWindowReplacement, mayFoldChangeScannedImports, replaceConsumerEnvironmentConditions } from "./plugins/typeof-window.js";
|
|
135
137
|
import { hasMdxFiles, loadMdxEsmReader, pageExtensionsIncludeMdx } from "./utils/mdx-scan.js";
|
|
136
|
-
import { publicFileRouteKey } from "./utils/public-file-path.js";
|
|
137
138
|
import { scanPublicFileRoutes, scanPublicFiles } from "./utils/public-routes.js";
|
|
138
139
|
import { createIgnoreDynamicRequestsPlugin } from "./plugins/ignore-dynamic-requests.js";
|
|
139
140
|
import { assertPluginRscVersion, needsAppReactServerDom } from "./utils/plugin-rsc-version.js";
|
|
@@ -843,6 +844,7 @@ const PAGES_REQUEST_STAGE_ENTRY = resolveRuntimeEntryModule("pages-request-stage
|
|
|
843
844
|
const PAGES_RESPONSE_STAGE_ENTRY = resolveRuntimeEntryModule("pages-response-stage-entry");
|
|
844
845
|
const NITRO_PUBLIC_FILES_ENTRY = resolveRuntimeEntryModule("nitro-public-files");
|
|
845
846
|
const NITRO_PUBLIC_FILES_PLUGIN = resolveRuntimeEntryModule("nitro-public-files-plugin");
|
|
847
|
+
const SRVX_MIDDLEWARE_ORIGIN_ENTRY = resolveRuntimeEntryModule("srvx-middleware-origin");
|
|
846
848
|
const WORKER_ROUTER_ENTRIES = /* @__PURE__ */ new Set([resolveRuntimeEntryModule("app-router-entry"), resolveRuntimeEntryModule("pages-router-entry")]);
|
|
847
849
|
/** Virtual module that registers config-driven cache adapters (see VinextOptions.cache). */
|
|
848
850
|
const RESOLVED_CACHE_ADAPTERS = "\0" + VIRTUAL_CACHE_ADAPTERS;
|
|
@@ -1466,6 +1468,7 @@ function vinext(options = {}) {
|
|
|
1466
1468
|
}),
|
|
1467
1469
|
dataUrlCssPlugin(),
|
|
1468
1470
|
createCssModuleImportCompatibilityPlugin(),
|
|
1471
|
+
createCssTargetPlugin(),
|
|
1469
1472
|
createDevServerLifecyclePlugin({}, (config) => config[VINEXT_DEV_CLI_LIFECYCLE] === true),
|
|
1470
1473
|
{
|
|
1471
1474
|
name: "vinext:config",
|
|
@@ -1764,12 +1767,6 @@ function vinext(options = {}) {
|
|
|
1764
1767
|
} } : {},
|
|
1765
1768
|
build: {
|
|
1766
1769
|
ssrEmitAssets: true,
|
|
1767
|
-
cssTarget: [
|
|
1768
|
-
"chrome111",
|
|
1769
|
-
"edge111",
|
|
1770
|
-
"firefox114",
|
|
1771
|
-
"safari15"
|
|
1772
|
-
],
|
|
1773
1770
|
assetsDir: clientAssetsDir,
|
|
1774
1771
|
...!isSSR && !hasClientBuildEnvironment ? { assetsInlineLimit: clientAssetsInlineLimit } : {},
|
|
1775
1772
|
...withBuildBundlerOptions({
|
|
@@ -2363,9 +2360,14 @@ function vinext(options = {}) {
|
|
|
2363
2360
|
const entry = hasAppDir ? "vinext/server/app-router-entry" : "vinext/server/pages-router-entry";
|
|
2364
2361
|
if (!hasAppDir && hasNitroPlugin) return [
|
|
2365
2362
|
`import pagesWorker from ${JSON.stringify(entry)};`,
|
|
2363
|
+
`import { resolveSrvxMiddlewareOrigin } from ${JSON.stringify(SRVX_MIDDLEWARE_ORIGIN_ENTRY)};`,
|
|
2366
2364
|
...nitroPublicFiles ? [`import { withNitroPagesPublicFiles } from ${JSON.stringify(NITRO_PUBLIC_FILES_ENTRY)};`, "const worker = withNitroPagesPublicFiles(pagesWorker);"] : ["const worker = pagesWorker;"],
|
|
2367
2365
|
"export default { fetch(request, env, ctx) {",
|
|
2368
|
-
|
|
2366
|
+
" return worker.fetch(request, env, {",
|
|
2367
|
+
" ...ctx,",
|
|
2368
|
+
` hostRuntime: ${JSON.stringify(nitroHostRuntime)},`,
|
|
2369
|
+
" middlewareOrigin: resolveSrvxMiddlewareOrigin(request),",
|
|
2370
|
+
" });",
|
|
2369
2371
|
"} };"
|
|
2370
2372
|
].join("\n");
|
|
2371
2373
|
return `export { default } from ${JSON.stringify(entry)};`;
|
|
@@ -2453,10 +2455,13 @@ function vinext(options = {}) {
|
|
|
2453
2455
|
deviceSizes: nextConfig?.images?.deviceSizes,
|
|
2454
2456
|
imageSizes: nextConfig?.images?.imageSizes,
|
|
2455
2457
|
qualities: nextConfig?.images?.qualities,
|
|
2458
|
+
localPatterns: nextConfig?.images?.localPatterns,
|
|
2456
2459
|
dangerouslyAllowSVG: nextConfig?.images?.dangerouslyAllowSVG,
|
|
2457
2460
|
dangerouslyAllowLocalIP: nextConfig?.images?.dangerouslyAllowLocalIP,
|
|
2458
2461
|
contentDispositionType: nextConfig?.images?.contentDispositionType,
|
|
2459
|
-
contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy
|
|
2462
|
+
contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy,
|
|
2463
|
+
minimumCacheTTL: nextConfig?.images?.minimumCacheTTL,
|
|
2464
|
+
maximumResponseBody: nextConfig?.images?.maximumResponseBody
|
|
2460
2465
|
},
|
|
2461
2466
|
hasPagesDir,
|
|
2462
2467
|
publicFiles: isServeCommand && devPublicFileRoutes ? [...devPublicFileRoutes].sort() : scanPublicFileRoutes(root, this.environment.config.publicDir === "" ? false : this.environment.config.publicDir),
|
|
@@ -2737,9 +2742,11 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
|
|
|
2737
2742
|
handler(_options, bundle) {
|
|
2738
2743
|
if (this.environment?.name !== "client") return;
|
|
2739
2744
|
const manifest = {};
|
|
2745
|
+
const appBrowserRuntimeModule = toSlash(resolveRuntimeEntryModule("app-browser-entry"));
|
|
2740
2746
|
for (const chunk of Object.values(bundle)) {
|
|
2741
2747
|
if (chunk.type !== "chunk") continue;
|
|
2742
2748
|
if (chunk.isDynamicEntry && isVirtualEntryFacade(chunk.facadeModuleId, VIRTUAL_APP_ROUTE_MANIFEST)) manifest.appRouteManifest = chunk.fileName;
|
|
2749
|
+
if (chunk.moduleIds.some((id) => toSlash(id) === appBrowserRuntimeModule)) manifest.appBrowserRuntime = chunk.fileName;
|
|
2743
2750
|
if (!chunk.isEntry) continue;
|
|
2744
2751
|
if (isVirtualEntryFacade(chunk.facadeModuleId, VIRTUAL_CLIENT_ENTRY)) manifest.pagesClientEntry = chunk.fileName;
|
|
2745
2752
|
else if (isVirtualEntryFacade(chunk.facadeModuleId, VIRTUAL_APP_BROWSER_ENTRY)) manifest.appBrowserEntry = chunk.fileName;
|
|
@@ -3378,14 +3385,17 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
|
|
|
3378
3385
|
const viteBase = server.config.base;
|
|
3379
3386
|
const viteBasePath = viteBase.startsWith("/") && viteBase !== "/" ? viteBase.replace(/\/+$/, "") : "";
|
|
3380
3387
|
const routingBasePath = bp || viteBasePath;
|
|
3388
|
+
const viteStrippedBasePath = originalRequestUrl !== originalEncodedUrl;
|
|
3389
|
+
let originalUrlHadBasePath = false;
|
|
3381
3390
|
if (routingBasePath) {
|
|
3382
|
-
if (hasBasePath(pathname, routingBasePath)) {
|
|
3391
|
+
if (!viteStrippedBasePath && hasBasePath(pathname, routingBasePath)) {
|
|
3383
3392
|
const stripped = stripBasePath(pathname, routingBasePath);
|
|
3384
3393
|
url = stripped + (url.includes("?") ? url.slice(url.indexOf("?")) : "");
|
|
3385
3394
|
pathname = stripped;
|
|
3386
3395
|
}
|
|
3387
3396
|
const middlewarePathname = middlewareUrl.split("?")[0];
|
|
3388
3397
|
if (hasBasePath(middlewarePathname, routingBasePath)) {
|
|
3398
|
+
originalUrlHadBasePath = true;
|
|
3389
3399
|
const middlewareQs = middlewareUrl.includes("?") ? middlewareUrl.slice(middlewareUrl.indexOf("?")) : "";
|
|
3390
3400
|
middlewareUrl = stripBasePath(middlewarePathname, routingBasePath) + middlewareQs;
|
|
3391
3401
|
}
|
|
@@ -3395,7 +3405,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
|
|
|
3395
3405
|
routeUrl = stripBasePath(routePathname, routingBasePath) + routeQs;
|
|
3396
3406
|
}
|
|
3397
3407
|
}
|
|
3398
|
-
let configMatchPathname =
|
|
3408
|
+
let configMatchPathname = middlewareUrl.split("?")[0];
|
|
3399
3409
|
if (nextConfig && !nextConfig.skipTrailingSlashRedirect) {
|
|
3400
3410
|
const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
|
|
3401
3411
|
const trailingSlashRedirect = normalizeTrailingSlash(routeUrl.split("?")[0], bp, nextConfig.trailingSlash, qs);
|
|
@@ -3412,7 +3422,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
|
|
|
3412
3422
|
const rawRoutePathname = routeUrl.split("?")[0];
|
|
3413
3423
|
if (isNextDataPathname(rawRoutePathname)) {
|
|
3414
3424
|
const rawDataMatch = parseNextDataPathname(rawRoutePathname, devBuildId);
|
|
3415
|
-
const dataMatch = rawDataMatch ? parseNextDataPathname(pathname, devBuildId) : null;
|
|
3425
|
+
const dataMatch = rawDataMatch ? parseNextDataPathname(pathname, devBuildId, true) : null;
|
|
3416
3426
|
if (dataMatch && rawDataMatch) {
|
|
3417
3427
|
isDataReq = true;
|
|
3418
3428
|
const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
|
|
@@ -3441,25 +3451,6 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
|
|
|
3441
3451
|
});
|
|
3442
3452
|
}
|
|
3443
3453
|
}
|
|
3444
|
-
const filePathMatchesRewrite = [
|
|
3445
|
-
...nextConfig?.rewrites.beforeFiles ?? [],
|
|
3446
|
-
...nextConfig?.rewrites.afterFiles ?? [],
|
|
3447
|
-
...nextConfig?.rewrites.fallback ?? []
|
|
3448
|
-
].some((rewrite) => matchesRewriteSource(pathname, rewrite, {
|
|
3449
|
-
basePath: bp,
|
|
3450
|
-
hadBasePath: true
|
|
3451
|
-
}));
|
|
3452
|
-
const isFilePathRequest = pathname.includes(".") && !pathname.endsWith(".html");
|
|
3453
|
-
const isExistingPublicMutation = req.method !== "GET" && req.method !== "HEAD" && isExistingDevPublicFile(pathname);
|
|
3454
|
-
let filePathMatchesPagesRoute = false;
|
|
3455
|
-
const requestHostname = getUrlHostname(requestOrigin);
|
|
3456
|
-
if (isFilePathRequest && !filePathMatchesRewrite && !isDataReq) {
|
|
3457
|
-
const [pageRoutes, apiRoutes] = await Promise.all([pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher), apiRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher)]);
|
|
3458
|
-
const pageRouteUrl = nextConfig?.i18n ? resolvePagesI18nRequest(pathname, nextConfig.i18n, req.headers, requestHostname, bp, nextConfig.trailingSlash ?? false).url : pathname;
|
|
3459
|
-
const apiRouteUrl = stripI18nLocaleForApiRoute(pathname, nextConfig?.i18n ?? null);
|
|
3460
|
-
filePathMatchesPagesRoute = matchRoute(pageRouteUrl, pageRoutes) !== null || matchRoute(apiRouteUrl, apiRoutes) !== null;
|
|
3461
|
-
}
|
|
3462
|
-
if (isFilePathRequest && !isDataReq && !filePathMatchesRewrite && !filePathMatchesPagesRoute && !isNextStaticPath(pathname, "", assetPrefixPathname(nextConfig?.assetPrefix ?? "")) && !isExistingPublicMutation) return next();
|
|
3463
3454
|
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)])));
|
|
3464
3455
|
const isDataRequest = isDataReq;
|
|
3465
3456
|
const nodeRequestHeaders = filterInternalHeaders(rawHeaders);
|
|
@@ -3482,12 +3473,14 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
|
|
|
3482
3473
|
const devRunMiddlewareAdapter = capturedMiddlewarePath ? async (_request, _ctx, opts) => {
|
|
3483
3474
|
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() : "";
|
|
3484
3475
|
const mwOrigin = `${rawProto === "https" || rawProto === "http" ? rawProto : "http"}://${requestHost}`;
|
|
3485
|
-
const
|
|
3476
|
+
const middlewareRequestUrl = new URL(middlewareUrl, mwOrigin);
|
|
3477
|
+
if (originalUrlHadBasePath) middlewareRequestUrl.pathname = restoreBasePath(middlewareRequestUrl.pathname, bp);
|
|
3478
|
+
const middlewareRequest = new Request(middlewareRequestUrl, {
|
|
3486
3479
|
method: req.method,
|
|
3487
3480
|
headers: nodeRequestHeaders,
|
|
3488
3481
|
signal: webRequest.signal
|
|
3489
3482
|
});
|
|
3490
|
-
const result = await runMiddleware(getPagesRunner(), capturedMiddlewarePath, middlewareRequest, nextConfig?.i18n, nextConfig?.basePath, nextConfig?.trailingSlash, opts.isDataRequest, pathname, opts.isStaleDataRequest, nextConfig?.skipTrailingSlashRedirect);
|
|
3483
|
+
const result = await runMiddleware(getPagesRunner(), capturedMiddlewarePath, middlewareRequest, nextConfig?.i18n, nextConfig?.basePath, nextConfig?.trailingSlash, opts.isDataRequest, pathname, opts.isStaleDataRequest, nextConfig?.skipTrailingSlashRedirect, opts.restoreLocaleRootTrailingSlash);
|
|
3491
3484
|
if (hasAppDir && result.continue) {
|
|
3492
3485
|
const mwCtxEntries = [];
|
|
3493
3486
|
if (result.responseHeaders) {
|
|
@@ -3628,7 +3621,8 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
|
|
|
3628
3621
|
trustedRevalidateOrigin: getTrustedDevRevalidateOrigin(),
|
|
3629
3622
|
allowedRevalidateHeaderKeys: nextConfig?.allowedRevalidateHeaderKeys,
|
|
3630
3623
|
trailingSlash: nextConfig?.trailingSlash,
|
|
3631
|
-
skipTrailingSlashRedirect: nextConfig?.skipTrailingSlashRedirect
|
|
3624
|
+
skipTrailingSlashRedirect: nextConfig?.skipTrailingSlashRedirect,
|
|
3625
|
+
requestPathname: originalUrlHadBasePath ? restoreBasePath(routeUrl.split("?")[0], bp) : routeUrl.split("?")[0]
|
|
3632
3626
|
})) return;
|
|
3633
3627
|
if (hasAppDir) {
|
|
3634
3628
|
if (pipelineResult.configRewriteFired) forwardInternalApiRewriteToApp(pipelineResult.apiUrl);
|
|
@@ -4117,6 +4111,11 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
|
|
|
4117
4111
|
nitroHostRuntime = nitro.options.exportConditions?.includes("workerd") ? "worker" : "node";
|
|
4118
4112
|
if (!nextConfig) return;
|
|
4119
4113
|
if (!hasAppDir && !hasPagesDir) return;
|
|
4114
|
+
if (!nitro.options.dev) {
|
|
4115
|
+
const requestTargetPlugin = resolveRuntimeEntryModule("nitro-request-target-plugin");
|
|
4116
|
+
nitro.options.plugins ??= [];
|
|
4117
|
+
if (!nitro.options.plugins.includes(requestTargetPlugin)) nitro.options.plugins.push(requestTargetPlugin);
|
|
4118
|
+
}
|
|
4120
4119
|
nitroPublicFiles = registerNitroPublicFiles(nitro.options, NITRO_PUBLIC_FILES_PLUGIN, () => scanPublicFiles(root, nitroPublicDir));
|
|
4121
4120
|
if (resolvedServerExternalPackages.length > 0) nitro.options.traceDeps = [.../* @__PURE__ */ new Set([...nitro.options.traceDeps ?? [], ...resolvedServerExternalPackages])];
|
|
4122
4121
|
} }
|
|
@@ -4263,6 +4262,7 @@ export const loadServerActionClient = ${hasServerActions ? `() => import(${JSON.
|
|
|
4263
4262
|
pagesClientAssetsModule = buildPagesClientAssetsModule({
|
|
4264
4263
|
clientEntry: runtimeMetadata.clientEntryFile ?? void 0,
|
|
4265
4264
|
appBootstrapPreinitModules: runtimeMetadata.appBootstrapPreinitModules,
|
|
4265
|
+
appBootstrapPreloadModules: runtimeMetadata.appBootstrapPreloadModules,
|
|
4266
4266
|
appRouteManifestModule: runtimeMetadata.appRouteManifestModule,
|
|
4267
4267
|
appClientReferenceChunks: runtimeMetadata.appClientReferenceChunks,
|
|
4268
4268
|
ssrManifest,
|
package/dist/init-cloudflare.js
CHANGED
|
@@ -140,7 +140,7 @@ function setupCloudflarePlatform(context, cloudflare) {
|
|
|
140
140
|
generatedPlatformFiles.push(path.relative(context.root, responseStorePath) || RESPONSE_STORE_WRANGLER_CONFIG);
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
|
-
const nextSteps = [];
|
|
143
|
+
const nextSteps = !wranglerCode || !findTopLevelJsonProperty(wranglerCode, "main") ? workerEntryWarning(context.root, context.isStaticExport) : [];
|
|
144
144
|
if (cloudflare.cdnCache === "response-store" && (cloudflare.responseStoreMode ?? "service-binding") === "service-binding") nextSteps.push("Deploy Workers Response Store before deploying the application:", ` ${context.packageManager ?? "npm"} run deploy:response-store`);
|
|
145
145
|
if (cloudflare.prerender && cloudflare.cdnCache !== "static-assets") nextSteps.push("Pre-rendered routes are built, but Cloudflare deploys do not serve them.", " Use the Static Assets cache to serve them, or cache warming to fill another cache.");
|
|
146
146
|
return {
|
|
@@ -193,14 +193,15 @@ function setupCfPlatform(context, cloudflare) {
|
|
|
193
193
|
}
|
|
194
194
|
const configPath = path.join(context.root, "cloudflare.config.ts");
|
|
195
195
|
const generatedPlatformFiles = [];
|
|
196
|
+
const nextSteps = [];
|
|
196
197
|
if (!fs.existsSync(configPath)) {
|
|
197
198
|
fs.writeFileSync(configPath, generateTypedCloudflareConfig({
|
|
198
199
|
...projectInfo,
|
|
199
200
|
isStaticExport: context.isStaticExport
|
|
200
201
|
}, cloudflare, context.today));
|
|
201
202
|
generatedPlatformFiles.push("cloudflare.config.ts");
|
|
203
|
+
nextSteps.push(...workerEntryWarning(context.root, context.isStaticExport));
|
|
202
204
|
}
|
|
203
|
-
const nextSteps = [];
|
|
204
205
|
if (serviceBinding) nextSteps.push("After `vinext build`, deploy the Response Store Worker explicitly (and repeat when its code/config changes):", ` ${context.packageManager ?? "npm"} run deploy:response-store`, "vinext-cloudflare deploy only deploys the application Worker.");
|
|
205
206
|
if (cloudflare.prerender && cloudflare.cdnCache !== "static-assets") nextSteps.push("Pre-rendered routes are built, but Cloudflare deploys do not serve them.", " Use the Static Assets cache to serve them, or cache warming to fill another cache.");
|
|
206
207
|
nextSteps.push("For TypeScript, add \".cloudflare/types\" to the include list in tsconfig.json.", "Worker types are generated during dev/build; run `cf workers types` before standalone type-checks.");
|
|
@@ -280,6 +281,21 @@ function resolveWorkerEntry(root) {
|
|
|
280
281
|
return "vinext/server/fetch-handler";
|
|
281
282
|
}
|
|
282
283
|
/**
|
|
284
|
+
* A `worker/index.*` that never reaches vinext's handler (say, a migrated Vite
|
|
285
|
+
* SPA's API Worker) answers every page route itself, so each one 404s (#4460).
|
|
286
|
+
*/
|
|
287
|
+
function workerEntryWarning(root, isStaticExport) {
|
|
288
|
+
if (isStaticExport) return [];
|
|
289
|
+
const entry = resolveWorkerEntry(root);
|
|
290
|
+
if (entry === "vinext/server/fetch-handler") return [];
|
|
291
|
+
if (fs.readFileSync(path.join(root, entry), "utf-8").includes("vinext/server/fetch-handler")) return [];
|
|
292
|
+
return [
|
|
293
|
+
`Warning: ${entry.slice(2)} does not import vinext/server/fetch-handler. As the Worker entry`,
|
|
294
|
+
" it must hand requests to vinext, or every page 404s. Otherwise point the Worker entry",
|
|
295
|
+
" (entrypoint in cloudflare.config.ts, or main in wrangler.jsonc) at vinext/server/fetch-handler."
|
|
296
|
+
];
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
283
299
|
* Next.js runs no middleware for a static export, and an export with
|
|
284
300
|
* `trailingSlash` relies on the default html_handling to serve `/about/` from
|
|
285
301
|
* `about/index.html`, so export apps keep asset-first serving.
|
package/dist/init-platform.js
CHANGED
|
@@ -148,9 +148,9 @@ async function resolveInitOptions(args, options = {}) {
|
|
|
148
148
|
if (name && platform !== "cloudflare") throw new Error("--name requires --platform=cloudflare.");
|
|
149
149
|
const explicitPrerender = parsePrerenderArg(args);
|
|
150
150
|
if (platform === "cloudflare" && platformOptions?.cdnCache === "static-assets" && explicitPrerender === false) throw new Error("--no-prerender cannot be used with --cdn-cache=static-assets, which requires build-time prerendering.");
|
|
151
|
-
const supportsWarmCdnCache = platformOptions?.cdnCache
|
|
151
|
+
const supportsWarmCdnCache = platformOptions?.cdnCache !== void 0 && platformOptions.cdnCache !== "none";
|
|
152
152
|
if (platform === "cloudflare" && !supportsWarmCdnCache) {
|
|
153
|
-
if (explicitWarmCdnCache === true) throw new Error("--warm-cache requires --cdn-cache=response-store or
|
|
153
|
+
if (explicitWarmCdnCache === true) throw new Error("--warm-cache requires a cache: pass --cdn-cache=response-store, workers-cache, data-cache, or static-assets.");
|
|
154
154
|
}
|
|
155
155
|
const prerender = platform === "cloudflare" && platformOptions?.cdnCache === "static-assets" ? false : explicitPrerender ?? await resolveInitPrerender(args, options, platform);
|
|
156
156
|
const warmCdnCache = platform === "cloudflare" && supportsWarmCdnCache ? await resolveInitWarmCdnCache(args, options) : false;
|
package/dist/init.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import path, { toSlash } from "./deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { detectPackageManager, detectPackageManagerName, detectProject, ensureESModule, findViteConfigPath, hasViteConfig, renameCJSConfigs } from "./utils/project.js";
|
|
3
3
|
import { compactResourceName, cssModulesConfigSource, findConfigKeepingWorkerName, setupCloudflarePlatform, updateViteConfigForCssModules, usesCommonJsViteConfig, validateCloudflarePlatformSetup } from "./init-cloudflare.js";
|
|
4
|
-
import { getReactUpgradeDeps } from "./utils/react-version.js";
|
|
4
|
+
import { findPackageVersion, getReactUpgradeDeps } from "./utils/react-version.js";
|
|
5
5
|
import { getPluginReactUpgradeDeps } from "./utils/plugin-react-version.js";
|
|
6
|
+
import { createRequire } from "node:module";
|
|
6
7
|
import fs from "node:fs";
|
|
7
8
|
import { spawn, spawnSync } from "node:child_process";
|
|
8
9
|
//#region src/init.ts
|
|
@@ -297,6 +298,26 @@ function addDependencyEntries(root, deps, { dev }) {
|
|
|
297
298
|
if (added.length > 0) fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
|
298
299
|
return added;
|
|
299
300
|
}
|
|
301
|
+
/** The spec in the manifest sections `isDepInstalled` reads. */
|
|
302
|
+
function readDeclaredDependency(root, name) {
|
|
303
|
+
try {
|
|
304
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf-8"));
|
|
305
|
+
return pkg.dependencies?.[name] ?? pkg.devDependencies?.[name] ?? pkg.peerDependencies?.[name];
|
|
306
|
+
} catch {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/** The declared spec, or the installed version of a package hoisted from elsewhere. */
|
|
311
|
+
function readCurrentDependencyVersion(root, name) {
|
|
312
|
+
const declared = readDeclaredDependency(root, name);
|
|
313
|
+
if (declared !== void 0) return declared;
|
|
314
|
+
try {
|
|
315
|
+
const resolved = createRequire(path.join(root, "package.json")).resolve(name);
|
|
316
|
+
return findPackageVersion(resolved, name) ?? void 0;
|
|
317
|
+
} catch {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
300
321
|
/**
|
|
301
322
|
* Check if react/react-dom need upgrading for react-server-dom-webpack compatibility.
|
|
302
323
|
*
|
|
@@ -578,12 +599,20 @@ async function init(options) {
|
|
|
578
599
|
let dependencyInstallNeedsApproval = false;
|
|
579
600
|
const dependencyEntriesAdded = [];
|
|
580
601
|
const devDependencyEntriesAdded = [];
|
|
602
|
+
const upgradedFrom = /* @__PURE__ */ new Map();
|
|
603
|
+
const recordUpgrades = (deps) => {
|
|
604
|
+
for (const dep of deps) {
|
|
605
|
+
const { name } = parseDependencySpecifier(dep);
|
|
606
|
+
upgradedFrom.set(name, readCurrentDependencyVersion(root, name));
|
|
607
|
+
}
|
|
608
|
+
};
|
|
581
609
|
if (isApp) {
|
|
582
610
|
const reactUpgrade = shouldInstall ? [.../* @__PURE__ */ new Set([...getReactUpgradeDeps(root), ...getReactUpgradeDeps(root, {
|
|
583
611
|
fromManifest: true,
|
|
584
612
|
installing: true
|
|
585
613
|
})])] : getReactUpgradeDeps(root, { fromManifest: true });
|
|
586
614
|
if (reactUpgrade.length > 0) {
|
|
615
|
+
recordUpgrades(reactUpgrade);
|
|
587
616
|
console.log(` ${terminalStyle.cyan(terminalStyle.bold("Upgrading dependencies:"))}`);
|
|
588
617
|
console.log(formatList(reactUpgrade.map((dep) => dep.replace(/@latest$/, "")), " "));
|
|
589
618
|
try {
|
|
@@ -601,6 +630,7 @@ async function init(options) {
|
|
|
601
630
|
}
|
|
602
631
|
const pluginReactUpgrade = getPluginReactUpgradeDeps(root);
|
|
603
632
|
if (pluginReactUpgrade.length > 0) {
|
|
633
|
+
recordUpgrades(pluginReactUpgrade);
|
|
604
634
|
console.log(` ${terminalStyle.cyan(terminalStyle.bold("Upgrading devDependencies:"))}`);
|
|
605
635
|
console.log(formatList(pluginReactUpgrade.map((dep) => dep.replace(/@latest$/, "")), " "));
|
|
606
636
|
try {
|
|
@@ -654,13 +684,20 @@ async function init(options) {
|
|
|
654
684
|
if (pmName === "pnpm" && shouldInstall && !dependencyInstallNeedsApproval && !options._exec && hasAutomaticallyIgnoredBuilds(inspectPnpmIgnoredBuilds(root))) dependencyInstallNeedsApproval = true;
|
|
655
685
|
else if (pmName === "pnpm" && shouldInstall && !dependencyInstallNeedsApproval && options._inspectPnpmIgnoredBuilds && hasAutomaticallyIgnoredBuilds(options._inspectPnpmIgnoredBuilds(root))) dependencyInstallNeedsApproval = true;
|
|
656
686
|
console.log(` ${terminalStyle.green(terminalStyle.bold("vinext init complete!"))}\n`);
|
|
657
|
-
|
|
687
|
+
const addedDependencies = dependencyEntriesAdded.filter((name) => !upgradedFrom.has(name));
|
|
688
|
+
const addedDevDependencies = devDependencyEntriesAdded.filter((name) => !upgradedFrom.has(name));
|
|
689
|
+
if (addedDependencies.length > 0) {
|
|
658
690
|
console.log(` ${terminalStyle.green("✓")} Added dependencies to dependencies:`);
|
|
659
|
-
console.log(formatList(
|
|
691
|
+
console.log(formatList(addedDependencies, " "));
|
|
660
692
|
}
|
|
661
|
-
if (
|
|
693
|
+
if (addedDevDependencies.length > 0) {
|
|
662
694
|
console.log(` ${terminalStyle.green("✓")} Added dependencies to devDependencies:`);
|
|
663
|
-
console.log(formatList(
|
|
695
|
+
console.log(formatList(addedDevDependencies, " "));
|
|
696
|
+
}
|
|
697
|
+
for (const [name, from] of upgradedFrom) {
|
|
698
|
+
const to = readDeclaredDependency(root, name);
|
|
699
|
+
if (to === void 0 || to === from) continue;
|
|
700
|
+
console.log(` ${terminalStyle.green("✓")} Upgraded ${name} ${from ?? "(not installed)"} \u2192 ${to}`);
|
|
664
701
|
}
|
|
665
702
|
if (dependencyInstallNeedsApproval) console.log(` ${terminalStyle.yellow("!")} Dependency installation is waiting for build-script approval`);
|
|
666
703
|
if (addedTypeModule) console.log(` ${terminalStyle.green("✓")} Added "type": "module" to package.json`);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
//#region src/plugins/css-target.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Applies {@link DEFAULT_CSS_TARGET} only where nobody chose a target (#4413).
|
|
5
|
+
*
|
|
6
|
+
* Vite merges config by concatenating arrays, and the CSS minifier keeps the
|
|
7
|
+
* oldest version of each browser, so a pin merged onto a chosen target would
|
|
8
|
+
* stop an app from ever raising it. Instead nothing is set while config hooks
|
|
9
|
+
* run, so the app and every plugin hook see and merge plain Vite values. The
|
|
10
|
+
* post-ordered `config` and `configEnvironment` hooks only note where a target
|
|
11
|
+
* was set, and the pin is applied once config is resolved.
|
|
12
|
+
*
|
|
13
|
+
* Both the top-level `build`, which Vite's CSS plugin minifies with (a copy of
|
|
14
|
+
* the environment's in per-environment builds), and every environment's `build`
|
|
15
|
+
* are checked.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createCssTargetPlugin(): Plugin;
|
|
18
|
+
//#endregion
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
//#region src/plugins/css-target.ts
|
|
2
|
+
/**
|
|
3
|
+
* CSS minification target. Vite defaults it to the same target as JS
|
|
4
|
+
* (modern evergreens), which lets the CSS minifier (Lightning CSS by
|
|
5
|
+
* default, or esbuild) rewrite
|
|
6
|
+
* `@media (max-width: 768px)` to the Media Queries Level 4 range
|
|
7
|
+
* syntax `@media (width <= 768px)`. Both forms are semantically
|
|
8
|
+
* equivalent in modern browsers, but the rewrite is observable to
|
|
9
|
+
* user code that inspects `cssText` of `CSSMediaRule`s and breaks
|
|
10
|
+
* tools that pattern-match the raw query string. Next.js does not
|
|
11
|
+
* perform this rewrite by default (its webpack/lightningcss CSS
|
|
12
|
+
* pipeline preserves the original syntax), so user code carried
|
|
13
|
+
* over from Next.js can break when migrating to vinext.
|
|
14
|
+
*
|
|
15
|
+
* The minifier lowers a CSS feature when ANY target in the list lacks
|
|
16
|
+
* support, so we only need to pin one engine below the range-syntax
|
|
17
|
+
* baseline. Range syntax shipped in Chrome 104, Edge 104, Firefox 63,
|
|
18
|
+
* and Safari 16.4 (per esbuild's `internal/compat/css_table.go`
|
|
19
|
+
* MediaRange entry — and caniuse). Of those, Safari is the latest:
|
|
20
|
+
* pinning `safari15` (semantically Safari 15.0, which predates
|
|
21
|
+
* Safari 16.4) is sufficient to suppress the rewrite on its own.
|
|
22
|
+
*
|
|
23
|
+
* The other three targets are pinned to ~2023 baselines instead of
|
|
24
|
+
* the absolute oldest supported version so the minifier does NOT
|
|
25
|
+
* collaterally downlevel unrelated modern CSS features. With
|
|
26
|
+
* chrome111/edge111/firefox114 we keep through:
|
|
27
|
+
* - `:is()` pseudo-class (Chrome 88, Firefox 78)
|
|
28
|
+
* - `hwb()` colors (Chrome 101, Firefox 96)
|
|
29
|
+
* - `lab()`, `oklch()`, `color()` (Chrome 111, Firefox 113)
|
|
30
|
+
* - gradient interpolation hints (Chrome 111)
|
|
31
|
+
* CSS Nesting (Chrome 120, Safari 17.2) and Firefox-137 gradient
|
|
32
|
+
* interpolation will still be lowered; that is an intentional
|
|
33
|
+
* trade-off — those features are newer than the baseline and
|
|
34
|
+
* lowering them is the correct behavior for our target audience.
|
|
35
|
+
*
|
|
36
|
+
* Mirrors the Next.js fixture
|
|
37
|
+
* test/e2e/app-dir/css-media-query/css-media-query.test.ts which
|
|
38
|
+
* asserts `cssText` preserves `max-width: 768px`.
|
|
39
|
+
*/
|
|
40
|
+
const DEFAULT_CSS_TARGET = [
|
|
41
|
+
"chrome111",
|
|
42
|
+
"edge111",
|
|
43
|
+
"firefox114",
|
|
44
|
+
"safari15"
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Applies {@link DEFAULT_CSS_TARGET} only where nobody chose a target (#4413).
|
|
48
|
+
*
|
|
49
|
+
* Vite merges config by concatenating arrays, and the CSS minifier keeps the
|
|
50
|
+
* oldest version of each browser, so a pin merged onto a chosen target would
|
|
51
|
+
* stop an app from ever raising it. Instead nothing is set while config hooks
|
|
52
|
+
* run, so the app and every plugin hook see and merge plain Vite values. The
|
|
53
|
+
* post-ordered `config` and `configEnvironment` hooks only note where a target
|
|
54
|
+
* was set, and the pin is applied once config is resolved.
|
|
55
|
+
*
|
|
56
|
+
* Both the top-level `build`, which Vite's CSS plugin minifies with (a copy of
|
|
57
|
+
* the environment's in per-environment builds), and every environment's `build`
|
|
58
|
+
* are checked.
|
|
59
|
+
*/
|
|
60
|
+
function createCssTargetPlugin() {
|
|
61
|
+
let topLevelConfigured = false;
|
|
62
|
+
const configuredEnvironments = /* @__PURE__ */ new Set();
|
|
63
|
+
return {
|
|
64
|
+
name: "vinext:css-target",
|
|
65
|
+
enforce: "post",
|
|
66
|
+
config: {
|
|
67
|
+
order: "post",
|
|
68
|
+
handler(config) {
|
|
69
|
+
topLevelConfigured = config.build?.cssTarget !== void 0;
|
|
70
|
+
configuredEnvironments.clear();
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
configEnvironment: {
|
|
74
|
+
order: "post",
|
|
75
|
+
handler(name, config) {
|
|
76
|
+
if (config.build?.cssTarget !== void 0) configuredEnvironments.add(name);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
configResolved: {
|
|
80
|
+
order: "pre",
|
|
81
|
+
handler(config) {
|
|
82
|
+
pinUnsetCssTarget(config.build, topLevelConfigured);
|
|
83
|
+
for (const [name, environment] of Object.entries(config.environments)) pinUnsetCssTarget(environment.build, configuredEnvironments.has(name));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function pinUnsetCssTarget(build, configured) {
|
|
89
|
+
if (configured || build.cssTarget !== build.target) return;
|
|
90
|
+
build.cssTarget = [...DEFAULT_CSS_TARGET];
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { createCssTargetPlugin };
|
|
@@ -109,6 +109,10 @@ type ParallelSlot = {
|
|
|
109
109
|
loadingTreePositions?: number[];
|
|
110
110
|
/** Absolute path to the slot's error component */
|
|
111
111
|
errorPath: string | null;
|
|
112
|
+
/** Every error convention from the slot root to its active page, outermost first. */
|
|
113
|
+
errorPaths?: string[];
|
|
114
|
+
/** Slot-root-relative tree positions aligned with errorPaths. */
|
|
115
|
+
errorTreePositions?: number[];
|
|
112
116
|
/** Nearest not-found convention for the slot's active branch. */
|
|
113
117
|
notFoundPath?: string | null;
|
|
114
118
|
/** Tree position of that convention relative to the slot root. */
|
|
@@ -167,6 +171,12 @@ export type AppRoute = {
|
|
|
167
171
|
id: string;
|
|
168
172
|
ownerTreePath: string;
|
|
169
173
|
state: "active" | "default" | "unmatched";
|
|
174
|
+
/**
|
|
175
|
+
* Set on a sub-route minted for a slot page with no children page of its
|
|
176
|
+
* own: its children render a default, a sibling catch-all, or nothing, so
|
|
177
|
+
* its route segments don't describe them.
|
|
178
|
+
*/
|
|
179
|
+
synthetic?: true;
|
|
170
180
|
};
|
|
171
181
|
/**
|
|
172
182
|
* Interception markers not wrapped in an `@slot` directory.
|
|
@@ -594,7 +594,8 @@ function discoverSlotSubRoutes(routes, matcher, ghostParents = []) {
|
|
|
594
594
|
childrenSlot: {
|
|
595
595
|
id: childrenSlotId,
|
|
596
596
|
ownerTreePath: childrenOwnerTreePath,
|
|
597
|
-
state: childrenDefault ? "default" : childrenCatchAll ? "active" : "unmatched"
|
|
597
|
+
state: childrenDefault ? "default" : childrenCatchAll ? "active" : "unmatched",
|
|
598
|
+
synthetic: true
|
|
598
599
|
},
|
|
599
600
|
loadingPath: null,
|
|
600
601
|
loadingPaths: parentRoute.loadingPaths,
|
|
@@ -742,10 +743,22 @@ function withSlotLoadingEntries(slot, pagePath, matcher) {
|
|
|
742
743
|
...slot,
|
|
743
744
|
loadingPaths: loadingEntries.map((entry) => entry.path),
|
|
744
745
|
loadingTreePositions: loadingEntries.map((entry) => entry.treePosition),
|
|
746
|
+
...findSlotErrorFields(slot.ownerDir, pagePath, matcher),
|
|
745
747
|
...findSlotNotFoundFields(slot.ownerDir, pagePath, matcher)
|
|
746
748
|
};
|
|
747
749
|
}
|
|
748
750
|
/**
|
|
751
|
+
* Every error convention on the slot's active branch. Each catches errors in
|
|
752
|
+
* its own segment, below that segment's layout.
|
|
753
|
+
*/
|
|
754
|
+
function findSlotErrorFields(slotDir, pagePath, matcher) {
|
|
755
|
+
const entries = findSlotSegmentFileEntries(slotDir, pagePath, "error", matcher);
|
|
756
|
+
return {
|
|
757
|
+
errorPaths: entries.map((entry) => entry.path),
|
|
758
|
+
errorTreePositions: entries.map((entry) => entry.treePosition)
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
749
762
|
* Every not-found convention on the slot's active branch, plus the nearest one,
|
|
750
763
|
* which supplies the slot's not-found metadata.
|
|
751
764
|
*/
|
|
@@ -1347,6 +1360,7 @@ function discoverParallelSlots(dir, appDir, matcher, includeNestedOnlySlots = fa
|
|
|
1347
1360
|
loadingPaths: loadingEntries.map((loading) => loading.path),
|
|
1348
1361
|
loadingTreePositions: loadingEntries.map((loading) => loading.treePosition),
|
|
1349
1362
|
errorPath: findFile(slotDir, "error", matcher),
|
|
1363
|
+
...findSlotErrorFields(slotDir, pagePath, matcher),
|
|
1350
1364
|
...findSlotNotFoundFields(slotDir, pagePath, matcher),
|
|
1351
1365
|
interceptingRoutes,
|
|
1352
1366
|
layoutIndex: -1,
|