@thomas.f/prnext 0.1.18-alpha → 0.1.20-alpha
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 +2 -0
- package/build/actions.mjs +26 -14
- package/build/app.mjs +90 -101
- package/build/build-lock.mjs +2 -71
- package/build/build-retention.mjs +119 -0
- package/build/bundle-runtime.mjs +9 -8
- package/build/cache-command.mjs +31 -0
- package/build/check.mjs +41 -3
- package/build/compilation-cache.mjs +32 -12
- package/build/compilation-storage.mjs +190 -0
- package/build/compiler.mjs +8 -7
- package/build/config.mjs +25 -2
- package/build/create.mjs +1 -1
- package/build/css-modules.mjs +4 -0
- package/build/dev-action-graph.mjs +21 -0
- package/build/dev-css-assets.mjs +173 -0
- package/build/dev-css-update.mjs +14 -12
- package/build/dev-lazy-build.mjs +77 -0
- package/build/dynamic.mjs +13 -6
- package/build/font-cache.mjs +9 -6
- package/build/font-files.mjs +1 -1
- package/build/incremental.mjs +112 -18
- package/build/index.mjs +61 -15
- package/build/lazy-dynamic-imports.mjs +137 -0
- package/build/migrate.mjs +4 -4
- package/build/migration-audit.mjs +19 -31
- package/build/migration-imports.mjs +245 -0
- package/build/migration-scenarios-runner.mjs +73 -0
- package/build/migration-scenarios.mjs +72 -0
- package/build/native-discovery.mjs +65 -5
- package/build/native-packages.mjs +2 -0
- package/build/native-ppr.mjs +32 -0
- package/build/npm-packages.mjs +1 -0
- package/build/og.mjs +121 -1
- package/build/parallel-plan.mjs +55 -0
- package/build/persistent-cache.mjs +29 -24
- package/build/production-builder.mjs +1 -1
- package/build/production-check.mjs +34 -0
- package/build/react-compiler-report.mjs +31 -8
- package/build/react-compiler.mjs +101 -10
- package/build/server-config.mjs +35 -0
- package/build/source-analysis.mjs +54 -4
- package/build/standalone.mjs +21 -3
- package/build/static-adapter.mjs +7 -3
- package/build/transform.mjs +38 -6
- package/build/typescript-dev.mjs +3 -1
- package/build/webpack-graph.mjs +13 -3
- package/cli.mjs +24 -6
- package/compat/app-dynamic.cjs +12 -1
- package/compat/app-layout-context.cjs +7 -3
- package/compat/cache-handlers.cjs +3 -1
- package/compat/flight-delta.cjs +50 -13
- package/compat/index.d.ts +24 -1
- package/compat/link.cjs +2 -2
- package/compat/navigation-authorization.cjs +8 -1
- package/docs/ai/compatibility.md +187 -7
- package/docs/ai/deployment.md +141 -0
- package/docs/ai/quickstart.md +5 -0
- package/docs/ai/routing.md +11 -0
- package/docs/ai/troubleshooting.md +79 -0
- package/package.json +26 -11
- package/release/fontkit.mjs +31 -0
- package/release/verify.mjs +3 -0
- package/runtime/api.mjs +5 -2
- package/runtime/app-client.mjs +254 -53
- package/runtime/app-partial.mjs +2 -10
- package/runtime/app-prefetch.mjs +2 -2
- package/runtime/app-render.mjs +11 -7
- package/runtime/app-stream-channel.mjs +3 -2
- package/runtime/app-styles.mjs +22 -4
- package/runtime/atomic-file.mjs +27 -0
- package/runtime/cache-components-rsc.mjs +3 -1
- package/runtime/compile-cache-retention.mjs +53 -0
- package/runtime/compile-cache.mjs +28 -1
- package/runtime/dev-client.mjs +13 -5
- package/runtime/dev-file-changes.mjs +123 -8
- package/runtime/dev-gateway.mjs +3 -2
- package/runtime/dev-lazy-imports.mjs +121 -0
- package/runtime/dev-lazy-staging.mjs +14 -0
- package/runtime/dev-route-selection.mjs +64 -0
- package/runtime/dev-runtime-pool.mjs +3 -2
- package/runtime/dev-runtime-spare.mjs +1 -1
- package/runtime/dev-session-retention.mjs +154 -0
- package/runtime/dev-style-retention.mjs +15 -0
- package/runtime/development.mjs +86 -26
- package/runtime/env.mjs +9 -0
- package/runtime/flight-delta.mjs +59 -9
- package/runtime/fs.mjs +15 -8
- package/runtime/lazy-import-client.mjs +38 -0
- package/runtime/native-ppr.mjs +35 -0
- package/runtime/og/NOTICE.txt +1 -1
- package/runtime/og/index.node.mjs +76 -31216
- package/runtime/og/upstream.json +115 -0
- package/runtime/persistent/client.mjs +4 -2
- package/runtime/persistent/daemon.mjs +3 -11
- package/runtime/persistent/health.mjs +58 -0
- package/runtime/project-lock.mjs +71 -0
- package/runtime/request-transport.mjs +112 -32
- package/runtime/storage-path.mjs +36 -0
- package/runtime/trace.mjs +44 -4
- package/runtime/worker.mjs +9 -4
- package/vendor/fontkit/NOTICE.txt +5 -0
- package/vendor/fontkit/SOURCE-NOTICES.txt +209 -0
- package/vendor/fontkit/index.mjs +3 -0
- package/vendor/fontkit/licenses/@swc__helpers/LICENSE +201 -0
- package/vendor/fontkit/licenses/base64-js/LICENSE +21 -0
- package/vendor/fontkit/licenses/brotli/readme.md +61 -0
- package/vendor/fontkit/licenses/clone/LICENSE +18 -0
- package/vendor/fontkit/licenses/dfa/README.md +83 -0
- package/vendor/fontkit/licenses/fast-deep-equal/LICENSE +21 -0
- package/vendor/fontkit/licenses/fontkit/README.md +266 -0
- package/vendor/fontkit/licenses/restructure/LICENSE +21 -0
- package/vendor/fontkit/licenses/tiny-inflate/LICENSE +21 -0
- package/vendor/fontkit/licenses/tslib/LICENSE.txt +12 -0
- package/vendor/fontkit/licenses/unicode-properties/LICENSE +8 -0
- package/vendor/fontkit/licenses/unicode-trie/LICENSE +8 -0
- package/vendor/fontkit/upstream.json +215 -0
- package/vendor/nft/LICENSE +7 -0
- package/vendor/nft/README.md +16 -0
- package/vendor/nft/out/analyze.d.ts +8 -0
- package/vendor/nft/out/analyze.js +1216 -0
- package/vendor/nft/out/analyze.js.map +1 -0
- package/vendor/nft/out/cli.d.ts +2 -0
- package/vendor/nft/out/cli.js +94 -0
- package/vendor/nft/out/cli.js.map +1 -0
- package/vendor/nft/out/fs.d.ts +22 -0
- package/vendor/nft/out/fs.js +106 -0
- package/vendor/nft/out/fs.js.map +1 -0
- package/vendor/nft/out/index.d.ts +4 -0
- package/vendor/nft/out/index.js +25 -0
- package/vendor/nft/out/index.js.map +1 -0
- package/vendor/nft/out/node-file-trace.d.ts +41 -0
- package/vendor/nft/out/node-file-trace.js +380 -0
- package/vendor/nft/out/node-file-trace.js.map +1 -0
- package/vendor/nft/out/resolve-dependency.d.ts +6 -0
- package/vendor/nft/out/resolve-dependency.js +427 -0
- package/vendor/nft/out/resolve-dependency.js.map +1 -0
- package/vendor/nft/out/types.d.ts +66 -0
- package/vendor/nft/out/types.js +2 -0
- package/vendor/nft/out/types.js.map +1 -0
- package/vendor/nft/out/utils/ast-helpers.js +49 -0
- package/vendor/nft/out/utils/ast-helpers.js.map +1 -0
- package/vendor/nft/out/utils/binary-locators.js +88 -0
- package/vendor/nft/out/utils/binary-locators.js.map +1 -0
- package/vendor/nft/out/utils/get-package-base.js +30 -0
- package/vendor/nft/out/utils/get-package-base.js.map +1 -0
- package/vendor/nft/out/utils/interop-require.js +24 -0
- package/vendor/nft/out/utils/interop-require.js.map +1 -0
- package/vendor/nft/out/utils/node-version.js +10 -0
- package/vendor/nft/out/utils/node-version.js.map +1 -0
- package/vendor/nft/out/utils/sharedlib-emit.js +33 -0
- package/vendor/nft/out/utils/sharedlib-emit.js.map +1 -0
- package/vendor/nft/out/utils/special-cases.js +347 -0
- package/vendor/nft/out/utils/special-cases.js.map +1 -0
- package/vendor/nft/out/utils/static-eval.js +579 -0
- package/vendor/nft/out/utils/static-eval.js.map +1 -0
- package/vendor/nft/out/utils/types.js +2 -0
- package/vendor/nft/out/utils/types.js.map +1 -0
- package/vendor/nft/out/utils/wrappers.js +659 -0
- package/vendor/nft/out/utils/wrappers.js.map +1 -0
- package/vendor/nft/package.json +4 -0
- package/vendor/nft/upstream.json +51 -0
package/compat/index.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface InstantSample {
|
|
|
14
14
|
export type InstantConfig = boolean | { level?: 'warning' | 'experimental-error'; unstable_samples?: InstantSample[]; unstable_disableValidation?: true; unstable_disableDevValidation?: true; unstable_disableBuildValidation?: true };
|
|
15
15
|
|
|
16
16
|
export interface ReactCompilerOptions {
|
|
17
|
+
/** Babel by default. The native Oxc backend is experimental and opt-in. */
|
|
18
|
+
backend?: 'babel' | 'oxc';
|
|
17
19
|
compilationMode?: 'infer' | 'annotation';
|
|
18
20
|
panicThreshold?: 'none' | 'critical_errors' | 'all_errors';
|
|
19
21
|
/** PRNext requires matching React 19 peers. */
|
|
@@ -121,6 +123,8 @@ export interface Rewrite extends CustomRoute { destination: string }
|
|
|
121
123
|
export type ConfigRedirect = CustomRoute & Redirect;
|
|
122
124
|
/** Implemented project options. Unsupported behavior-changing options fail the build. */
|
|
123
125
|
export interface NextConfig {
|
|
126
|
+
/** Public origin and transport peers permitted to set X-Forwarded-Host/Proto. */
|
|
127
|
+
server?: {publicOrigin?: string; trustedProxies?: readonly string[]};
|
|
124
128
|
/** PRNext only. CLI > environment > build configuration > profile.
|
|
125
129
|
* 0 disables the corresponding retirement; keepWarm retains one lane per used host.
|
|
126
130
|
*/
|
|
@@ -131,6 +135,10 @@ export interface NextConfig {
|
|
|
131
135
|
workerPreload?: false | { routes: string[]; maxRssMb?: number; timeoutMs?: number };
|
|
132
136
|
/** Keep bounded previous public hashed assets. false disables carry-over. Defaults: one hour, two generations, 64 MiB. */
|
|
133
137
|
deploymentRetention?: false | {maxAge?: number; maxGenerations?: number; maxBytes?: number};
|
|
138
|
+
/** Common disk budget for regenerable compiler caches, in bytes (default 256 MiB).
|
|
139
|
+
* Applied after builds; active dev sessions/workers can defer reclamation.
|
|
140
|
+
* Runtime data, invalidations, page and image caches are excluded. */
|
|
141
|
+
compilationCache?: {maxDiskSize?: number};
|
|
134
142
|
/** PRNext production prerender processes; maxMemoryMb bounds their combined observed memory. */
|
|
135
143
|
prerender?: {workers?: number; maxMemoryMb?: number};
|
|
136
144
|
/** Explicit App route patterns that must produce complete static HTML without browser JavaScript. */
|
|
@@ -167,7 +175,20 @@ export interface NextConfig {
|
|
|
167
175
|
implementation?: 'sass' | 'sass-embedded';
|
|
168
176
|
[option: string]: unknown;
|
|
169
177
|
};
|
|
170
|
-
experimental?: {
|
|
178
|
+
experimental?: {
|
|
179
|
+
nextScriptWorkers?: boolean;
|
|
180
|
+
/** App Router development only; compile literal client imports on first use. */
|
|
181
|
+
lazyDynamicImports?: boolean;
|
|
182
|
+
/** Start App Route Handlers before upload EOF; mutations must handle aborted uploads. */
|
|
183
|
+
streamingRequestBodies?: boolean;
|
|
184
|
+
/** Serve certified public PPR document shells before starting Node. Requires cacheComponents. */
|
|
185
|
+
nativePprShell?: boolean;
|
|
186
|
+
/** Bound independent production CSS builds after graph discovery. Disabled by default. */
|
|
187
|
+
parallelBuilds?: boolean | {maxWorkers?: number; maxMemoryMb?: number};
|
|
188
|
+
optimizePackageImports?: string[];
|
|
189
|
+
proxyClientMaxBodySize?: number | string;
|
|
190
|
+
serverActions?: true | {allowedOrigins?: string[]; bodySizeLimit?: number | string};
|
|
191
|
+
};
|
|
171
192
|
trailingSlash?: boolean;
|
|
172
193
|
skipTrailingSlashRedirect?: boolean;
|
|
173
194
|
skipMiddlewareUrlNormalize?: boolean;
|
|
@@ -216,6 +237,7 @@ export interface StaticBuildOptions {
|
|
|
216
237
|
}
|
|
217
238
|
export interface ReactCompilerReport {
|
|
218
239
|
version: 1;
|
|
240
|
+
backend?: 'babel' | 'oxc';
|
|
219
241
|
compilerVersion: string | null;
|
|
220
242
|
enabled: boolean;
|
|
221
243
|
buildId: string | null;
|
|
@@ -227,6 +249,7 @@ export interface ReactCompilerReport {
|
|
|
227
249
|
summary: {files: number; functions: number; optimized: number; skipped: number; errors: number; diagnostics: number; mixed: number; transforms: number; cacheReuses: number};
|
|
228
250
|
files: Array<{
|
|
229
251
|
file: string; transforms: number; cacheReuses: number; targets: string[]; notes: string[];
|
|
252
|
+
diagnostics?: Array<{kind: 'CompileError' | 'CompileDiagnostic'; status: 'error' | 'diagnostic'; reason: string | null; category: string | null; targets: Array<'browser' | 'node' | 'edge' | 'unspecified'>}>;
|
|
230
253
|
functions: Array<{
|
|
231
254
|
name: string | null;
|
|
232
255
|
start: {line: number; column: number} | null;
|
package/compat/link.cjs
CHANGED
|
@@ -21,11 +21,11 @@ const Link = React.forwardRef(function Link({ href, as, children, replace, scrol
|
|
|
21
21
|
const source = formatUrl(href);
|
|
22
22
|
const requestPrefetch = React.useCallback((priority = 'intent') => {
|
|
23
23
|
if (prefetch === false || process.env.NODE_ENV !== 'production') return;
|
|
24
|
-
if (app
|
|
24
|
+
if (app && (app.router.partialPrefetch || prefetch === true)) app.router.prefetch(target, { priority, full: prefetch === true });
|
|
25
25
|
if (!app && pages) void pages.prefetch(source, as ? target : undefined, { locale, priority }).catch(() => {});
|
|
26
26
|
}, [app, pages, source, target, as, locale, prefetch]);
|
|
27
27
|
React.useEffect(() => {
|
|
28
|
-
if ((app ? !app.router.partialPrefetch : !pages) || prefetch === false || process.env.NODE_ENV !== 'production' || typeof IntersectionObserver === 'undefined' || !anchorRef.current) return;
|
|
28
|
+
if ((app ? !app.router.partialPrefetch && prefetch !== true : !pages) || prefetch === false || process.env.NODE_ENV !== 'production' || typeof IntersectionObserver === 'undefined' || !anchorRef.current) return;
|
|
29
29
|
const observer = new IntersectionObserver(entries => {
|
|
30
30
|
if (entries.some(entry => entry.isIntersecting)) { observer.disconnect(); requestPrefetch('viewport'); }
|
|
31
31
|
}, { rootMargin: '200px' });
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const { createHmac } = require('node:crypto');
|
|
3
|
+
function developmentNavigationSecret(actionKey) {
|
|
4
|
+
if (typeof actionKey !== 'string' || !actionKey) return undefined;
|
|
5
|
+
// The compiler retains this private key across generations of one dev
|
|
6
|
+
// session. Derive a separate purpose key so worker replacement cannot look
|
|
7
|
+
// like an account change, without publishing or reusing the encryption key.
|
|
8
|
+
return createHmac('sha256', actionKey).update('prnext:development:navigation-authorization:v1').digest('hex');
|
|
9
|
+
}
|
|
3
10
|
function navigationAuthorization(context, secret, cookieNames) {
|
|
4
11
|
if (!secret || context?.staticState) return undefined;
|
|
5
12
|
const names = cookieNames === undefined ? null : new Set(cookieNames);
|
|
6
13
|
const cookies = context.cookies.getAll().filter(cookie => !names || names.has(cookie.name)).map(({ name, value }) => [name, value]).sort((a, b) => a[0].localeCompare(b[0]));
|
|
7
14
|
return createHmac('sha256', secret).update(JSON.stringify([cookies, context.headers.get('authorization') || ''])).digest('hex');
|
|
8
15
|
}
|
|
9
|
-
module.exports = { navigationAuthorization };
|
|
16
|
+
module.exports = { navigationAuthorization, developmentNavigationSecret };
|
package/docs/ai/compatibility.md
CHANGED
|
@@ -18,6 +18,13 @@ transpilation, image/font tooling and caching deserve targeted build and browser
|
|
|
18
18
|
tests. Support for one configuration shape does not imply support for all
|
|
19
19
|
upstream plugin behavior.
|
|
20
20
|
|
|
21
|
+
When moving from 0.1.19-alpha, use the installed
|
|
22
|
+
[upgrade checklist](deployment.md#upgrading-from-0119-alpha): rebuild matching
|
|
23
|
+
artifacts, configure the public HTTPS origin and proxy trust, verify strict
|
|
24
|
+
account transitions and review saved persistent health routes. Storage cleanup
|
|
25
|
+
must preserve runtime data and invalidation history. Experimental performance
|
|
26
|
+
options remain independent and opt-in.
|
|
27
|
+
|
|
21
28
|
## Instrumentation and tracing
|
|
22
29
|
|
|
23
30
|
Use a single `instrumentation.ts`, `.js`, `.mjs` or `.cjs` at the project root
|
|
@@ -132,6 +139,66 @@ new source files and configuration changes restart the native watch generation.
|
|
|
132
139
|
adding its generated declaration to the config. Compiler support does not imply
|
|
133
140
|
that every application is ready for TypeScript 7's own language/config changes.
|
|
134
141
|
|
|
142
|
+
## Experimental performance paths
|
|
143
|
+
|
|
144
|
+
These options are independent and disabled by default. Enable them in the
|
|
145
|
+
application's existing configuration, then qualify its actual workflows:
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
export default {
|
|
149
|
+
cacheComponents: true,
|
|
150
|
+
experimental: {
|
|
151
|
+
nativePprShell: true,
|
|
152
|
+
streamingRequestBodies: true,
|
|
153
|
+
parallelBuilds: {maxWorkers: 4, maxMemoryMb: 1024},
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`nativePprShell` lets Rust send the exact certified build shell before starting
|
|
159
|
+
Node, then resume its React continuation. The initial implementation covers
|
|
160
|
+
concrete App PPR document GETs without query strings, cookies, authorization,
|
|
161
|
+
middleware, rewrites, base paths, router-state/Flight/prefetch headers or CSP
|
|
162
|
+
nonces. Generic parameter shells, Edge, external caches and unsupported requests
|
|
163
|
+
keep the ordinary Node path. Prefixes and artifacts have checked hashes and
|
|
164
|
+
bounded sizes; continuations use a private transport field, never an HTTP flag.
|
|
165
|
+
Responses remain private and no-store. The cache generation must still be zero
|
|
166
|
+
and the build artifact unexpired: any persisted invalidation disables this build
|
|
167
|
+
snapshot optimization, including across server restarts. It does not disable
|
|
168
|
+
PPR itself or invalidate an already committed response. Requests already using
|
|
169
|
+
a snapshot finish with that same artifact when an invalidation races them.
|
|
170
|
+
|
|
171
|
+
`streamingRequestBodies` makes `Request.body` available to Node App Route
|
|
172
|
+
Handlers before upload EOF. It negotiates its own protocol capability and sends
|
|
173
|
+
at most one 64 KiB frame per reader credit. Unsupported workers use the existing
|
|
174
|
+
buffered path. Server Actions, Pages APIs and middleware-buffered requests retain
|
|
175
|
+
their previous buffering behavior. Streaming handlers can begin application
|
|
176
|
+
effects before a truncated or excessive upload is rejected: validate the input
|
|
177
|
+
and complete authorization before committing a mutation. The total request limit
|
|
178
|
+
remains 32 MiB. Existing ingress byte reservations are preserved; this feature
|
|
179
|
+
does not promise a smaller V8 heap or higher memory admission concurrency. A
|
|
180
|
+
cancelled or early-returned upload closes its single-use lane without replaying
|
|
181
|
+
the mutation, while retaining the healthy Node host.
|
|
182
|
+
|
|
183
|
+
`parallelBuilds` freezes App stylesheet plans after dependency discovery,
|
|
184
|
+
deduplicates outputs and emits independent jobs with deterministic linking.
|
|
185
|
+
Graph discovery itself remains ordered. Concurrency is bounded by CPU count,
|
|
186
|
+
available memory and the configured worker/budget limits. `maxWorkers` accepts
|
|
187
|
+
1–8; `maxMemoryMb` accepts 256–8192 and is an admission estimate, not a hard RSS
|
|
188
|
+
limit for third-party code. Custom webpack/loaders, custom PostCSS pipelines and
|
|
189
|
+
Sass callbacks retain serial execution. A failed job stops new admission and
|
|
190
|
+
settles started jobs before the staging build is discarded; the last published
|
|
191
|
+
build is preserved. An enabled build records its actual stylesheet job count
|
|
192
|
+
and selected concurrency in `manifest.buildParallelism`.
|
|
193
|
+
|
|
194
|
+
Development refreshes can also target the routes that import a changed Server
|
|
195
|
+
Action or its transitive dependencies. Certification uses both dependency
|
|
196
|
+
graphs before and after a change. An unrelated tab still applies a deferred
|
|
197
|
+
generation before navigating to a changed route. Unknown or incomplete graphs,
|
|
198
|
+
binding/runtime/route changes, global configuration, rewrites/middleware,
|
|
199
|
+
internationalized or parallel/intercepting routing retain a global refresh.
|
|
200
|
+
Server generations still publish as a whole; pending mutations are never replayed.
|
|
201
|
+
|
|
135
202
|
## React Compiler
|
|
136
203
|
|
|
137
204
|
Enable the bundled official React Compiler in the project's existing config:
|
|
@@ -142,7 +209,7 @@ export default {
|
|
|
142
209
|
};
|
|
143
210
|
```
|
|
144
211
|
|
|
145
|
-
|
|
212
|
+
The default Babel backend needs no separate compiler installation. The default is disabled;
|
|
146
213
|
`reactCompiler: false` preserves the uncompiled component path. Enabled builds
|
|
147
214
|
optimize project-owned browser components in both Pages and App applications,
|
|
148
215
|
in development and production. App Client Components also use the transform in
|
|
@@ -153,17 +220,43 @@ Components, Server Action modules, PRNext internals, generated entrypoints and
|
|
|
153
220
|
npm packages are not compiled. Keep the matching React 19 peer versions required
|
|
154
221
|
by the installed framework.
|
|
155
222
|
|
|
156
|
-
|
|
157
|
-
in those extensions remain unsupported.
|
|
223
|
+
With the default Babel backend, ordinary `.mts`/`.cts` hook helpers can be
|
|
224
|
+
optimized; server/client directives in those extensions remain unsupported.
|
|
225
|
+
Decorated `.mts`/`.cts` utility modules
|
|
158
226
|
keep their native compilation path while importing React components can still
|
|
159
227
|
be optimized.
|
|
160
228
|
|
|
161
229
|
For gradual adoption, use `reactCompiler: { compilationMode: 'annotation' }`, then
|
|
162
230
|
put `"use memo";` at the beginning of each component or hook to optimize. In
|
|
163
231
|
either mode, `"use no memo";` excludes an individual function. Supported object
|
|
164
|
-
options are `compilationMode: 'infer' | 'annotation'`,
|
|
232
|
+
options are `backend: 'babel' | 'oxc'`, `compilationMode: 'infer' | 'annotation'`,
|
|
165
233
|
`panicThreshold: 'none' | 'critical_errors' | 'all_errors'` and `target: '19'`.
|
|
166
|
-
Defaults are `'infer'`, `'none'` and `'19'`; other fields are rejected.
|
|
234
|
+
Defaults are Babel, `'infer'`, `'none'` and `'19'`; other fields are rejected.
|
|
235
|
+
|
|
236
|
+
The experimental native Rust backend is an explicit alternative:
|
|
237
|
+
|
|
238
|
+
```sh
|
|
239
|
+
npm install --save-dev oxc-transform-react@0.157.0
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```js
|
|
243
|
+
export default {
|
|
244
|
+
reactCompiler: { backend: 'oxc' },
|
|
245
|
+
};
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Oxc is an optional peer, so ordinary Babel builds do not install its compiler,
|
|
249
|
+
WASM distribution or native binding. Run the installation above in the application
|
|
250
|
+
project on the build machine, with optional platform dependencies enabled. A
|
|
251
|
+
global CLI also resolves this project-local peer. This option
|
|
252
|
+
requires the native binding; an absent or incompatible compiler, missing binding
|
|
253
|
+
or compilation failure fails explicitly. PRNext never silently changes the backend. JSX remains available
|
|
254
|
+
to the existing graph compiler, while this backend removes TypeScript syntax.
|
|
255
|
+
App Client Component server rendering uses Oxc's SSR output; browser graphs use
|
|
256
|
+
its client output. The same project boundaries and Server Action exclusions
|
|
257
|
+
apply. Source maps, loader maps and the existing Fast Refresh pipeline remain
|
|
258
|
+
part of the compilation path. Unsupported options are rejected rather than
|
|
259
|
+
passed through to the native compiler.
|
|
167
260
|
|
|
168
261
|
After a successful build, inspect the compiler's actual results:
|
|
169
262
|
|
|
@@ -172,8 +265,8 @@ prnext compiler
|
|
|
172
265
|
prnext compiler --json
|
|
173
266
|
```
|
|
174
267
|
|
|
175
|
-
|
|
176
|
-
or skip status, and the compiler's reasons. These are transform decisions;
|
|
268
|
+
For Babel, the report names observed functions, their project-relative files,
|
|
269
|
+
optimization or skip status, and the compiler's reasons. These are transform decisions;
|
|
177
270
|
server-code removal and tree shaking can later omit a function from the browser
|
|
178
271
|
bundle. Cached transforms retain their
|
|
179
272
|
diagnostics and are identified as reused. Browser and server graphs do not
|
|
@@ -183,6 +276,12 @@ complete application coverage. Disabled compilation is reported explicitly.
|
|
|
183
276
|
The report describes the last successful build, stays outside public assets and
|
|
184
277
|
does not include source code. A failed build preserves the previous report.
|
|
185
278
|
|
|
279
|
+
The Oxc report identifies the backend and package version, records native
|
|
280
|
+
diagnostics at file scope, and states that function optimization totals are
|
|
281
|
+
unavailable: its API does not expose Babel's function-success events. This is
|
|
282
|
+
not a count of zero optimized functions. Cached native diagnostics are replayed;
|
|
283
|
+
cache identities include the backend, compiler version and client/SSR mode.
|
|
284
|
+
|
|
186
285
|
The compiler can skip code that cannot be safely optimized. Follow the Rules of
|
|
187
286
|
React and check actual behavior rather than assuming every component was
|
|
188
287
|
compiled. It reduces repeated component work; it does not guarantee faster
|
|
@@ -192,6 +291,10 @@ production build with the option enabled and disabled. Compilation adds build
|
|
|
192
291
|
work; PRNext caches pure transforms with their compiler version and settings.
|
|
193
292
|
|
|
194
293
|
See the [official React Compiler documentation](https://react.dev/learn/react-compiler).
|
|
294
|
+
The [Oxc React Compiler guide](https://oxc.rs/docs/guide/usage/transformer/react-compiler.html)
|
|
295
|
+
describes the experimental backend. Measure compilation and application behavior
|
|
296
|
+
with the selected backend before adopting it; selecting Rust alone is not a
|
|
297
|
+
measured speedup for a project.
|
|
195
298
|
|
|
196
299
|
Only explicit private Next.js import adapters are supported. Do not add arbitrary
|
|
197
300
|
`next/dist/...` imports or install another Next runtime to satisfy one: isolate
|
|
@@ -236,6 +339,29 @@ by silently adding `--force` or `--legacy-peer-deps`.
|
|
|
236
339
|
can run project code, and installed custom loaders still require a real build.
|
|
237
340
|
The audit is not a sandbox for untrusted projects.
|
|
238
341
|
|
|
342
|
+
The version 2 JSON report follows static imports from project sources into the
|
|
343
|
+
installed packages they reference. It checks explicit PRNext adapters and their
|
|
344
|
+
statically declared named exports, and includes the importing file, line and
|
|
345
|
+
import chain when a dependency uses an unavailable API. It resolves selected
|
|
346
|
+
Node, browser and React Server Component package conditions, including workspace
|
|
347
|
+
symlinks, without importing those package modules. Unreferenced packages are not
|
|
348
|
+
enumerated. Runtime branches, custom loader output and every possible bundler
|
|
349
|
+
condition remain outside this check.
|
|
350
|
+
|
|
351
|
+
A module-level `use server` directive is a server boundary even when a Client
|
|
352
|
+
Component reaches it through a re-export. Its dependencies are still audited in
|
|
353
|
+
the server context. A client dependency on a Node builtin needs an actual browser
|
|
354
|
+
implementation; package `browser` mappings and installed shims are resolved
|
|
355
|
+
before diagnosing it. Custom configuration aliases still require a build with
|
|
356
|
+
that application's configuration.
|
|
357
|
+
|
|
358
|
+
`evidence.state: "checked"` means the selected static graph was inspected, not
|
|
359
|
+
that migration is certified. `"unknown"` identifies unresolved/computed imports,
|
|
360
|
+
loader inputs or incomplete coverage. The graph is bounded to 2,000 modules,
|
|
361
|
+
12,000 imports, 32 MiB of source reads and 32 import hops. Hitting a limit leaves
|
|
362
|
+
the remaining coverage unknown. `ok` means no blocking diagnostic was found;
|
|
363
|
+
inspect warnings and coverage even when it is true.
|
|
364
|
+
|
|
239
365
|
## Compare running applications
|
|
240
366
|
|
|
241
367
|
Start the original application and the candidate on separate available ports.
|
|
@@ -258,6 +384,60 @@ in a real browser, test authorized and unauthorized states, and run the existing
|
|
|
258
384
|
application tests. Keep the original setup available until the candidate is
|
|
259
385
|
actually verified. Timings from this comparison are not controlled benchmarks.
|
|
260
386
|
|
|
387
|
+
## Run application browser scenarios
|
|
388
|
+
|
|
389
|
+
An explicit browser option can run the application's own assertions against
|
|
390
|
+
each server. Install Playwright and its Chromium browser in the application
|
|
391
|
+
using its normal development setup; PRNext never installs them for this check.
|
|
392
|
+
Provide a trusted `.mjs`, `.cjs` or `.js` module inside the application directory:
|
|
393
|
+
|
|
394
|
+
```js
|
|
395
|
+
// migration.scenarios.mjs
|
|
396
|
+
export default [
|
|
397
|
+
{
|
|
398
|
+
async run({page, baseURL}) {
|
|
399
|
+
await page.goto(`${baseURL}/sign-in`);
|
|
400
|
+
await page.getByLabel('Email').fill(process.env.MIGRATION_TEST_EMAIL);
|
|
401
|
+
await page.getByLabel('Password').fill(process.env.MIGRATION_TEST_PASSWORD);
|
|
402
|
+
await page.getByRole('button', {name: 'Sign in', exact: true}).click();
|
|
403
|
+
await page.getByRole('heading', {name: 'Dashboard', exact: true}).waitFor();
|
|
404
|
+
await page.getByRole('button', {name: 'Save note', exact: true}).click();
|
|
405
|
+
await page.getByText('Note saved', {exact: true}).waitFor();
|
|
406
|
+
await page.getByRole('button', {name: 'Sign out', exact: true}).click();
|
|
407
|
+
await page.getByRole('heading', {name: 'Sign in', exact: true}).waitFor();
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
];
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Replace the URLs and accessible names with the application's real controls.
|
|
414
|
+
Supply dedicated test account values through the command's environment rather than
|
|
415
|
+
command arguments or source files. Use isolated test databases: these explicit
|
|
416
|
+
callbacks execute application code and can submit forms or mutate data.
|
|
417
|
+
|
|
418
|
+
```sh
|
|
419
|
+
prnext migrate --check --against http://localhost:3000 --candidate http://localhost:3001 --routes paths.json --browser-scenarios migration.scenarios.mjs --timeout 15000 --json
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
Only this option loads the scenario module and starts a browser. It requires
|
|
423
|
+
the application's installed `playwright` or `@playwright/test`. Each callback
|
|
424
|
+
receives a new isolated browser context for each target. Assert observable
|
|
425
|
+
behavior inside the callback; its return value is ignored. A callback that
|
|
426
|
+
fulfills passes for that target, and a thrown assertion fails. Both targets
|
|
427
|
+
must pass independently; equal durations or response samples are not used to
|
|
428
|
+
infer browser equivalence.
|
|
429
|
+
|
|
430
|
+
The report records scenario numbers, targets and pass/fail results. It excludes
|
|
431
|
+
application console output, raw error messages, request data, cookies and
|
|
432
|
+
screenshots. Read or debug the original application test separately when a
|
|
433
|
+
generic failure needs investigation. Keep credentials out of assertion labels
|
|
434
|
+
and application-managed artifacts too. An unavailable browser or incomplete run
|
|
435
|
+
is reported as unknown. There are at most 20 scenarios, a 100–60,000 ms budget
|
|
436
|
+
per callback, a bounded startup period and a five-minute maximum for the worker.
|
|
437
|
+
A timeout closes its context and ends the run before another target starts.
|
|
438
|
+
The worker also closes its owned browser when it finishes. This is explicit
|
|
439
|
+
execution of trusted test code, not a sandbox for an untrusted module.
|
|
440
|
+
|
|
261
441
|
## Boundaries that often matter
|
|
262
442
|
|
|
263
443
|
React server/client directives in `.mts`/`.cts` are rejected; use `.ts`/`.tsx`.
|
package/docs/ai/deployment.md
CHANGED
|
@@ -8,12 +8,90 @@ Build with the installed PRNext and run the resulting trusted output with its
|
|
|
8
8
|
matching runtime:
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
|
+
prnext check --production
|
|
11
12
|
prnext typecheck
|
|
12
13
|
prnext build
|
|
13
14
|
prnext output --json
|
|
14
15
|
prnext start --hostname 127.0.0.1 --port 3000
|
|
15
16
|
```
|
|
16
17
|
|
|
18
|
+
### Upgrading from 0.1.19-alpha
|
|
19
|
+
|
|
20
|
+
Install matching framework/native versions, then rebuild and restart the complete
|
|
21
|
+
application or standalone output. Keep Node and the React protocol peers aligned
|
|
22
|
+
with this package's metadata. Existing compiler entries are reused only when
|
|
23
|
+
their identities match; never delete `data.sqlite3` or invalidation history to
|
|
24
|
+
perform an upgrade. Read the storage section below before pruning compiler caches.
|
|
25
|
+
|
|
26
|
+
Persistent apps need a supervisor restart too. In a maintenance window for the
|
|
27
|
+
whole `PRNEXT_PM_HOME`, run `prnext pdown` with that same home before replacing
|
|
28
|
+
packages. It stops all managed apps and preserves saved settings and enabled
|
|
29
|
+
entries; `prestart` alone keeps the already loaded supervisor code. Update and
|
|
30
|
+
rebuild the installations that must return with 0.1.20, then launch `pstart` or
|
|
31
|
+
`prestart` through the new CLI. It also restores all enabled entries, with their
|
|
32
|
+
saved binary paths and health routes. Check `pstatus` and real health responses;
|
|
33
|
+
a global CLI update does not replace each app's package or binary. Keep independent
|
|
34
|
+
lifecycles in separate homes.
|
|
35
|
+
|
|
36
|
+
Set `server.publicOrigin` to the external HTTPS origin and `server.trustedProxies`
|
|
37
|
+
to the immediate proxy's IP/CIDR addresses. The configured origin wins; forwarded
|
|
38
|
+
host/protocol headers are trusted only from those peers. Rebuild after config
|
|
39
|
+
changes and check redirects, secure cookies and authentication callbacks over
|
|
40
|
+
the actual public URL. This does not establish a forwarded client-IP chain.
|
|
41
|
+
|
|
42
|
+
Run production preflight, then test account A → sign out → account B with the
|
|
43
|
+
actual `navigationCache.authCookies`, including shared layouts and browser
|
|
44
|
+
history. Changed or unknown strict identities require a fresh document; cached
|
|
45
|
+
PPR previews wait for fresh identity. Authorize protected reads and writes in
|
|
46
|
+
the application as before.
|
|
47
|
+
|
|
48
|
+
Use a dedicated complete HTTP 200 application health response for database/service
|
|
49
|
+
readiness. `/_prnext/health` checks native readiness only; redirects no longer
|
|
50
|
+
pass persistent health checks. Previously saved applications keep their health
|
|
51
|
+
path, so a redirecting `/` must be replaced in the saved persistent settings.
|
|
52
|
+
Observe the post-switch rollback window and exercise an explicit idempotent
|
|
53
|
+
retry; a lost response can follow a successful write, and mutations are never
|
|
54
|
+
automatically replayed. Keep schema changes compatible with the previous server.
|
|
55
|
+
|
|
56
|
+
### Production preflight
|
|
57
|
+
|
|
58
|
+
Run `prnext check --production --json` to collect deployment diagnostics without
|
|
59
|
+
building or rewriting the application. It evaluates the production config and
|
|
60
|
+
environment files, restores the calling process environment afterward, and checks
|
|
61
|
+
installed dependencies, route conventions, the public origin, proxy trust,
|
|
62
|
+
authentication retention settings and active experimental options. JSON diagnostics
|
|
63
|
+
include `code`, `path`, `severity` and an action where one is needed. Errors fail
|
|
64
|
+
the command; warnings require review and do not change its exit status.
|
|
65
|
+
|
|
66
|
+
If a build already exists, preflight also compares its public origin, proxy and
|
|
67
|
+
authentication retention settings with the current config and rejects a development artifact. Rebuild after
|
|
68
|
+
changing deployment settings: `prnext start` reads the selected artifact and does
|
|
69
|
+
not reevaluate the source configuration. Missing output is informational before
|
|
70
|
+
the first build; unreadable existing metadata requires review.
|
|
71
|
+
|
|
72
|
+
For authenticated App Router applications, explicitly list every session cookie
|
|
73
|
+
name, including HTTPS variants used by the authentication library:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
export default {
|
|
77
|
+
navigationCache: {
|
|
78
|
+
authCookies: ['session-cookie-name', '__Secure-session-cookie-name'],
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Replace these example names with the application's actual cookies; PRNext does
|
|
84
|
+
not infer authentication from cookie names. This enables strict retained-page
|
|
85
|
+
state resets when the server's authorization identity changes. Test account A →
|
|
86
|
+
sign out → account B with both active and retained pages, and confirm that private
|
|
87
|
+
drafts disappear. Public applications can review the guidance or disable page
|
|
88
|
+
retention with `navigationCache: false`.
|
|
89
|
+
|
|
90
|
+
A successful preflight checks configuration, not external services or application
|
|
91
|
+
authorization. Qualify the final build over public HTTPS, including authentication,
|
|
92
|
+
health checks, failure recovery and rollback. Experimental warnings identify the
|
|
93
|
+
options that need workload-specific validation; they are not performance claims.
|
|
94
|
+
|
|
17
95
|
The default build directory is `.prnext`; `distDir` can change it. The private
|
|
18
96
|
project output selector is `.prnext-output.json`. Do not assume `.next` layout,
|
|
19
97
|
run `next start` on a PRNext build or hand-edit its manifests to bypass runtime
|
|
@@ -254,6 +332,69 @@ an explicit choice, not a reason to print credentials or copy `.env` into assets
|
|
|
254
332
|
|
|
255
333
|
## Observe before tuning
|
|
256
334
|
|
|
335
|
+
### Installation and disk storage
|
|
336
|
+
|
|
337
|
+
The default installation includes Babel React Compiler support. The Oxc React
|
|
338
|
+
Compiler backend is an optional peer installed explicitly; read the
|
|
339
|
+
[compatibility guide](compatibility.md) before selecting it. Keep optional native
|
|
340
|
+
platform dependencies enabled. The framework's internal Fontkit bundle includes
|
|
341
|
+
its provenance and dependency licenses under `vendor/fontkit`; applications do
|
|
342
|
+
not need a separate Fontkit dependency for `next/font`.
|
|
343
|
+
|
|
344
|
+
Production builds retain one OpenGraph renderer when needed. A bounded analysis
|
|
345
|
+
of the compiled server graph may omit it only when the application can be
|
|
346
|
+
certified not to use `ImageResponse`. Development, Edge, unknown external modules
|
|
347
|
+
and computed loading keep it. No configuration change is needed. Deploy the
|
|
348
|
+
standalone output alone when using `output: 'standalone'`; copying the complete
|
|
349
|
+
ordinary build beside it duplicates those artifacts.
|
|
350
|
+
|
|
351
|
+
Compiler caches share a **256 MiB** retention budget per project:
|
|
352
|
+
|
|
353
|
+
```js
|
|
354
|
+
export default {
|
|
355
|
+
compilationCache: {maxDiskSize: 128 * 1024 * 1024}, // bytes, 0–4 GiB
|
|
356
|
+
};
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
PRNext applies the policy after a build, including failures, and after a clean
|
|
360
|
+
development shutdown. It is a retention target, not a hard filesystem quota:
|
|
361
|
+
active development, pinned V8 workers, busy files or an incomplete bounded scan
|
|
362
|
+
can defer reclamation. Existing per-cache limits still apply. Eviction can make
|
|
363
|
+
the next build slower; evicted downloaded fonts need network access again.
|
|
364
|
+
Large JSON entries use bounded, checksummed compression; old raw records remain
|
|
365
|
+
readable, and corrupt/incompatible records are cache misses.
|
|
366
|
+
|
|
367
|
+
Inspect and preview changes without executing application configuration:
|
|
368
|
+
|
|
369
|
+
```sh
|
|
370
|
+
prnext cache --json
|
|
371
|
+
prnext cache --prune --dry-run --max-bytes 67108864 --json
|
|
372
|
+
prnext cache --prune --max-bytes 67108864
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
The CLI reads the policy saved by the last build. `--max-bytes` overrides only
|
|
376
|
+
that purge; `0` removes eligible compiler records. Statistics cover recognized
|
|
377
|
+
framework cache files, excluding unknown paths; `scanComplete: false` means a
|
|
378
|
+
lower bound and prevents purging from an incomplete snapshot. Stop development
|
|
379
|
+
before purging. Concurrent builds are protected by the publisher lock, active
|
|
380
|
+
managed workers pin their namespace, and failed deletions can be retried.
|
|
381
|
+
|
|
382
|
+
These commands never remove runtime data, `data.sqlite3`, page/image indexes,
|
|
383
|
+
invalidation generations, tags or fill leases. Never delete/reset the data
|
|
384
|
+
database to reclaim compiler storage: that can lose invalidation history. The
|
|
385
|
+
runtime instead performs small incremental SQLite reclamation steps and bounded
|
|
386
|
+
orphan-file maintenance on its own timer. Existing SQLite databases without
|
|
387
|
+
incremental auto-vacuum retain their existing format; no full VACUUM runs on a
|
|
388
|
+
request. Older page files without a verifiable reader lease are retained.
|
|
389
|
+
|
|
390
|
+
Builds and dev sessions also journal their owned temporary directories. After a
|
|
391
|
+
crash, later starts reclaim eligible entries only after a grace period and proof
|
|
392
|
+
that their local owner/workers have exited. Unknown directories, foreign-host or
|
|
393
|
+
unverifiable owners and uncommitted build backups are kept for recovery. Do not
|
|
394
|
+
remove a recovery backup until the selected build has been checked.
|
|
395
|
+
|
|
396
|
+
### Runtime observations
|
|
397
|
+
|
|
257
398
|
Production rendering, API and regeneration admission use bounded queues grouped
|
|
258
399
|
by resolved route pattern. Different parameter values share one pattern's
|
|
259
400
|
waiting budget. Waiting patterns take turns as capacity becomes available;
|
package/docs/ai/quickstart.md
CHANGED
|
@@ -13,6 +13,11 @@ react-server-dom-webpack 19.3.1**. Its Node engine range is
|
|
|
13
13
|
`^22.23.4 || ^24.22.1 || >=26.12.1`. Check the installed package manifest when
|
|
14
14
|
upgrading; these requirements may change between releases.
|
|
15
15
|
|
|
16
|
+
Optional peers are installed only for the features that use them:
|
|
17
|
+
`@redis/client` for [shared Redis caching](data.md), and `oxc-transform-react`
|
|
18
|
+
for the [experimental Oxc React Compiler](compatibility.md#react-compiler).
|
|
19
|
+
The default Babel compiler needs no additional compiler installation.
|
|
20
|
+
|
|
16
21
|
Published releases include a matching native component through optional
|
|
17
22
|
dependencies for Windows, macOS and glibc Linux, on x64 and ARM64. Keep optional
|
|
18
23
|
dependencies enabled. Consumers do not need Rust; building PRNext from its source
|
package/docs/ai/routing.md
CHANGED
|
@@ -88,6 +88,9 @@ Client Components can participate in server rendering. Read `window`,
|
|
|
88
88
|
`useEffect`, not unconditionally during render. Server and first browser render
|
|
89
89
|
must agree. Use `.ts` or `.tsx` for `'use client'` and `'use server'` boundaries;
|
|
90
90
|
PRNext rejects those directives in `.mts`/`.cts` instead of silently misbundling.
|
|
91
|
+
The migration audit reports these unsupported boundaries too. It also checks
|
|
92
|
+
`server-only` and `client-only` markers through imported helpers, respecting
|
|
93
|
+
module-level Server Action boundaries and Node Route Handlers.
|
|
91
94
|
|
|
92
95
|
## Navigation and typed routes
|
|
93
96
|
|
|
@@ -110,6 +113,14 @@ without connection information retain bounded prefetching. `prefetch={false}`
|
|
|
110
113
|
disables Link speculation, including hover and focus. None of these policies
|
|
111
114
|
blocks a real click or changes authorization and private-data checks. App Link
|
|
112
115
|
automatic prefetching retains its existing partial-rendering requirement.
|
|
116
|
+
Set `prefetch={true}` to warm the full destination explicitly in an ordinary
|
|
117
|
+
App Router application without `cacheComponents`. The same network limits
|
|
118
|
+
apply, and development does not prefetch. Full prefetch warms modules and data;
|
|
119
|
+
the click still sends a fresh server request before showing the destination.
|
|
120
|
+
This includes prerendered pages whose access is controlled by a proxy: a
|
|
121
|
+
prefetched response cannot authorize a later navigation after an HttpOnly
|
|
122
|
+
cookie changes. Leave the prop unset to keep automatic behavior, or use `false`
|
|
123
|
+
to disable speculation.
|
|
113
124
|
|
|
114
125
|
### Connection loss during App navigation
|
|
115
126
|
|
|
@@ -2,6 +2,70 @@
|
|
|
2
2
|
|
|
3
3
|
[AI documentation index](../../AI.md)
|
|
4
4
|
|
|
5
|
+
## Compile large client imports only when used in development
|
|
6
|
+
|
|
7
|
+
For App Router applications, the explicit experimental option below keeps
|
|
8
|
+
literal client `import()` targets outside the initial browser graph. It defers
|
|
9
|
+
their transformation and compilation, rather than only downloading an already
|
|
10
|
+
compiled chunk later.
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
// prnext.config.mjs
|
|
14
|
+
export default {
|
|
15
|
+
experimental: { lazyDynamicImports: true }
|
|
16
|
+
};
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The option affects `prnext dev` only. Production keeps its ordinary dynamic
|
|
20
|
+
chunks and does not use a development compilation endpoint. SSR also keeps its
|
|
21
|
+
normal behavior. A `next/dynamic` component with `{ ssr: false }` is a useful
|
|
22
|
+
candidate for an editor or other large browser-only feature; an import needed
|
|
23
|
+
by SSR still needs its server compilation.
|
|
24
|
+
|
|
25
|
+
On first use, the development server compiles the requested subgraph, publishes
|
|
26
|
+
its immutable assets, and loads its CSS before resolving the import. Already
|
|
27
|
+
loaded ESM dependencies are reused through their original module URLs, keeping
|
|
28
|
+
shared objects and live bindings. Once activated, the module participates in
|
|
29
|
+
subsequent JavaScript and stylesheet updates. A failed compilation can be
|
|
30
|
+
requested again after correcting its source.
|
|
31
|
+
|
|
32
|
+
Activated styles remain loaded for the generation, including when parallel
|
|
33
|
+
slots select their own styles. Prefer CSS Modules or selectors scoped to the
|
|
34
|
+
deferred feature when its global styles should not affect other components.
|
|
35
|
+
|
|
36
|
+
The initial scope is App Router applications using the native compiler, with
|
|
37
|
+
same-origin assets and no webpack hook or custom loaders. Literal imports from
|
|
38
|
+
project `.js`, `.jsx`, `.mjs`, `.cjs`, `.ts` and `.tsx` sources are eligible;
|
|
39
|
+
computed imports, import attributes, literal requests containing `?` or `#`,
|
|
40
|
+
imports inside installed packages and typed `.mts`/`.cts` helpers keep the
|
|
41
|
+
ordinary compiler behavior. The compiler keeps the distinct module identities
|
|
42
|
+
of those literal query and fragment imports. If an alias or a transitive
|
|
43
|
+
dependency introduces a resolved query or fragment suffix inside a deferred
|
|
44
|
+
graph, activation returns an explicit error
|
|
45
|
+
before reusing any shared export bridge. Disable the option for that graph;
|
|
46
|
+
query and fragment identities in deferred graphs are not currently supported.
|
|
47
|
+
The compiler does not silently duplicate a shared CommonJS dependency: that
|
|
48
|
+
case returns an explicit error. Convert that shared dependency to ESM or disable
|
|
49
|
+
the option.
|
|
50
|
+
Server Actions first introduced only by a deferred graph also require a static
|
|
51
|
+
import or the ordinary compiler, because the running server implementation
|
|
52
|
+
cannot be extended by publishing browser assets alone.
|
|
53
|
+
|
|
54
|
+
There are at most 128 registered imports and 4,096 static JavaScript dependency
|
|
55
|
+
identities per generation. Deferred assets have a cumulative 128 MiB budget per
|
|
56
|
+
active generation. Existing development request and generation limits still
|
|
57
|
+
apply. Public requests contain opaque registered IDs, never source filenames;
|
|
58
|
+
an unknown ID cannot initiate a deferred compilation. Static ESM export bridges
|
|
59
|
+
have their own startup cost, so measure your application's initial build and
|
|
60
|
+
first-use delay before keeping the option enabled.
|
|
61
|
+
|
|
62
|
+
Deferred JSON imports share their native ESM namespace and default object across
|
|
63
|
+
importers. Deferred assets are written outside the served directory and published
|
|
64
|
+
as complete immutable files. This experimental path requires hardlinks within
|
|
65
|
+
the development generation's filesystem; disable `lazyDynamicImports` if that
|
|
66
|
+
filesystem cannot create them. A failed activation keeps existing assets intact
|
|
67
|
+
and conservatively accounts for any publication whose outcome is uncertain.
|
|
68
|
+
|
|
5
69
|
## Collect a useful failure
|
|
6
70
|
|
|
7
71
|
Read the installed version, command, working directory, Node version, manager,
|
|
@@ -54,6 +118,21 @@ repair. Verify the interactive result after the change.
|
|
|
54
118
|
|
|
55
119
|
## HMR and cache failures
|
|
56
120
|
|
|
121
|
+
When an Action overlaps a refresh or navigation, its mutation result remains
|
|
122
|
+
independent from whether its older render is applied. A newer interaction can
|
|
123
|
+
release a superseded development commit wait; it never replays the mutation.
|
|
124
|
+
|
|
125
|
+
For a development state publication failure, keep the private
|
|
126
|
+
`.prnext-dev/<session>/diagnostics/state-publication.json` receipt. It records the
|
|
127
|
+
operation phase, error code, bounded rename attempts and last published sequence,
|
|
128
|
+
without source contents or a full source path. Windows transient rename failures
|
|
129
|
+
are retried for up to two seconds; a permanent failure preserves the previous
|
|
130
|
+
complete state file. After a replacement runtime has activated, publication
|
|
131
|
+
failure still retires obsolete runtimes through the gateway and keeps the
|
|
132
|
+
existing three-generation snapshot bound. In-flight requests drain before
|
|
133
|
+
their old runtime closes. Record the actual code and phase instead of assuming
|
|
134
|
+
an antivirus or file watcher caused the lock.
|
|
135
|
+
|
|
57
136
|
Development compiles requested routes and preserves state for compatible edits;
|
|
58
137
|
config/environment, custom Document or incompatible module changes can reload
|
|
59
138
|
the document. Production prerendering and compression are not development HMR.
|