@wular/pnext 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/pnext +9 -2
- package/dist/server/_chunks/aliases-j47a10ce.js +44 -0
- package/dist/server/_chunks/analyze-arswqe6s.js +445 -0
- package/dist/server/_chunks/boot-af0mv3dy.js +36 -0
- package/dist/server/_chunks/build-spy3dxp4.js +84 -0
- package/dist/server/_chunks/build-t9h0hec3.js +3550 -0
- package/dist/server/_chunks/build-tier-m7yvqz61.js +2472 -0
- package/dist/server/_chunks/compile-53j02j27.js +22 -0
- package/dist/server/_chunks/config-1yzwexq6.js +27 -0
- package/dist/server/_chunks/config-n2z7yxps.js +22 -0
- package/dist/server/_chunks/create-meec9hs6.js +134 -0
- package/dist/server/_chunks/dev-fjmqg6en.js +220 -0
- package/dist/server/_chunks/esbuild-yyktfrtt.js +15 -0
- package/dist/server/_chunks/generate-n9sh6hzt.js +21 -0
- package/dist/server/_chunks/index-0374j2b9.js +66 -0
- package/dist/server/_chunks/index-06nyqntx.js +213 -0
- package/dist/server/_chunks/index-1011cscr.js +5263 -0
- package/dist/server/_chunks/index-11sfk4hb.js +170 -0
- package/dist/server/_chunks/index-20ppawv7.js +297 -0
- package/dist/server/_chunks/index-2dv4y4wd.js +1065 -0
- package/dist/server/_chunks/index-2vz0wzdn.js +59 -0
- package/dist/server/_chunks/index-2wfv4kvx.js +182 -0
- package/dist/server/_chunks/index-357na4a8.js +109 -0
- package/dist/server/_chunks/index-3b3at80h.js +109 -0
- package/dist/server/_chunks/index-3tf1xjsp.js +6166 -0
- package/dist/server/_chunks/index-3xbr4eyv.js +105 -0
- package/dist/server/_chunks/index-4399bvd2.js +18 -0
- package/dist/server/_chunks/index-4hgjrqh7.js +851 -0
- package/dist/server/_chunks/index-4q2gbfwk.js +2530 -0
- package/dist/server/_chunks/index-4t92hdxd.js +172 -0
- package/dist/server/_chunks/index-4zzebszd.js +10 -0
- package/dist/server/_chunks/index-5gyr4emz.js +107 -0
- package/dist/server/_chunks/index-5hr4062s.js +70 -0
- package/dist/server/_chunks/index-68m3mwbd.js +84 -0
- package/dist/server/_chunks/index-6b009mt0.js +56 -0
- package/dist/server/_chunks/index-6e4fqv30.js +588 -0
- package/dist/server/_chunks/index-6gex3pfa.js +15 -0
- package/dist/server/_chunks/index-6kp9r0d9.js +11 -0
- package/dist/server/_chunks/index-6q7zvrap.js +134 -0
- package/dist/server/_chunks/index-73z4esab.js +38 -0
- package/dist/server/_chunks/index-79ngvam8.js +60 -0
- package/dist/server/_chunks/index-7wc9n8be.js +25 -0
- package/dist/server/_chunks/index-8k7pfejn.js +1599 -0
- package/dist/server/_chunks/index-8kcxdfya.js +206 -0
- package/dist/server/_chunks/index-91x12ykq.js +274 -0
- package/dist/server/_chunks/index-9ch50vtq.js +18 -0
- package/dist/server/_chunks/index-9hx2641q.js +28 -0
- package/dist/server/_chunks/index-9n2914ww.js +535 -0
- package/dist/server/_chunks/index-9ych9ma8.js +207 -0
- package/dist/server/_chunks/index-b6wtkdp4.js +24 -0
- package/dist/server/_chunks/index-bcws5eh2.js +35 -0
- package/dist/server/_chunks/index-c0g2wf3z.js +92 -0
- package/dist/server/_chunks/index-cf4rvxv6.js +95 -0
- package/dist/server/_chunks/index-cjgqs13g.js +65 -0
- package/dist/server/_chunks/index-ckkdpht5.js +41 -0
- package/dist/server/_chunks/index-cyfednwb.js +87 -0
- package/dist/server/_chunks/index-danncfhy.js +311 -0
- package/dist/server/_chunks/index-dg0f05zs.js +199 -0
- package/dist/server/_chunks/index-e3a6yx84.js +18 -0
- package/dist/server/_chunks/index-e88tyv35.js +45 -0
- package/dist/server/_chunks/index-eajaspjk.js +1253 -0
- package/dist/server/_chunks/index-eeaanp2e.js +483 -0
- package/dist/server/_chunks/index-egykcqg3.js +101 -0
- package/dist/server/_chunks/index-en7n9f7m.js +22 -0
- package/dist/server/_chunks/index-ezgj0tr1.js +88 -0
- package/dist/server/_chunks/index-fkp000p1.js +590 -0
- package/dist/server/_chunks/index-fn1chkkd.js +214 -0
- package/dist/server/_chunks/index-fp8r0sqs.js +64 -0
- package/dist/server/_chunks/index-ggk2j965.js +9432 -0
- package/dist/server/_chunks/index-grta8ap3.js +238 -0
- package/dist/server/_chunks/index-h2a70tg4.js +7 -0
- package/dist/server/_chunks/index-h4xy648y.js +51 -0
- package/dist/server/_chunks/index-hkdfj58q.js +92 -0
- package/dist/server/_chunks/index-j2zrcp1k.js +66 -0
- package/dist/server/_chunks/index-jcsjq3d1.js +20 -0
- package/dist/server/_chunks/index-jepjvcrf.js +198 -0
- package/dist/server/_chunks/index-jks0x0a1.js +14 -0
- package/dist/server/_chunks/index-jx7bqvw1.js +57 -0
- package/dist/server/_chunks/index-k1g3epw0.js +1299 -0
- package/dist/server/_chunks/index-knp0s912.js +7 -0
- package/dist/server/_chunks/index-kq8kpzye.js +472 -0
- package/dist/server/_chunks/index-kqyy1d4f.js +50 -0
- package/dist/server/_chunks/index-kresp2n8.js +445 -0
- package/dist/server/_chunks/index-ms9v9tnx.js +31 -0
- package/dist/server/_chunks/index-n4hxpng2.js +11 -0
- package/dist/server/_chunks/index-ncnes8c6.js +17 -0
- package/dist/server/_chunks/index-nqh3xhdc.js +57 -0
- package/dist/server/_chunks/index-nyrba2kr.js +4130 -0
- package/dist/server/_chunks/index-p77b4kcx.js +296 -0
- package/dist/server/_chunks/index-pym1cezq.js +39 -0
- package/dist/server/_chunks/index-q738kkhj.js +100 -0
- package/dist/server/_chunks/index-qjj6gddn.js +54 -0
- package/dist/server/_chunks/index-qm6kmhqs.js +110 -0
- package/dist/server/_chunks/index-qn4z5s3c.js +819 -0
- package/dist/server/_chunks/index-qpwsgt3a.js +158 -0
- package/dist/server/_chunks/index-r97ptz1q.js +97 -0
- package/dist/server/_chunks/index-ras0sdab.js +26 -0
- package/dist/server/_chunks/index-rcs322t1.js +19 -0
- package/dist/server/_chunks/index-rn8dyr1f.js +126 -0
- package/dist/server/_chunks/index-rt9qq1va.js +4 -0
- package/dist/server/_chunks/index-rthrsed5.js +356 -0
- package/dist/server/_chunks/index-sctcgyvv.js +185 -0
- package/dist/server/_chunks/index-sjpckxqn.js +213 -0
- package/dist/server/_chunks/index-sq3kvz3g.js +200 -0
- package/dist/server/_chunks/index-stbk3jhn.js +31 -0
- package/dist/server/_chunks/index-sv8m6789.js +266 -0
- package/dist/server/_chunks/index-tgcakdxc.js +125 -0
- package/dist/server/_chunks/index-tgsfjmep.js +74 -0
- package/dist/server/_chunks/index-tq0pc7eg.js +154 -0
- package/dist/server/_chunks/index-tq1f96v7.js +51 -0
- package/dist/server/_chunks/index-tqn2qnnn.js +241 -0
- package/dist/server/_chunks/index-tvqkq6e6.js +128 -0
- package/dist/server/_chunks/index-v1ags1na.js +132 -0
- package/dist/server/_chunks/index-vvmmknm1.js +1431 -0
- package/dist/server/_chunks/index-vvq7rqtn.js +329 -0
- package/dist/server/_chunks/index-vz0km5qk.js +33 -0
- package/dist/server/_chunks/index-w6h8m6vp.js +138 -0
- package/dist/server/_chunks/index-web361b8.js +138 -0
- package/dist/server/_chunks/index-wpfhfbs4.js +194 -0
- package/dist/server/_chunks/index-x0y005nh.js +283 -0
- package/dist/server/_chunks/index-x3yn4ywm.js +22 -0
- package/dist/server/_chunks/index-x93hv0sc.js +271 -0
- package/dist/server/_chunks/index-xvj80c3a.js +30 -0
- package/dist/server/_chunks/index-xywjg2vc.js +100 -0
- package/dist/server/_chunks/index-y2jr2n72.js +152 -0
- package/dist/server/_chunks/index-y36a0ybw.js +57 -0
- package/dist/server/_chunks/index-ye9hmsvf.js +47 -0
- package/dist/server/_chunks/index-yhxkxghe.js +56 -0
- package/dist/server/_chunks/index-ym67zqxp.js +130 -0
- package/dist/server/_chunks/index-ytjvpbm2.js +736 -0
- package/dist/server/_chunks/index-yz54pxrh.js +960 -0
- package/dist/server/_chunks/index-z4z9zv3b.js +733 -0
- package/dist/server/_chunks/index-z84ab1w0.js +1270 -0
- package/dist/server/_chunks/index-z88qv16t.js +11 -0
- package/dist/server/_chunks/index-zqpqyg8p.js +666 -0
- package/dist/server/_chunks/loader-7yw0j98z.js +78 -0
- package/dist/server/_chunks/modules-jn8bmbn8.js +74 -0
- package/dist/server/_chunks/pipeline-yy9jhydf.js +832 -0
- package/dist/server/_chunks/production-jar9ztm3.js +44 -0
- package/dist/server/_chunks/proxy-config-j84dgksn.js +21 -0
- package/dist/server/_chunks/proxy-w1d0wmsn.js +33 -0
- package/dist/server/_chunks/router-k1reahfn.js +498 -0
- package/dist/server/_chunks/routes-2s277fc6.js +64 -0
- package/dist/server/_chunks/run-pvd8bs1t.js +696 -0
- package/dist/server/_chunks/server-mt4a994c.js +1835 -0
- package/dist/server/_chunks/tsconfig-defaults-1nb3308g.js +20 -0
- package/dist/server/_chunks/typegen-0qr0459b.js +35 -0
- package/dist/server/api/client-cache.js +14 -0
- package/dist/server/cli/index.js +378 -0
- package/dist/server/cli/start.js +137 -0
- package/dist/server/client/reference.js +16 -0
- package/dist/server/compat/next/cache.js +56 -0
- package/dist/server/compat/next/canonical-url.js +13 -0
- package/dist/server/compat/next/client-cache.js +57 -0
- package/dist/server/compat/next/client-navigation.js +232 -0
- package/dist/server/compat/next/client-only.js +1 -0
- package/dist/server/compat/next/client-script.js +178 -0
- package/dist/server/compat/next/client-server.js +34 -0
- package/dist/server/compat/next/config-headers.js +32 -0
- package/dist/server/compat/next/config-loader.js +25 -0
- package/dist/server/compat/next/config.js +10 -0
- package/dist/server/compat/next/constants.js +18 -0
- package/dist/server/compat/next/custom-server.js +10 -0
- package/dist/server/compat/next/dist/client/components/app-router-headers.js +48 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/revalidate.js +27 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-cache.js +25 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-no-store.js +25 -0
- package/dist/server/compat/next/dynamic.js +32 -0
- package/dist/server/compat/next/error.js +112 -0
- package/dist/server/compat/next/font/cache.js +14 -0
- package/dist/server/compat/next/font/google.js +3 -0
- package/dist/server/compat/next/font/index.js +1 -0
- package/dist/server/compat/next/font/local.js +22 -0
- package/dist/server/compat/next/font/runtime-client.js +33 -0
- package/dist/server/compat/next/font/runtime.js +41 -0
- package/dist/server/compat/next/font/shared.js +22 -0
- package/dist/server/compat/next/form.js +129 -0
- package/dist/server/compat/next/head.js +10 -0
- package/dist/server/compat/next/headers.js +30 -0
- package/dist/server/compat/next/image/client.js +11 -0
- package/dist/server/compat/next/image/config.js +18 -0
- package/dist/server/compat/next/image/optimizer.js +25 -0
- package/dist/server/compat/next/image/patterns.js +12 -0
- package/dist/server/compat/next/image/props.js +16 -0
- package/dist/server/compat/next/image/shared.js +86 -0
- package/dist/server/compat/next/image/static-metadata.js +32 -0
- package/dist/server/compat/next/image/validate.js +8 -0
- package/dist/server/compat/next/image.js +59 -0
- package/dist/server/compat/next/index.js +1 -0
- package/dist/server/compat/next/legacy-image.js +78 -0
- package/dist/server/compat/next/legacy-request-apis.js +24 -0
- package/dist/server/compat/next/link-transform.js +14 -0
- package/dist/server/compat/next/link.js +14 -0
- package/dist/server/compat/next/navigation.js +190 -0
- package/dist/server/compat/next/offline.js +45 -0
- package/dist/server/compat/next/og.js +8 -0
- package/dist/server/compat/next/preferred-region.js +8 -0
- package/dist/server/compat/next/redirects.js +30 -0
- package/dist/server/compat/next/resource-hints.js +30 -0
- package/dist/server/compat/next/rewrites.js +41 -0
- package/dist/server/compat/next/root-params.js +121 -0
- package/dist/server/compat/next/route-state.js +23 -0
- package/dist/server/compat/next/router.js +103 -0
- package/dist/server/compat/next/script.js +37 -0
- package/dist/server/compat/next/server-only.js +1 -0
- package/dist/server/compat/next/server.js +131 -0
- package/dist/server/compat/next/svgr.js +14 -0
- package/dist/server/compat/next/telemetry.js +10 -0
- package/dist/server/compat/next/usage.js +13 -0
- package/dist/server/compat/next/user-agent.js +12 -0
- package/dist/server/compat/next/web-vitals.js +35 -0
- package/dist/server/compat/react/action-state.js +11 -0
- package/dist/server/compat/react/client-lite.js +83 -0
- package/dist/server/compat/react/client.js +131 -0
- package/dist/server/compat/react/compiler-runtime.js +42 -0
- package/dist/server/compat/react/dom-client.js +106 -0
- package/dist/server/compat/react/dom-react-server.js +37 -0
- package/dist/server/compat/react/dom-server.js +40 -0
- package/dist/server/compat/react/dom.js +52 -0
- package/dist/server/compat/react/hooks-extra.js +12 -0
- package/dist/server/compat/react/internals.js +14 -0
- package/dist/server/compat/react/parity.js +11 -0
- package/dist/server/compat/react/preact.js +113 -0
- package/dist/server/compat/react/react-server.js +133 -0
- package/dist/server/compat/react/router-shim.js +8 -0
- package/dist/server/compat/react/server-component-use.js +14 -0
- package/dist/server/compat/react/server-inserted-html.js +14 -0
- package/dist/server/compat/react/server.js +194 -0
- package/dist/server/compat/react/style-values.js +10 -0
- package/dist/server/compat/react/use.js +10 -0
- package/dist/server/compat/react/view-transition.js +12 -0
- package/dist/server/generation.json +1 -0
- package/package.json +4 -1
- package/src/api/dynamic.tsx +2 -0
- package/src/api/server.ts +24 -6
- package/src/cli/adapters/vercel-warm.ts +315 -61
- package/src/cli/adapters/vercel.ts +348 -71
- package/src/cli/build.ts +58 -33
- package/src/cli/index.ts +23 -10
- package/src/cli/serve/entry.ts +21 -159
- package/src/cli/serve/immutable.ts +31 -0
- package/src/cli/serve/pipeline.ts +82 -84
- package/src/cli/start.ts +3 -1
- package/src/client/chunk-fold.ts +19 -6
- package/src/client/react-tier.ts +3 -2
- package/src/client/reference-stub.ts +21 -2
- package/src/compat/actions/client-plugin.ts +4 -2
- package/src/compat/actions/config.ts +6 -5
- package/src/compat/actions/extensions.ts +2 -3
- package/src/compat/aliases.ts +8 -1
- package/src/compat/bundler/config.ts +88 -0
- package/src/compat/bundler/optimize-package-imports.ts +86 -26
- package/src/compat/bundler/relay-transform.ts +15 -3
- package/src/compat/cache-control.ts +16 -8
- package/src/compat/css/modules.ts +18 -5
- package/src/compat/lifecycle/error-funnel.ts +1 -1
- package/src/compat/lifecycle/instrumentation.ts +117 -24
- package/src/compat/lifecycle/testmode.ts +3 -2
- package/src/compat/next/config-loader.ts +137 -13
- package/src/compat/next/font/runtime.ts +22 -2
- package/src/compat/next/og.ts +3 -3
- package/src/compat/next/usage.ts +3 -2
- package/src/compat/pages/api.ts +83 -14
- package/src/compat/pages/router.ts +30 -14
- package/src/compat/register/bundler.ts +3 -1
- package/src/compat/register/middleware.ts +1 -1
- package/src/compat/register/otel.ts +5 -9
- package/src/compat/register/render.ts +3 -1
- package/src/compat/register/use-cache.ts +3 -1
- package/src/compat/release.ts +46 -0
- package/src/compat/segment/serve.ts +1 -1
- package/src/compat/validation/validate.ts +10 -7
- package/src/config.ts +51 -7
- package/src/css/assets.ts +213 -0
- package/src/css/build.ts +174 -238
- package/src/dev/server.ts +27 -8
- package/src/extensions.ts +4 -0
- package/src/render/hooks.ts +13 -0
- package/src/render/renderer.ts +52 -32
- package/src/request/context.ts +9 -0
- package/src/resolve/dynamic.ts +3 -1
- package/src/resolve/imports.ts +12 -52
- package/src/resolve/package-json.ts +56 -0
- package/src/resolve/scan-facts.ts +65 -0
- package/src/routing/href.ts +10 -3
- package/src/routing/match.ts +287 -0
- package/src/routing/metadata-files.ts +19 -5
- package/src/routing/proxy-config.ts +137 -0
- package/src/routing/proxy.ts +35 -134
- package/src/routing/routes.ts +22 -281
- package/src/runtime/fingerprint.ts +23 -8
- package/src/runtime/load.ts +170 -0
- package/src/runtime/loader.ts +215 -43
- package/src/runtime/module-cache.ts +13 -0
- package/src/runtime/modules.ts +370 -81
- package/src/runtime/prebundle.ts +81 -0
- package/src/runtime/production.ts +391 -0
- package/src/runtime/release-graph.ts +334 -0
- package/src/runtime/vendor-build.ts +724 -13
- package/src/runtime/vendor.ts +16 -3
- package/src/types.ts +2 -0
- package/src/utils/fs.ts +89 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveManifest } from '../../utils/fs'
|
|
1
|
+
import { type ExactNames, exactNameIndex, hasExactName, resolveManifest } from '../../utils/fs'
|
|
2
2
|
/**
|
|
3
3
|
* The production request pipeline. Split out of `start.ts` so the prebundled
|
|
4
4
|
* server entry parses only what listening needs: this module (renderer,
|
|
@@ -14,10 +14,14 @@ import { Readable } from 'node:stream'
|
|
|
14
14
|
import { loadConfig, pathToFileHref } from '../../config'
|
|
15
15
|
import type { ResolvedConfig } from '../../config'
|
|
16
16
|
import { bootstrapCompat } from '../../compat-bootstrap'
|
|
17
|
-
import {
|
|
18
|
-
|
|
17
|
+
import {
|
|
18
|
+
importModuleOnce,
|
|
19
|
+
registerServerRuntime,
|
|
20
|
+
serverBundleTargetForRuntime,
|
|
21
|
+
} from '../../runtime/load'
|
|
19
22
|
import { abortUpstreamFetchOnDisconnect } from '../../runtime/fetch-host'
|
|
20
|
-
import { applyProxyResponse, createProxyRunner } from '../../routing/proxy'
|
|
23
|
+
import { applyProxyResponse, createProxyRunner, type ProxyRunnerOptions } from '../../routing/proxy'
|
|
24
|
+
import { attachRelease, releaseModuleHref } from '../../runtime/production'
|
|
21
25
|
import {
|
|
22
26
|
isPprShellUpgradeEligible,
|
|
23
27
|
renderGlobalNotFoundResponse,
|
|
@@ -32,15 +36,16 @@ import {
|
|
|
32
36
|
import {
|
|
33
37
|
canonicalTrailingSlashPath,
|
|
34
38
|
malformedUrlResponse,
|
|
39
|
+
repeatedSlashRedirect,
|
|
35
40
|
trailingSlashRedirect,
|
|
36
41
|
} from '../../routing/href'
|
|
37
42
|
import { type PeerAddressSource, withForwardedHeaders } from '../../routing/forwarded'
|
|
38
|
-
import { normalizePathname, parseNavState, selectRouteForRequest } from '../../routing/
|
|
43
|
+
import { normalizePathname, parseNavState, selectRouteForRequest } from '../../routing/match'
|
|
39
44
|
import { runWithCacheScope } from '../../request/cache'
|
|
40
45
|
import { metadataRouteHandlerModule } from '../../routing/metadata-files'
|
|
46
|
+
import { immutableAssetPath, immutableCacheControl } from './immutable'
|
|
41
47
|
import {
|
|
42
48
|
finalizeResponse,
|
|
43
|
-
getAssetExtensions,
|
|
44
49
|
getRenderExtensions,
|
|
45
50
|
getProxyExtensions,
|
|
46
51
|
getRequestExtensions,
|
|
@@ -55,13 +60,13 @@ import {
|
|
|
55
60
|
getWorkUnit,
|
|
56
61
|
runWithWorkUnit,
|
|
57
62
|
setPhase,
|
|
63
|
+
setWorkUnitRelease,
|
|
58
64
|
setWorkUnitRoute,
|
|
59
65
|
} from '../../request/context'
|
|
60
66
|
import { setRequestRuntime } from '../../routing/request-environment'
|
|
61
67
|
import { getRenderSpanExtensions } from '../../render/hooks'
|
|
62
|
-
import { publishEmittedAssets } from '../../css/
|
|
68
|
+
import { publishEmittedAssets } from '../../css/assets'
|
|
63
69
|
import { contentType } from '../../utils/content-type'
|
|
64
|
-
import { stopEsbuildService } from '../../utils/esbuild'
|
|
65
70
|
import { markErrorLogged } from '../../utils/error-log'
|
|
66
71
|
import type {
|
|
67
72
|
BuildManifest,
|
|
@@ -70,17 +75,6 @@ import type {
|
|
|
70
75
|
StaticFileMetadata,
|
|
71
76
|
} from '../../types'
|
|
72
77
|
|
|
73
|
-
/** Compat module-mode route hrefs are the only prod use of the dev import layer; keep it off the start graph. */
|
|
74
|
-
async function moduleHrefForRoute(
|
|
75
|
-
config: ResolvedConfig,
|
|
76
|
-
route: RouteManifestEntry,
|
|
77
|
-
): Promise<string> {
|
|
78
|
-
const { devServerModuleHref } = await import('../../runtime/modules')
|
|
79
|
-
return devServerModuleHref(config, route.file, 'build', {
|
|
80
|
-
conditionTarget: serverBundleTargetForRuntime(route.segmentConfig?.runtime),
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
78
|
/**
|
|
85
79
|
* The production request handler `pnext start` serves with. Exposed on its own
|
|
86
80
|
* so deployment adapters (e.g. Vercel) can serve the exact same pipeline
|
|
@@ -105,6 +99,22 @@ export async function createRequestHandler(
|
|
|
105
99
|
config.outPath,
|
|
106
100
|
config.root,
|
|
107
101
|
)
|
|
102
|
+
// Everything a request imports comes from the build's release; each handler resolves once, here.
|
|
103
|
+
const release = attachRelease(config)
|
|
104
|
+
release.staticMetadataFiles = manifest.staticMetadataFiles
|
|
105
|
+
const handlerHrefs = new Map(
|
|
106
|
+
manifest.routes
|
|
107
|
+
.filter(route => route.kind === 'handler')
|
|
108
|
+
.map(route => [
|
|
109
|
+
route.id,
|
|
110
|
+
releaseModuleHref(
|
|
111
|
+
release,
|
|
112
|
+
'server',
|
|
113
|
+
serverBundleTargetForRuntime(route.segmentConfig?.runtime),
|
|
114
|
+
route.file,
|
|
115
|
+
),
|
|
116
|
+
]),
|
|
117
|
+
)
|
|
108
118
|
const persistManifest = async () => {
|
|
109
119
|
const stored = JSON.parse(await readFile(manifestPath, 'utf8')) as BuildManifest
|
|
110
120
|
stored.staticFiles = manifest.staticFiles
|
|
@@ -120,6 +130,7 @@ export async function createRequestHandler(
|
|
|
120
130
|
// Content-hashed asset names, as the build emitted them: a render in THIS
|
|
121
131
|
// process must link the same files, not the logical `global.css` spelling.
|
|
122
132
|
publishEmittedAssets(config.outPath, manifest.assetNames)
|
|
133
|
+
const exactNames = exactNameIndex(config.outPath)
|
|
123
134
|
// Publish the live routing state the compat request interceptors (action
|
|
124
135
|
// dispatch, rewrites) read; prod loads the route table once.
|
|
125
136
|
setRequestRuntime({ config, routes: manifest.routes, dev: false })
|
|
@@ -127,6 +138,7 @@ export async function createRequestHandler(
|
|
|
127
138
|
compiledModuleHref: manifest.proxyModule
|
|
128
139
|
? pathToFileHref(path.resolve(config.outPath, manifest.proxyModule))
|
|
129
140
|
: undefined,
|
|
141
|
+
released: release.proxy as ProxyRunnerOptions['released'],
|
|
130
142
|
})
|
|
131
143
|
const routesById = new Map(manifest.routes.map(route => [route.id, route]))
|
|
132
144
|
const nextCompat = Boolean(config.compat?.next)
|
|
@@ -149,6 +161,7 @@ export async function createRequestHandler(
|
|
|
149
161
|
const route = routesById.get(metadata.routeId)
|
|
150
162
|
if (!route) return
|
|
151
163
|
await runWithWorkUnit('render', async () => {
|
|
164
|
+
setWorkUnitRelease(release)
|
|
152
165
|
const url = new URL(`http://pnext.local${pathname}`)
|
|
153
166
|
const params = routeParamsFromPath(route, pathname)
|
|
154
167
|
const fetchCache = route.segmentConfig?.fetchCache
|
|
@@ -156,11 +169,10 @@ export async function createRequestHandler(
|
|
|
156
169
|
if (route.kind === 'handler') {
|
|
157
170
|
setWorkUnitRoute('route-handler', 'isr', { revalidateReason: reason })
|
|
158
171
|
setPhase('handler')
|
|
159
|
-
registerServerRuntime(config, route.sourceFiles)
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const module = await importModuleOnce<Parameters<typeof handleRouteModule>[0]>(href)
|
|
172
|
+
await registerServerRuntime(config, route.sourceFiles)
|
|
173
|
+
const module = await importModuleOnce<Parameters<typeof handleRouteModule>[0]>(
|
|
174
|
+
handlerHrefs.get(route.id)!,
|
|
175
|
+
)
|
|
164
176
|
const rendered = await getRenderExtensions().collectRenderMeta(
|
|
165
177
|
() =>
|
|
166
178
|
withRouteRuntime(route.segmentConfig?.runtime, () =>
|
|
@@ -255,7 +267,13 @@ export async function createRequestHandler(
|
|
|
255
267
|
|
|
256
268
|
setRequestExtensions({
|
|
257
269
|
onDemandRevalidatePath: async pathname => {
|
|
258
|
-
const built = await builtFileInfo(
|
|
270
|
+
const built = await builtFileInfo(
|
|
271
|
+
config.outPath,
|
|
272
|
+
pathname,
|
|
273
|
+
manifest.staticFiles,
|
|
274
|
+
false,
|
|
275
|
+
exactNames,
|
|
276
|
+
)
|
|
259
277
|
if (!built?.metadata) return
|
|
260
278
|
await runRegeneration(pathname, built.file, built.relative, built.metadata, 'on-demand')
|
|
261
279
|
},
|
|
@@ -269,6 +287,8 @@ export async function createRequestHandler(
|
|
|
269
287
|
request.method,
|
|
270
288
|
request.headers,
|
|
271
289
|
nextCompat,
|
|
290
|
+
manifest.publicAssets,
|
|
291
|
+
exactNames,
|
|
272
292
|
)
|
|
273
293
|
if (built) {
|
|
274
294
|
setWorkUnitRoute('html', 'static')
|
|
@@ -293,15 +313,13 @@ export async function createRequestHandler(
|
|
|
293
313
|
)
|
|
294
314
|
}
|
|
295
315
|
|
|
296
|
-
// The boot config compile is the only build work a prod server does; drop the
|
|
297
|
-
// resident esbuild service child (~10+ MB RSS) — it respawns if ever needed.
|
|
298
|
-
stopEsbuildService()
|
|
299
|
-
|
|
300
316
|
return function handleRequest(request: Request, server?: PeerAddressSource): Promise<Response> {
|
|
301
317
|
// One work unit spans the whole request; its after-queue flushes once the
|
|
302
318
|
// response fully closes (stream end, redirect, notFound, error, abort).
|
|
303
319
|
return runWithWorkUnit('render', async () => {
|
|
304
320
|
const unit = getWorkUnit()
|
|
321
|
+
// Every request is work of this release: app-directory facts come from it, never the disk.
|
|
322
|
+
setWorkUnitRelease(release)
|
|
305
323
|
try {
|
|
306
324
|
const raw = await handle(request, server)
|
|
307
325
|
const finalized = await finalizeResponse(
|
|
@@ -343,6 +361,8 @@ export async function createRequestHandler(
|
|
|
343
361
|
if (badRequest) return badRequest
|
|
344
362
|
request = withForwardedHeaders(request, server)
|
|
345
363
|
const requestedUrl = new URL(request.url)
|
|
364
|
+
const slashRedirect = repeatedSlashRedirect(requestedUrl)
|
|
365
|
+
if (slashRedirect) return slashRedirect
|
|
346
366
|
// assetPrefix is independent from basePath. Strip a path-style asset
|
|
347
367
|
// prefix first so `/cdn/_next/static/*` remains servable even when the app
|
|
348
368
|
// itself lives under a different basePath.
|
|
@@ -383,6 +403,11 @@ export async function createRequestHandler(
|
|
|
383
403
|
const revalidateBypass = Boolean(
|
|
384
404
|
bypassToken && request.headers.get('x-prerender-revalidate') === bypassToken,
|
|
385
405
|
)
|
|
406
|
+
// Trailing-slash normalization applies to the browser-visible (as-requested)
|
|
407
|
+
// URL, never to an internal rewrite destination, and precedes the proxy for
|
|
408
|
+
// every method as in Next: the proxy only ever sees canonical paths.
|
|
409
|
+
const canonicalRedirect = trailingSlashRedirect(config, requestedUrl)
|
|
410
|
+
if (canonicalRedirect) return canonicalRedirect
|
|
386
411
|
const canonicalUrl = new URL(request.url)
|
|
387
412
|
const canonicalHeaders = request.headers
|
|
388
413
|
let proxyResponse: Response | undefined
|
|
@@ -427,11 +452,6 @@ export async function createRequestHandler(
|
|
|
427
452
|
: new Request(canonicalRequestUrl, { headers: canonicalHeaders })
|
|
428
453
|
|
|
429
454
|
const method = request.method.toUpperCase()
|
|
430
|
-
// Trailing-slash normalization applies to the browser-visible (as-requested)
|
|
431
|
-
// URL, never to an internal rewrite destination. A middleware/next.config
|
|
432
|
-
// rewrite to `/en/` must render internally, not 308 the visitor to `/en`.
|
|
433
|
-
const canonicalRedirect = trailingSlashRedirect(config, requestedUrl, method)
|
|
434
|
-
if (canonicalRedirect) return applyProxyResponse(canonicalRedirect, proxyResponse)
|
|
435
455
|
// Soft navigations carry the client's parallel-route state; when the
|
|
436
456
|
// target involves slots, interception, or a host render, the response is
|
|
437
457
|
// state-dependent and must render dynamically (never from prebuilt html).
|
|
@@ -461,7 +481,13 @@ export async function createRequestHandler(
|
|
|
461
481
|
// rewrites it.
|
|
462
482
|
const built =
|
|
463
483
|
method === 'GET' || method === 'HEAD'
|
|
464
|
-
? await builtFileInfo(
|
|
484
|
+
? await builtFileInfo(
|
|
485
|
+
config.outPath,
|
|
486
|
+
url.pathname,
|
|
487
|
+
manifest.staticFiles,
|
|
488
|
+
nextCompat,
|
|
489
|
+
exactNames,
|
|
490
|
+
)
|
|
465
491
|
: null
|
|
466
492
|
const hardStaticStale =
|
|
467
493
|
built !== null &&
|
|
@@ -526,6 +552,8 @@ export async function createRequestHandler(
|
|
|
526
552
|
request.method,
|
|
527
553
|
request.headers,
|
|
528
554
|
nextCompat,
|
|
555
|
+
manifest.publicAssets,
|
|
556
|
+
exactNames,
|
|
529
557
|
)
|
|
530
558
|
if (staticFile && !(draftBypass && isHtmlResponse(staticFile))) {
|
|
531
559
|
const staticMode = servedBuilt.metadata?.revalidateSeconds !== undefined ? 'isr' : 'static'
|
|
@@ -594,7 +622,14 @@ export async function createRequestHandler(
|
|
|
594
622
|
// isOnDemandRevalidate semantics) and persist the fresh bytes so
|
|
595
623
|
// subsequent requests serve the regenerated static copy again.
|
|
596
624
|
const renderedHandler = await getRenderExtensions().collectRenderMeta(
|
|
597
|
-
() =>
|
|
625
|
+
() =>
|
|
626
|
+
handleRoute(
|
|
627
|
+
config,
|
|
628
|
+
matched.route,
|
|
629
|
+
handlerHrefs.get(matched.route.id)!,
|
|
630
|
+
canonicalRequest,
|
|
631
|
+
matched.params,
|
|
632
|
+
),
|
|
598
633
|
{
|
|
599
634
|
fetchCache: matched.route.segmentConfig?.fetchCache,
|
|
600
635
|
refreshFetches: staleOnDemand,
|
|
@@ -971,34 +1006,20 @@ function maybeCloseNodeFetchConnection(response: Response, request: Request) {
|
|
|
971
1006
|
return response
|
|
972
1007
|
}
|
|
973
1008
|
|
|
974
|
-
// Compat mode gate (a pure read of config.compat, no compat import): under
|
|
975
|
-
// compat the compiled module is loaded so bare next/* / react aliases resolve
|
|
976
|
-
// to the compat layer. Mirrors compat/aliases.ts reactCompatEnabled — kept inline
|
|
977
|
-
// so start.ts carries no static edge into compat.
|
|
978
|
-
function compatModuleMode(config: Awaited<ReturnType<typeof loadConfig>>): boolean {
|
|
979
|
-
return Boolean(config.compat?.next || config.compat?.react || config.compat?.reactCompiler)
|
|
980
|
-
}
|
|
981
|
-
|
|
982
1009
|
async function handleRoute(
|
|
983
1010
|
config: Awaited<ReturnType<typeof loadConfig>>,
|
|
984
1011
|
route: RouteManifestEntry,
|
|
1012
|
+
href: string,
|
|
985
1013
|
request: Request,
|
|
986
1014
|
params: Record<string, RouteParamValue>,
|
|
987
1015
|
) {
|
|
988
1016
|
return withRouteRuntime(route.segmentConfig?.runtime, async () => {
|
|
989
|
-
registerServerRuntime(config, route.sourceFiles)
|
|
1017
|
+
await registerServerRuntime(config, route.sourceFiles)
|
|
990
1018
|
// Module resolution and handler invocation run through the render-span seam
|
|
991
1019
|
// (compat/otel emits `resolve page components` + `executing api route`;
|
|
992
1020
|
// pass-through for pure-core apps).
|
|
993
1021
|
const spans = getRenderSpanExtensions()
|
|
994
1022
|
const module = await spans.withFindPageComponentsSpan(route.route, async () => {
|
|
995
|
-
// Compat mode loads the compiled module (aliases baked in): a raw import
|
|
996
|
-
// would resolve bare next/* specifiers (next/headers etc.) against whatever
|
|
997
|
-
// next package is installed instead of the compat layer — Bun's runtime
|
|
998
|
-
// onResolve plugin cannot alias bare imports. Same pattern as pageRender.
|
|
999
|
-
const href = compatModuleMode(config)
|
|
1000
|
-
? await moduleHrefForRoute(config, route)
|
|
1001
|
-
: new URL(`file://${route.file}`).href
|
|
1002
1023
|
const imported = await importModuleOnce<
|
|
1003
1024
|
RouteHandlerModule & Parameters<typeof metadataRouteHandlerModule>[0]
|
|
1004
1025
|
>(href)
|
|
@@ -1067,10 +1088,12 @@ async function builtFileInfo(
|
|
|
1067
1088
|
pathname: string,
|
|
1068
1089
|
staticFiles: Record<string, StaticFileMetadata> = {},
|
|
1069
1090
|
nextStaticFallback = false,
|
|
1091
|
+
exactNames?: ExactNames,
|
|
1070
1092
|
): Promise<BuiltFileInfo | null> {
|
|
1071
1093
|
const file = await firstFile(
|
|
1072
1094
|
path.join(outPath, 'public'),
|
|
1073
1095
|
builtFileCandidates(outPath, pathname, nextStaticFallback),
|
|
1096
|
+
exactNames,
|
|
1074
1097
|
)
|
|
1075
1098
|
if (!file) return null
|
|
1076
1099
|
const publicPath = path.join(outPath, 'public')
|
|
@@ -1195,6 +1218,8 @@ export async function maybeBuiltFile(
|
|
|
1195
1218
|
method = 'GET',
|
|
1196
1219
|
requestHeaders?: Headers,
|
|
1197
1220
|
nextStaticFallback = false,
|
|
1221
|
+
publicAssets: string[] = [],
|
|
1222
|
+
exactNames?: ExactNames,
|
|
1198
1223
|
) {
|
|
1199
1224
|
const normalizedMethod = method.toUpperCase()
|
|
1200
1225
|
if (normalizedMethod !== 'GET' && normalizedMethod !== 'HEAD') return null
|
|
@@ -1203,6 +1228,7 @@ export async function maybeBuiltFile(
|
|
|
1203
1228
|
const file = await firstFile(
|
|
1204
1229
|
publicPath,
|
|
1205
1230
|
builtFileCandidates(outPath, pathname, nextStaticFallback),
|
|
1231
|
+
exactNames,
|
|
1206
1232
|
)
|
|
1207
1233
|
if (!file) return null
|
|
1208
1234
|
const relative = path.relative(publicPath, file).split(path.sep).join('/')
|
|
@@ -1219,7 +1245,8 @@ export async function maybeBuiltFile(
|
|
|
1219
1245
|
const variant = requestHeaders?.get('rsc') === '1' ? '-rsc' : ''
|
|
1220
1246
|
const etag = `W/"${fileStat.size.toString(16)}-${Math.trunc(fileStat.mtimeMs).toString(16)}${variant}"`
|
|
1221
1247
|
if (!headers.has('cache-control')) {
|
|
1222
|
-
|
|
1248
|
+
const immutable = immutableAssetPath(relative) && !publicAssets.includes(relative)
|
|
1249
|
+
headers.set('cache-control', immutable ? immutableCacheControl : 'no-cache')
|
|
1223
1250
|
headers.set('etag', etag)
|
|
1224
1251
|
if (requestHeaders?.get('if-none-match') === etag) {
|
|
1225
1252
|
return new Response(null, { status: 304, headers })
|
|
@@ -1344,40 +1371,11 @@ function cachedGzip(key: string, body: Buffer) {
|
|
|
1344
1371
|
return zipped
|
|
1345
1372
|
}
|
|
1346
1373
|
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
/**
|
|
1350
|
-
* Everything the build emits under `assets/` (served at `/_next/static/*` in
|
|
1351
|
-
* compat) is immutable, which is the promise Next makes for that whole
|
|
1352
|
-
* namespace. It holds because every one of those names carries a content hash:
|
|
1353
|
-
* esbuild's for chunks and fonts, assetContentHash for the route entries and the
|
|
1354
|
-
* stylesheets (see fingerprintClientEntries / fingerprintAsset), and a build id
|
|
1355
|
-
* for `_next/static/<id>/_*Manifest.js`. An UNHASHED name must never reach here —
|
|
1356
|
-
* the same URL would answer different bytes after a deploy, and every browser
|
|
1357
|
-
* that saw the old ones would keep them for a year.
|
|
1358
|
-
*
|
|
1359
|
-
* Route outputs (prerendered html, handler bodies) live outside both prefixes
|
|
1360
|
-
* and stay revalidating; the public/ tree the app ships is likewise untouched.
|
|
1361
|
-
*/
|
|
1362
|
-
export function immutableAssetPath(relativePath: string) {
|
|
1363
|
-
return immutableAssetPrefixes().some(prefix => relativePath.startsWith(prefix))
|
|
1364
|
-
}
|
|
1365
|
-
|
|
1366
|
-
/** The public-relative prefixes `immutableAssetPath` covers. */
|
|
1367
|
-
export function immutableAssetPrefixes() {
|
|
1368
|
-
return [
|
|
1369
|
-
'assets/',
|
|
1370
|
-
'_next/static/',
|
|
1371
|
-
...getAssetExtensions()
|
|
1372
|
-
.staticAssetPublicPrefixes()
|
|
1373
|
-
.map(prefix => prefix.replace(/^\/+/, '')),
|
|
1374
|
-
]
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
async function firstFile(root: string, files: string[]) {
|
|
1374
|
+
async function firstFile(root: string, files: string[], exactNames?: ExactNames) {
|
|
1378
1375
|
for (const file of files) {
|
|
1379
1376
|
if (!isInside(root, file)) continue
|
|
1380
1377
|
if (!existsSync(file)) continue
|
|
1378
|
+
if (exactNames && !hasExactName(exactNames, root, path.relative(root, file))) continue
|
|
1381
1379
|
if ((await stat(file)).isFile()) return file
|
|
1382
1380
|
}
|
|
1383
1381
|
return null
|
package/src/cli/start.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* `pnext start`: the listen path only. Everything a request needs — renderer,
|
|
3
3
|
* routing, server runtime — lives in `./serve/pipeline` and is imported
|
|
4
4
|
* dynamically once the port is bound, so neither the listen syscall nor the
|
|
5
|
-
* ready banner waits on parsing it
|
|
5
|
+
* ready banner waits on parsing it.
|
|
6
6
|
*/
|
|
7
7
|
import { readFile } from 'node:fs/promises'
|
|
8
8
|
import path from 'node:path'
|
|
@@ -13,6 +13,7 @@ import { getBuildExtensions } from '../extensions'
|
|
|
13
13
|
import { drainWorkUnits } from '../request/context'
|
|
14
14
|
import { markErrorLogged } from '../utils/error-log'
|
|
15
15
|
import { isPostpone } from '../render/postpone'
|
|
16
|
+
import { registerPrebundleResolve } from '../runtime/prebundle'
|
|
16
17
|
import { browserHost, ensurePortFree, openBrowser, printServerReady } from './serve/ui'
|
|
17
18
|
import type { BuildManifest } from '../types'
|
|
18
19
|
import type { PeerAddressSource } from '../routing/forwarded'
|
|
@@ -33,6 +34,7 @@ type RequestHandler = (request: Request, server?: PeerAddressSource) => Promise<
|
|
|
33
34
|
export async function createRequestHandler(
|
|
34
35
|
options: { root?: string; config?: ResolvedConfig; manifest?: BuildManifest } = {},
|
|
35
36
|
): Promise<RequestHandler> {
|
|
37
|
+
registerPrebundleResolve()
|
|
36
38
|
const { createRequestHandler: create } = await import('./serve/pipeline')
|
|
37
39
|
return create(options)
|
|
38
40
|
}
|
package/src/client/chunk-fold.ts
CHANGED
|
@@ -91,8 +91,15 @@ async function foldGroup(
|
|
|
91
91
|
const memberNames = members.map(output => path.basename(output))
|
|
92
92
|
if (memberNames.some(name => !existsSync(path.join(chunksDir, name)))) return metafile
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
// The state holds every output's current text, in step with what earlier groups wrote.
|
|
95
|
+
const sources = new Map(
|
|
96
|
+
await Promise.all(
|
|
97
|
+
memberNames.map(async name => {
|
|
98
|
+
const file = path.join(chunksDir, name)
|
|
99
|
+
return [name, state.outputs.get(file)?.text ?? (await readText(file))] as const
|
|
100
|
+
}),
|
|
101
|
+
),
|
|
102
|
+
)
|
|
96
103
|
|
|
97
104
|
const aliases = memberAliases(memberNames, sources)
|
|
98
105
|
if (!aliases) return metafile
|
|
@@ -503,14 +510,20 @@ async function createFoldState(outDir: string, metafile: Metafile): Promise<Fold
|
|
|
503
510
|
}
|
|
504
511
|
}
|
|
505
512
|
|
|
513
|
+
const files = new Set<string>()
|
|
506
514
|
for (const name of Object.keys(metafile.outputs)) {
|
|
507
515
|
if (!name.endsWith('.js')) continue
|
|
508
516
|
const resolved = path.resolve(name)
|
|
509
517
|
const local = existsSync(resolved) ? resolved : path.join(outDir, path.basename(name))
|
|
510
|
-
if (
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
518
|
+
if (existsSync(local)) files.add(local)
|
|
519
|
+
}
|
|
520
|
+
// Read concurrently, indexed in metafile order.
|
|
521
|
+
const list = [...files]
|
|
522
|
+
const texts = await Promise.all(list.map(file => readText(file)))
|
|
523
|
+
for (const [at, file] of list.entries()) {
|
|
524
|
+
const output = foldOutput(texts[at]!)
|
|
525
|
+
outputs.set(file, output)
|
|
526
|
+
index(file, output, true)
|
|
514
527
|
}
|
|
515
528
|
|
|
516
529
|
return {
|
package/src/client/react-tier.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { existsSync,
|
|
1
|
+
import { existsSync, statSync } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
|
+
import { readSourceSync } from '../resolve/source-text'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Conservative static scan of a compat app's client graph deciding whether the client bundle can ship
|
|
@@ -87,7 +88,7 @@ export function clientSuspenseFree(seeds: Iterable<string>): boolean {
|
|
|
87
88
|
if (!SOURCE_EXTENSION.test(file) || !existsSync(file)) return false
|
|
88
89
|
let source: string
|
|
89
90
|
try {
|
|
90
|
-
source =
|
|
91
|
+
source = readSourceSync(file)
|
|
91
92
|
} catch {
|
|
92
93
|
return false
|
|
93
94
|
}
|
|
@@ -22,6 +22,12 @@ export interface ClientReferenceModuleOptions {
|
|
|
22
22
|
* inlined lookup is the same symbol the renderer tests for.
|
|
23
23
|
*/
|
|
24
24
|
inlineSymbol?: boolean
|
|
25
|
+
/**
|
|
26
|
+
* For a release: the reference names its source relative to the stub (`from`), at `target` - the
|
|
27
|
+
* source itself, or its path through the app's node_modules (`real`: resolved to the installed file).
|
|
28
|
+
* A moved build then still identifies the module its release indexed.
|
|
29
|
+
*/
|
|
30
|
+
portable?: { from: string; target: string; real: boolean }
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
export function clientReferenceModuleSource(
|
|
@@ -29,8 +35,17 @@ export function clientReferenceModuleSource(
|
|
|
29
35
|
exportNames: string[],
|
|
30
36
|
options: ClientReferenceModuleOptions = {},
|
|
31
37
|
) {
|
|
38
|
+
const portable = options.portable
|
|
39
|
+
const located = portable
|
|
40
|
+
? `decodeURIComponent(new URL(${JSON.stringify(path.relative(path.dirname(portable.from), portable.target).split(path.sep).join('/'))}, import.meta.url).pathname)`
|
|
41
|
+
: undefined
|
|
42
|
+
const file = !located
|
|
43
|
+
? JSON.stringify(sourceFile)
|
|
44
|
+
: portable?.real
|
|
45
|
+
? `__pnextRealpath(${located})`
|
|
46
|
+
: located
|
|
32
47
|
const reference = (exportName: string) =>
|
|
33
|
-
`createReference({ id: ${JSON.stringify(`c-${clientReferenceId(sourceFile, exportName)}`)}, file: ${
|
|
48
|
+
`createReference({ id: ${JSON.stringify(`c-${clientReferenceId(sourceFile, exportName)}`)}, file: ${file}, exportName: ${JSON.stringify(exportName)} })`
|
|
34
49
|
const defaultExport = exportNames.includes('default')
|
|
35
50
|
? `export default ${reference('default')};`
|
|
36
51
|
: ''
|
|
@@ -41,7 +56,11 @@ export function clientReferenceModuleSource(
|
|
|
41
56
|
? `const clientReferenceSymbol = Symbol.for('pnext.clientReference');`
|
|
42
57
|
: `import { clientReferenceSymbol } from ${JSON.stringify(pathToFileHref(clientReferenceRuntimeFile))};`
|
|
43
58
|
|
|
44
|
-
|
|
59
|
+
const realpath = portable?.real
|
|
60
|
+
? `import { realpathSync as __pnextRealpath } from 'node:fs';\n`
|
|
61
|
+
: ''
|
|
62
|
+
|
|
63
|
+
return `${realpath}${symbol}
|
|
45
64
|
|
|
46
65
|
function createReference(reference) {
|
|
47
66
|
function ClientReference({ children }) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
2
|
import { realpathSync } from 'node:fs'
|
|
3
3
|
import type { Plugin } from 'esbuild'
|
|
4
|
-
import { readText } from '../../utils/fs'
|
|
4
|
+
import { readText, toPosixPath } from '../../utils/fs'
|
|
5
5
|
import { escapeRegex } from '../../utils/code'
|
|
6
6
|
import { actionId } from './ids'
|
|
7
7
|
import { moduleActionExports, moduleLevelUseCache, moduleLevelUseServer } from './detect'
|
|
@@ -125,7 +125,9 @@ export function stubSourceFromSource(file: string, source: string, root?: string
|
|
|
125
125
|
const exports = moduleActionExports(source)
|
|
126
126
|
const actionIds: Record<string, string> = {}
|
|
127
127
|
for (const name of exports) actionIds[name] = canonicalActionId(file, name, root)
|
|
128
|
-
|
|
128
|
+
// Root-relative: the stub ships in client bundles and release artifacts.
|
|
129
|
+
const modulePath = root ? toPosixPath(path.relative(root, file)) : file
|
|
130
|
+
return clientStubSource({ modulePath, exports, actionIds })
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
export async function loadClientActionSource(file: string, root?: string) {
|
|
@@ -3,6 +3,7 @@ import { createRequire } from 'node:module'
|
|
|
3
3
|
import path from 'node:path'
|
|
4
4
|
import { pathToFileHref } from '../../config'
|
|
5
5
|
import { DEFAULT_BODY_LIMIT_BYTES } from './endpoint'
|
|
6
|
+
import { getNextConfig, nextConfigReleased } from '../next/config-loader'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Server-actions options read from the app's next.config in compat mode:
|
|
@@ -39,7 +40,7 @@ export async function loadServerActionsConfig(root: string): Promise<ServerActio
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
export async function loadResolvedNextConfig(root: string): Promise<NextConfigShape | undefined> {
|
|
42
|
-
return
|
|
43
|
+
return loadNextConfigFromStore() ?? (await loadNextConfig(root))
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
/**
|
|
@@ -50,9 +51,8 @@ export async function loadResolvedNextConfig(root: string): Promise<NextConfigSh
|
|
|
50
51
|
* silently dropped the configured bodySizeLimit. Returns undefined when the store is empty so the
|
|
51
52
|
* caller falls back to a direct file read.
|
|
52
53
|
*/
|
|
53
|
-
|
|
54
|
+
function loadNextConfigFromStore(): NextConfigShape | undefined {
|
|
54
55
|
try {
|
|
55
|
-
const { getNextConfig } = await import('../next/config-loader')
|
|
56
56
|
const store: NextConfigShape = getNextConfig()
|
|
57
57
|
return store && Object.keys(store).length > 0 ? store : undefined
|
|
58
58
|
} catch {
|
|
@@ -61,6 +61,7 @@ async function loadNextConfigFromStore(): Promise<NextConfigShape | undefined> {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export async function loadNextConfig(root: string): Promise<NextConfigShape | undefined> {
|
|
64
|
+
if (nextConfigReleased()) return getNextConfig()
|
|
64
65
|
for (const name of ['next.config.js', 'next.config.mjs', 'next.config.cjs']) {
|
|
65
66
|
const file = path.join(root, name)
|
|
66
67
|
if (!existsSync(file)) continue
|
|
@@ -109,9 +110,9 @@ export async function loadNextConfig(root: string): Promise<NextConfigShape | un
|
|
|
109
110
|
* skipped here - the lazy per-request path still validates.
|
|
110
111
|
*/
|
|
111
112
|
export function validateServerActionsConfigSync(root: string): void {
|
|
112
|
-
let config: NextConfigShape | undefined
|
|
113
|
+
let config: NextConfigShape | undefined = nextConfigReleased() ? getNextConfig() : undefined
|
|
113
114
|
const requireFrom = createRequire(path.join(root, 'noop.js'))
|
|
114
|
-
for (const name of ['next.config.js', 'next.config.cjs']) {
|
|
115
|
+
for (const name of config ? [] : ['next.config.js', 'next.config.cjs']) {
|
|
115
116
|
const file = path.join(root, name)
|
|
116
117
|
if (!existsSync(file)) continue
|
|
117
118
|
try {
|
|
@@ -21,8 +21,7 @@ import {
|
|
|
21
21
|
import { getRequestRuntime, type RequestRuntime } from '../../routing/request-environment'
|
|
22
22
|
import { toPosixPath } from '../../utils/fs'
|
|
23
23
|
import type { ActionManifestEntry, BuildManifest, RouteManifestEntry } from '../../types'
|
|
24
|
-
import { devServerModuleHref } from '../../runtime/
|
|
25
|
-
import { serverBundleTargetForRuntime } from '../../runtime/loader'
|
|
24
|
+
import { devServerModuleHref, serverBundleTargetForRuntime } from '../../runtime/load'
|
|
26
25
|
import {
|
|
27
26
|
renderActionReturnElement,
|
|
28
27
|
renderGlobalNotFoundResponse,
|
|
@@ -31,7 +30,7 @@ import {
|
|
|
31
30
|
renderPageResponse,
|
|
32
31
|
} from '../../render/renderer'
|
|
33
32
|
import { routeParamsFromPath } from '../../routing/handler'
|
|
34
|
-
import { selectRouteForRequest } from '../../routing/
|
|
33
|
+
import { selectRouteForRequest } from '../../routing/match'
|
|
35
34
|
import { discoverActions, registerDiscoveredActions } from './discovery'
|
|
36
35
|
import { clearActions, lookupActionSource, registerActionModule } from './registry'
|
|
37
36
|
import {
|
package/src/compat/aliases.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
+
import { isReleaseCompile } from '../runtime/load'
|
|
3
|
+
import { toPosixPath } from '../utils/fs'
|
|
2
4
|
import { createRequire } from 'node:module'
|
|
3
5
|
import type { Plugin } from 'esbuild'
|
|
4
6
|
import { frameworkRuntimeAliasEntries, pnextAliases, type CompatAliasTarget } from '../config'
|
|
@@ -329,7 +331,12 @@ export function rewriteNextFontSource(
|
|
|
329
331
|
let next = rewriteNextGoogleFontImports(source, runtimePath)
|
|
330
332
|
const localFontNames = nextLocalFontImportNames(next)
|
|
331
333
|
if (localFontNames.size === 0) return next
|
|
332
|
-
|
|
334
|
+
// A release names the caller root-relative, so its font identity survives moving the build.
|
|
335
|
+
const absoluteCaller = localFontCallerFile(file, root)
|
|
336
|
+
const callerFile =
|
|
337
|
+
isReleaseCompile() && root && path.isAbsolute(absoluteCaller)
|
|
338
|
+
? toPosixPath(path.relative(root, absoluteCaller))
|
|
339
|
+
: absoluteCaller
|
|
333
340
|
// Rewrite each `NAME(...)` call to `NAME.withFile(<file>)(...)` so the runtime
|
|
334
341
|
// gets the caller path (for `src` resolution + a stable per-caller hash). The
|
|
335
342
|
// client runtime only uses `callerFile` for the hash (which must match the
|