@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
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// lazy-static MISS responses. Emitting it for pure static HITs needs the route's cacheLife persisted in
|
|
15
15
|
// the build manifest and read by the static-serve path in src/cli/start.ts.
|
|
16
16
|
|
|
17
|
+
import { productionRelease } from '../../runtime/production'
|
|
17
18
|
import type { ResolvedConfig } from '../../config'
|
|
18
19
|
import { nextCompatEnabled } from '../../compat/aliases'
|
|
19
20
|
import {
|
|
@@ -84,7 +85,8 @@ export function registerUseCacheExtensions(config: ResolvedConfig): void {
|
|
|
84
85
|
// Seed the root-param NAME set for cache-key participation (Stage B-3): a
|
|
85
86
|
// `use cache` entry's conservative first-call key may only discriminate by
|
|
86
87
|
// root params, so the runtime needs the scanned names at build AND serve.
|
|
87
|
-
|
|
88
|
+
const released = productionRelease(config)?.compat?.rootParams
|
|
89
|
+
setUseCacheRootParamNames(released ? new Set(released) : scanRootParams(config.appPath))
|
|
88
90
|
|
|
89
91
|
// Arm `use cache` build-time validation for this build's prerender pass.
|
|
90
92
|
// Registered as a build STEP so it runs before any page is prerendered; the
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Compat facts a production release carries (COMPAT): compiled next.config, cache handlers and
|
|
2
|
+
// instrumentation, plus the app facts compat would otherwise rescan from source at boot.
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import type { ResolvedConfig } from '../config'
|
|
5
|
+
import type { CompatRelease } from '../runtime/production'
|
|
6
|
+
import { pagesRevalidateFacts } from './cache-control'
|
|
7
|
+
import { emitReleaseInstrumentation } from './lifecycle/instrumentation'
|
|
8
|
+
import { emitNextConfigBundle } from './next/config-loader'
|
|
9
|
+
import { pagesApiFacts, pagesRouteFacts } from './pages/api'
|
|
10
|
+
import { scanRootParams } from './ppr/root-params-scan'
|
|
11
|
+
|
|
12
|
+
export async function compatReleaseFacts(
|
|
13
|
+
config: ResolvedConfig,
|
|
14
|
+
outDir: string,
|
|
15
|
+
): Promise<CompatRelease> {
|
|
16
|
+
const [nextConfig, instrumentation] = await Promise.all([
|
|
17
|
+
emitNextConfigBundle(config.root, outDir),
|
|
18
|
+
emitReleaseInstrumentation(config, outDir),
|
|
19
|
+
])
|
|
20
|
+
const toPosix = (file: string) => file.split(path.sep).join('/')
|
|
21
|
+
return {
|
|
22
|
+
...(nextConfig ? { nextConfig: toPosix(path.relative(config.outPath, nextConfig.file)) } : {}),
|
|
23
|
+
...(instrumentation
|
|
24
|
+
? {
|
|
25
|
+
instrumentation: {
|
|
26
|
+
file: toPosix(instrumentation.file),
|
|
27
|
+
...(instrumentation.edge ? { edge: toPosix(instrumentation.edge) } : {}),
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
: {}),
|
|
31
|
+
compat: {
|
|
32
|
+
rootParams: [...scanRootParams(config.appPath)],
|
|
33
|
+
pagesRevalidate: pagesRevalidateFacts(config.root).map(
|
|
34
|
+
([file, seconds]): [string, number] => [toPosix(file), seconds],
|
|
35
|
+
),
|
|
36
|
+
pagesApi: pagesApiFacts(config.root),
|
|
37
|
+
pagesRoutes: pagesRouteFacts(config),
|
|
38
|
+
cacheHandlers: Object.fromEntries(
|
|
39
|
+
Object.entries(nextConfig?.handlers ?? {}).map(([name, file]) => [
|
|
40
|
+
name,
|
|
41
|
+
toPosix(path.relative(config.outPath, file)),
|
|
42
|
+
]),
|
|
43
|
+
),
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
} from '../../extensions'
|
|
31
31
|
import { getRequestRuntime } from '../../routing/request-environment'
|
|
32
32
|
import { takeCacheLifeStash } from '../cache/use-cache'
|
|
33
|
-
import { matchInterception, parseNavState, selectRouteForRequest } from '../../routing/
|
|
33
|
+
import { matchInterception, parseNavState, selectRouteForRequest } from '../../routing/match'
|
|
34
34
|
import {
|
|
35
35
|
currentPprShellHtml,
|
|
36
36
|
pprShellPath,
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
// undefined/non-component default export; and the output:'export' extras (exportPathMap + app, a
|
|
11
11
|
// dynamic route without generateStaticParams, route handlers without static opt-ins, force-dynamic).
|
|
12
12
|
|
|
13
|
-
import { existsSync, readdirSync
|
|
13
|
+
import { existsSync, readdirSync } from 'node:fs'
|
|
14
14
|
import path from 'node:path'
|
|
15
|
+
import { readSourceSync } from '../../resolve/source-text'
|
|
15
16
|
import type { ResolvedConfig } from '../../config'
|
|
16
17
|
import { extraPageExtensions } from '../../extensions'
|
|
17
18
|
import type { RouteManifestEntry } from '../../types'
|
|
@@ -366,7 +367,7 @@ function readSource(file: string): string | undefined {
|
|
|
366
367
|
if (sourceCache.has(file)) return sourceCache.get(file)
|
|
367
368
|
let source: string | undefined
|
|
368
369
|
try {
|
|
369
|
-
source =
|
|
370
|
+
source = readSourceSync(file)
|
|
370
371
|
} catch {
|
|
371
372
|
source = undefined
|
|
372
373
|
}
|
|
@@ -379,7 +380,12 @@ function routeFiles(route: RouteManifestEntry): string[] {
|
|
|
379
380
|
}
|
|
380
381
|
|
|
381
382
|
function isAppSourceFile(config: ResolvedConfig, file: string): boolean {
|
|
382
|
-
|
|
383
|
+
const materialized =
|
|
384
|
+
file.includes(`${path.sep}source-app${path.sep}`) ||
|
|
385
|
+
file.includes(`${path.sep}source-pages${path.sep}`)
|
|
386
|
+
// A build materializes pages sources into its output (`<out>/pnext-pages-compat`).
|
|
387
|
+
if (isInside(config.outPath, file))
|
|
388
|
+
return materialized && file.includes(`${path.sep}pnext-pages-compat${path.sep}`)
|
|
383
389
|
const relative = path.relative(config.root, file)
|
|
384
390
|
if (relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative)) {
|
|
385
391
|
// A standalone npm layout keeps node_modules INSIDE the root; framework-supplied route
|
|
@@ -387,10 +393,7 @@ function isAppSourceFile(config: ResolvedConfig, file: string): boolean {
|
|
|
387
393
|
// (a JSDoc example in pnext's extensions.ts failed a real app's build as './pic.png').
|
|
388
394
|
return !relative.split(path.sep).includes('node_modules')
|
|
389
395
|
}
|
|
390
|
-
return
|
|
391
|
-
file.includes(`${path.sep}source-app${path.sep}`) ||
|
|
392
|
-
file.includes(`${path.sep}source-pages${path.sep}`)
|
|
393
|
-
)
|
|
396
|
+
return materialized
|
|
394
397
|
}
|
|
395
398
|
|
|
396
399
|
function isInside(parent: string, file: string): boolean {
|
package/src/config.ts
CHANGED
|
@@ -2,10 +2,11 @@ import { existsSync, realpathSync } from 'node:fs'
|
|
|
2
2
|
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
3
3
|
import path from 'node:path'
|
|
4
4
|
import { loadEnv } from './env'
|
|
5
|
-
import { findWorkspaceRoot } from './resolve/
|
|
5
|
+
import { findWorkspaceRoot } from './resolve/package-json'
|
|
6
6
|
import { PREFETCH_MODES, type PNextConfig } from './types'
|
|
7
7
|
import { setCacheComponents } from './render/ppr'
|
|
8
8
|
import { setLegacyRequestAPIs } from './request/context'
|
|
9
|
+
import { attachRelease, locateRelease, readBuildIndex, releaseConfig } from './runtime/production'
|
|
9
10
|
|
|
10
11
|
export type ResolvedConfig = Required<Pick<PNextConfig, 'outDir' | 'basePath'>> &
|
|
11
12
|
Omit<PNextConfig, 'outDir' | 'basePath'> & {
|
|
@@ -61,7 +62,13 @@ export interface ConfigSourceOverrides {
|
|
|
61
62
|
}
|
|
62
63
|
export type ConfigSource = (
|
|
63
64
|
root: string,
|
|
64
|
-
options: {
|
|
65
|
+
options: {
|
|
66
|
+
dev?: boolean
|
|
67
|
+
serve?: boolean
|
|
68
|
+
warnings?: boolean
|
|
69
|
+
bundle?: string | null
|
|
70
|
+
handlers?: Record<string, string>
|
|
71
|
+
},
|
|
65
72
|
) => Promise<ConfigSourceOverrides>
|
|
66
73
|
|
|
67
74
|
let configSource: ConfigSource | undefined
|
|
@@ -73,7 +80,7 @@ export function registerConfigSource(source: ConfigSource): void {
|
|
|
73
80
|
async function resolveConfigSource(
|
|
74
81
|
config: PNextConfig,
|
|
75
82
|
root: string,
|
|
76
|
-
options:
|
|
83
|
+
options: Parameters<ConfigSource>[1],
|
|
77
84
|
): Promise<ConfigSourceOverrides> {
|
|
78
85
|
if (!config.compat?.next) return {}
|
|
79
86
|
if (!configSource) {
|
|
@@ -90,6 +97,8 @@ export async function loadConfig(
|
|
|
90
97
|
options: { dev?: boolean; serve?: boolean; warnings?: boolean } = {},
|
|
91
98
|
): Promise<ResolvedConfig> {
|
|
92
99
|
const root = canonicalRoot(path.resolve(rootInput))
|
|
100
|
+
const released = options.serve ? locateRelease(root, DEFAULT_OUT_DIR) : undefined
|
|
101
|
+
if (released) return loadReleasedConfig(root, released, options)
|
|
93
102
|
await loadEnv(root, options)
|
|
94
103
|
const configPath = path.join(root, 'pnext.config.ts')
|
|
95
104
|
const loadedConfig = existsSync(configPath)
|
|
@@ -119,8 +128,13 @@ export async function loadConfig(
|
|
|
119
128
|
setCacheComponents(false)
|
|
120
129
|
const sourceOverrides = stripUndefined(await resolveConfigSource(config, root, options))
|
|
121
130
|
const merged = { ...defaultConfig, ...config, ...sourceOverrides }
|
|
122
|
-
const appPath = await resolveAppPath(root, config)
|
|
123
131
|
const outRootPath = path.resolve(root, merged.outDir)
|
|
132
|
+
// A build materializes pages into its output, so the release names them portably.
|
|
133
|
+
const appPath = await resolveAppPath(
|
|
134
|
+
root,
|
|
135
|
+
config,
|
|
136
|
+
options.dev ? undefined : path.join(outRootPath, 'pnext-pages-compat'),
|
|
137
|
+
)
|
|
124
138
|
const workspaceRoot = canonicalRoot(
|
|
125
139
|
config.workspaceRoot
|
|
126
140
|
? path.resolve(root, config.workspaceRoot)
|
|
@@ -156,6 +170,36 @@ export async function loadConfig(
|
|
|
156
170
|
}
|
|
157
171
|
}
|
|
158
172
|
|
|
173
|
+
/**
|
|
174
|
+
* A production server's config: what the build resolved, read from its release instead of re-importing
|
|
175
|
+
* `pnext.config.ts`/`next.config.*`. Per-app process state is re-derived exactly as a source load does.
|
|
176
|
+
*/
|
|
177
|
+
async function loadReleasedConfig(
|
|
178
|
+
root: string,
|
|
179
|
+
outPath: string,
|
|
180
|
+
options: { dev?: boolean; serve?: boolean; warnings?: boolean },
|
|
181
|
+
): Promise<ResolvedConfig> {
|
|
182
|
+
const index = readBuildIndex(outPath)
|
|
183
|
+
const config = releaseConfig(index.config, root, outPath)
|
|
184
|
+
await loadEnv(root, options)
|
|
185
|
+
setLegacyRequestAPIs(
|
|
186
|
+
typeof config.compat?.next === 'object' && config.compat.next.legacyRequestAPIs === true,
|
|
187
|
+
)
|
|
188
|
+
setCacheComponents(false)
|
|
189
|
+
await resolveConfigSource(config, root, {
|
|
190
|
+
...options,
|
|
191
|
+
bundle: index.nextConfig ? path.resolve(outPath, index.nextConfig) : null,
|
|
192
|
+
handlers: Object.fromEntries(
|
|
193
|
+
Object.entries(index.compat?.cacheHandlers ?? {}).map(([name, file]) => [
|
|
194
|
+
name,
|
|
195
|
+
path.resolve(outPath, file),
|
|
196
|
+
]),
|
|
197
|
+
),
|
|
198
|
+
})
|
|
199
|
+
attachRelease(config, index)
|
|
200
|
+
return config
|
|
201
|
+
}
|
|
202
|
+
|
|
159
203
|
// One row per enum-valued config field; validateConfig checks them all.
|
|
160
204
|
const enumFields: readonly [keyof PNextConfig, readonly unknown[]][] = [
|
|
161
205
|
['prefetch', PREFETCH_MODES],
|
|
@@ -264,7 +308,7 @@ export function pnextAliases(target: CompatAliasTarget): Record<string, string>
|
|
|
264
308
|
}
|
|
265
309
|
}
|
|
266
310
|
|
|
267
|
-
async function resolveAppPath(root: string, config: PNextConfig) {
|
|
311
|
+
async function resolveAppPath(root: string, config: PNextConfig, pagesBase?: string) {
|
|
268
312
|
const rootApp = path.join(root, 'app')
|
|
269
313
|
if (config.compat?.next) {
|
|
270
314
|
const pagesPath = path.join(root, 'pages')
|
|
@@ -272,13 +316,13 @@ async function resolveAppPath(root: string, config: PNextConfig) {
|
|
|
272
316
|
if (existsSync(rootApp)) {
|
|
273
317
|
if (hasPages) {
|
|
274
318
|
const { materializePagesApp } = await import('./compat/pages/router')
|
|
275
|
-
const hybrid = await materializePagesApp(root)
|
|
319
|
+
const hybrid = await materializePagesApp(root, pagesBase)
|
|
276
320
|
if (hybrid) return hybrid
|
|
277
321
|
}
|
|
278
322
|
return rootApp
|
|
279
323
|
}
|
|
280
324
|
const { materializePagesApp } = await import('./compat/pages/router')
|
|
281
|
-
const pagesApp = await materializePagesApp(root)
|
|
325
|
+
const pagesApp = await materializePagesApp(root, pagesBase)
|
|
282
326
|
if (pagesApp) return pagesApp
|
|
283
327
|
} else if (existsSync(rootApp)) return rootApp
|
|
284
328
|
return path.join(root, 'src', 'app')
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-asset naming and the CSS-module runtime: what a render needs to link stylesheets. The CSS
|
|
3
|
+
* compiler lives in `./build`; a production server never loads it.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync } from 'node:fs'
|
|
6
|
+
import { readFile, writeFile } from 'node:fs/promises'
|
|
7
|
+
import path from 'node:path'
|
|
8
|
+
import { getCssExtensions } from '../extensions'
|
|
9
|
+
import { nextCompatEnabled } from '../render/hooks'
|
|
10
|
+
import { productionRelease } from '../runtime/production'
|
|
11
|
+
import { hashedAssetName } from '../utils/asset-hash'
|
|
12
|
+
import { cssModuleScopePath, ensureDir, readText } from '../utils/fs'
|
|
13
|
+
import type { ResolvedConfig } from '../config'
|
|
14
|
+
import type { RouteManifestEntry } from '../types'
|
|
15
|
+
|
|
16
|
+
let build: Promise<typeof import('./build')> | undefined
|
|
17
|
+
|
|
18
|
+
export async function globalCssHref(config: ResolvedConfig) {
|
|
19
|
+
const sources =
|
|
20
|
+
productionRelease(config)?.globalCss ??
|
|
21
|
+
(await (build ??= import('./build'))).globalCssSources(config)
|
|
22
|
+
return sources.length > 0 ? assetHref(config, 'global.css') : undefined
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type AssetHrefConfig = Pick<ResolvedConfig, 'assetPrefix' | 'compat' | 'outPath'>
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Logical build-asset name -> the content-hashed name the build actually emitted
|
|
29
|
+
* (`global.css` -> `global-1f4a9c2b3d5e6f70.css`). A production asset name must
|
|
30
|
+
* carry its content, or the URL cannot honestly be served `immutable`: the same
|
|
31
|
+
* name would answer different bytes after a deploy.
|
|
32
|
+
*
|
|
33
|
+
* Keyed by outPath, never process-global: one process builds several apps (the
|
|
34
|
+
* test suite does it constantly) and their names must not cross. Empty in dev,
|
|
35
|
+
* where names stay flat and every asset is served `no-cache` anyway.
|
|
36
|
+
*/
|
|
37
|
+
const emittedAssets = new Map<string, Map<string, string>>()
|
|
38
|
+
|
|
39
|
+
export function recordEmittedAsset(outPath: string, logical: string, emitted: string): void {
|
|
40
|
+
const names = emittedAssets.get(outPath) ?? new Map<string, string>()
|
|
41
|
+
names.set(logical, emitted)
|
|
42
|
+
emittedAssets.set(outPath, names)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Re-publish the build's name map at server boot (see BuildManifest.assetNames). */
|
|
46
|
+
export function publishEmittedAssets(
|
|
47
|
+
outPath: string,
|
|
48
|
+
names: Record<string, string> | undefined,
|
|
49
|
+
): void {
|
|
50
|
+
if (!names) return
|
|
51
|
+
for (const [logical, emitted] of Object.entries(names))
|
|
52
|
+
recordEmittedAsset(outPath, logical, emitted)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function emittedAssetNames(outPath: string): Record<string, string> {
|
|
56
|
+
return Object.fromEntries(emittedAssets.get(outPath) ?? [])
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function clearEmittedAssets(outPath: string): void {
|
|
60
|
+
emittedAssets.delete(outPath)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The file name a logical asset name resolves to. Identity until a build records one. */
|
|
64
|
+
export function emittedAssetName(
|
|
65
|
+
config: Pick<ResolvedConfig, 'outPath'> | undefined,
|
|
66
|
+
name: string,
|
|
67
|
+
): string {
|
|
68
|
+
if (!config?.outPath) return name
|
|
69
|
+
return emittedAssets.get(config.outPath)?.get(name) ?? name
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Where a built asset lives in the URL space. next-compat serves the build output under Next's
|
|
73
|
+
// static path, so a compat app's document references its CSS/JS exactly as Next does; core keeps
|
|
74
|
+
// `/assets/`. Every document-emitted build-asset URL goes through here (and the dev/prod servers
|
|
75
|
+
// accept both spellings), so an emitted href can never name a path the server will not serve —
|
|
76
|
+
// including the content hash the production name carries.
|
|
77
|
+
export function assetPathname(
|
|
78
|
+
config: Pick<ResolvedConfig, 'compat' | 'outPath'> | undefined,
|
|
79
|
+
name: string,
|
|
80
|
+
) {
|
|
81
|
+
const emitted = emittedAssetName(config, name)
|
|
82
|
+
return nextCompatEnabled(config ?? {}) ? `/_next/static/${emitted}` : `/assets/${emitted}`
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function assetHref(config: AssetHrefConfig | undefined, name: string) {
|
|
86
|
+
return withAssetPrefix(config, assetPathname(config, name))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// A route's built CSS filenames - the one rule behind the document's links, the
|
|
90
|
+
// inline-CSS path and analyze, so no consumer can disagree about whether a
|
|
91
|
+
// route has CSS. compat cssChunking records split names in cssAssets.
|
|
92
|
+
export function routeCssAssetNames(
|
|
93
|
+
route: Pick<RouteManifestEntry, 'id' | 'cssImports' | 'cssAssets'>,
|
|
94
|
+
): string[] {
|
|
95
|
+
if (route.cssImports.length === 0) return []
|
|
96
|
+
return route.cssAssets?.length ? route.cssAssets : [`${route.id}.css`]
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function routeCssHref(
|
|
100
|
+
route: RouteManifestEntry,
|
|
101
|
+
config?: AssetHrefConfig,
|
|
102
|
+
): string | string[] | undefined {
|
|
103
|
+
const assets = routeCssAssetNames(route)
|
|
104
|
+
if (assets.length === 0) return undefined
|
|
105
|
+
return assets.map(asset => assetHref(config, asset))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Put a render's next/font rules in the first stylesheet chunk, matching Next's
|
|
110
|
+
* linked CSS delivery without changing the rest of the route's chunk order.
|
|
111
|
+
*/
|
|
112
|
+
export async function emitFontCssStylesheet(
|
|
113
|
+
config: ResolvedConfig,
|
|
114
|
+
routeId: string,
|
|
115
|
+
fontCss: string,
|
|
116
|
+
baseAsset: string | undefined,
|
|
117
|
+
options: { dev: boolean },
|
|
118
|
+
) {
|
|
119
|
+
const outDir = path.join(config.outPath, options.dev ? 'cache' : 'public', 'assets')
|
|
120
|
+
await ensureDir(outDir)
|
|
121
|
+
const baseFile = baseAsset ? path.join(outDir, baseAsset) : undefined
|
|
122
|
+
const baseCss = baseFile && existsSync(baseFile) ? await readFile(baseFile, 'utf8') : ''
|
|
123
|
+
const contents = [fontCss, baseCss].filter(Boolean).join('\n')
|
|
124
|
+
const logicalName = baseAsset
|
|
125
|
+
? baseAsset.replace(/-[0-9a-f]{16}(?=\.css$)/, '')
|
|
126
|
+
: `${routeId}.css`
|
|
127
|
+
const name = hashedAssetName(logicalName, contents)
|
|
128
|
+
const file = path.join(outDir, name)
|
|
129
|
+
if (!existsSync(file) || (await readFile(file, 'utf8')) !== contents)
|
|
130
|
+
await writeFile(file, contents)
|
|
131
|
+
return name
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Prepend the configured assetPrefix (a CDN origin or path) to an app-absolute
|
|
135
|
+
// asset URL. Link hrefs use basePath instead and must NOT go through here.
|
|
136
|
+
export function withAssetPrefix(
|
|
137
|
+
config: Pick<ResolvedConfig, 'assetPrefix'> | undefined,
|
|
138
|
+
href: string,
|
|
139
|
+
) {
|
|
140
|
+
const prefix = config?.assetPrefix
|
|
141
|
+
if (!prefix) return href
|
|
142
|
+
return `${prefix.replace(/\/$/, '')}${href}`
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
let cssRuntimeRegistered = false
|
|
146
|
+
|
|
147
|
+
export function registerCssRuntime() {
|
|
148
|
+
if (cssRuntimeRegistered) return
|
|
149
|
+
cssRuntimeRegistered = true
|
|
150
|
+
|
|
151
|
+
Bun.plugin({
|
|
152
|
+
name: 'pnext-css-runtime',
|
|
153
|
+
setup(plugin) {
|
|
154
|
+
plugin.onLoad({ filter: /\.(?:css|scss|sass)$/ }, async ({ path: file }) =>
|
|
155
|
+
isCssModuleFile(file)
|
|
156
|
+
? {
|
|
157
|
+
exports: { default: await cssModuleMapping(file) },
|
|
158
|
+
loader: 'object',
|
|
159
|
+
}
|
|
160
|
+
: {
|
|
161
|
+
contents: 'export default undefined;',
|
|
162
|
+
loader: 'js',
|
|
163
|
+
},
|
|
164
|
+
)
|
|
165
|
+
},
|
|
166
|
+
})
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Sass is unsupported (no compiler); its imports still must not break the
|
|
170
|
+
// bundle, so .scss/.sass load as empty modules with module class-name maps.
|
|
171
|
+
export function isCssModuleFile(file: string) {
|
|
172
|
+
return /\.module\.(?:css|scss|sass)$/.test(file)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function cssModuleMapping(file: string) {
|
|
176
|
+
// Compat handles *.module.{scss,sass} (sass compiles + scopes); core keeps
|
|
177
|
+
// plain .module.css. Lazy read: the registry populates at compat bootstrap.
|
|
178
|
+
const compatMapping = getCssExtensions().resolveCssModule(file)
|
|
179
|
+
if (compatMapping) return compatMapping
|
|
180
|
+
const source = await readText(file)
|
|
181
|
+
const classNames = cssClassNames(source)
|
|
182
|
+
|
|
183
|
+
return Object.fromEntries(
|
|
184
|
+
[...classNames].map(className => [className, cssModuleClassName(file, className)]),
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function cssClassNames(source: string) {
|
|
189
|
+
const classNames = new Set<string>()
|
|
190
|
+
const classPattern = /(^|[^\\])\.(-?[_a-zA-Z][\w-]*)/g
|
|
191
|
+
let match: RegExpExecArray | null
|
|
192
|
+
|
|
193
|
+
while ((match = classPattern.exec(source))) {
|
|
194
|
+
if (match[2]) classNames.add(match[2])
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return classNames
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function cssModuleClassName(file: string, className: string) {
|
|
201
|
+
const base = path
|
|
202
|
+
.basename(file)
|
|
203
|
+
.replace(/\.module\.css$/, '')
|
|
204
|
+
.replace(/[^_a-zA-Z0-9]/g, '_')
|
|
205
|
+
const hash = pathHash(cssModuleScopePath(file))
|
|
206
|
+
return `${base}_${className}_${hash}`
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function pathHash(file: string) {
|
|
210
|
+
let hash = 5381
|
|
211
|
+
for (const char of file) hash = ((hash << 5) + hash) ^ char.charCodeAt(0)
|
|
212
|
+
return (hash >>> 0).toString(36).slice(0, 5)
|
|
213
|
+
}
|