@wular/pnext 0.0.1
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 +153 -0
- package/bin/pnext +67 -0
- package/config/lint/base.js +48 -0
- package/config/ts/base.json +26 -0
- package/config/ts/react.json +13 -0
- package/package.json +70 -0
- package/reference/compat.md +63 -0
- package/reference/config.md +120 -0
- package/reference/css.md +58 -0
- package/reference/dev.md +69 -0
- package/reference/env.md +40 -0
- package/reference/metadata.md +86 -0
- package/reference/navigation.md +149 -0
- package/reference/overview.md +35 -0
- package/reference/performance.md +97 -0
- package/reference/rendering.md +127 -0
- package/reference/routing.md +167 -0
- package/reference/typegen.md +64 -0
- package/src/api/cache.ts +80 -0
- package/src/api/client-cache.ts +9 -0
- package/src/api/client-navigation.ts +279 -0
- package/src/api/dynamic.tsx +102 -0
- package/src/api/link.tsx +119 -0
- package/src/api/navigation.ts +198 -0
- package/src/api/router/events.ts +53 -0
- package/src/api/router/history.ts +70 -0
- package/src/api/router/hub.ts +194 -0
- package/src/api/router/policies.ts +107 -0
- package/src/api/router/runtime.ts +5238 -0
- package/src/api/router/types.ts +299 -0
- package/src/api/router.ts +167 -0
- package/src/api/server.ts +323 -0
- package/src/api/suspense.ts +16 -0
- package/src/cache/context.ts +61 -0
- package/src/cli/adapters/vercel-warm.ts +375 -0
- package/src/cli/adapters/vercel.ts +1310 -0
- package/src/cli/analyze-print.ts +181 -0
- package/src/cli/analyze.ts +328 -0
- package/src/cli/boot-trace.ts +29 -0
- package/src/cli/build.ts +3114 -0
- package/src/cli/dev.ts +276 -0
- package/src/cli/index.ts +196 -0
- package/src/cli/named-bin.ts +119 -0
- package/src/cli/serve-ui.ts +160 -0
- package/src/cli/start.ts +1425 -0
- package/src/client/build.ts +2136 -0
- package/src/client/chunk-fold.ts +526 -0
- package/src/client/entry.ts +1525 -0
- package/src/client/paths.ts +22 -0
- package/src/client/prebuilt.ts +621 -0
- package/src/client/profile.ts +75 -0
- package/src/client/react-compiler.ts +94 -0
- package/src/client/reference-stub.ts +145 -0
- package/src/client/reference.ts +47 -0
- package/src/compat/actions/action-client.ts +531 -0
- package/src/compat/actions/action-dispatch.ts +676 -0
- package/src/compat/actions/action-router.ts +40 -0
- package/src/compat/actions/action-shared.ts +95 -0
- package/src/compat/actions/client-plugin.ts +135 -0
- package/src/compat/actions/client-stub.ts +65 -0
- package/src/compat/actions/config.ts +164 -0
- package/src/compat/actions/detect.ts +208 -0
- package/src/compat/actions/discovery.ts +244 -0
- package/src/compat/actions/early-submit.ts +40 -0
- package/src/compat/actions/endpoint.ts +602 -0
- package/src/compat/actions/flight.ts +52 -0
- package/src/compat/actions/form-state.ts +73 -0
- package/src/compat/actions/hoist.ts +485 -0
- package/src/compat/actions/ids.ts +39 -0
- package/src/compat/actions/index.ts +41 -0
- package/src/compat/actions/instances.ts +144 -0
- package/src/compat/actions/origin.ts +109 -0
- package/src/compat/actions/protocol.ts +125 -0
- package/src/compat/actions/registry.ts +74 -0
- package/src/compat/actions/rewrite.ts +282 -0
- package/src/compat/actions/serve.ts +414 -0
- package/src/compat/actions/server-tag.ts +21 -0
- package/src/compat/actions/unrecognized-error.ts +30 -0
- package/src/compat/adapter/build-complete.ts +257 -0
- package/src/compat/bundler/bun-externals.ts +53 -0
- package/src/compat/bundler/cjs-exports.ts +542 -0
- package/src/compat/bundler/config.ts +363 -0
- package/src/compat/bundler/externals.ts +34 -0
- package/src/compat/bundler/import-meta-url.ts +60 -0
- package/src/compat/bundler/modularize-imports.ts +119 -0
- package/src/compat/bundler/new-url-asset.ts +87 -0
- package/src/compat/bundler/optimize-package-imports.ts +273 -0
- package/src/compat/bundler/polyfill.ts +88 -0
- package/src/compat/bundler/react-compiler.ts +61 -0
- package/src/compat/bundler/react-profiler.tsx +25 -0
- package/src/compat/bundler/relay-transform.ts +116 -0
- package/src/compat/bundler/require-context.ts +281 -0
- package/src/compat/bundler/resolve-extensions.ts +75 -0
- package/src/compat/bundler/source-cache.ts +61 -0
- package/src/compat/bundler/static-imports.ts +25 -0
- package/src/compat/bundler/symlink-imports.ts +119 -0
- package/src/compat/bundler/tsconfig-paths.ts +50 -0
- package/src/compat/bundler/wasm.ts +153 -0
- package/src/compat/bundler/webpack-loaders.ts +685 -0
- package/src/compat/bundler/worker.ts +278 -0
- package/src/compat/cache/build-flags.ts +81 -0
- package/src/compat/cache/build-prerender-errors.ts +163 -0
- package/src/compat/cache/custom-handler.ts +159 -0
- package/src/compat/cache/fetch-patch.ts +745 -0
- package/src/compat/cache/handler.ts +100 -0
- package/src/compat/cache/modern-handler.ts +275 -0
- package/src/compat/cache/resume-data-cache.ts +143 -0
- package/src/compat/cache/revalidate.ts +759 -0
- package/src/compat/cache/runtime-error.ts +124 -0
- package/src/compat/cache/use-cache-transform.ts +961 -0
- package/src/compat/cache/use-cache.ts +1695 -0
- package/src/compat/cache-control.ts +269 -0
- package/src/compat/client/base-path.ts +64 -0
- package/src/compat/client/css-order.ts +36 -0
- package/src/compat/client/errors/control-flow.ts +92 -0
- package/src/compat/client/errors/error-boundary.ts +222 -0
- package/src/compat/client/errors/global-error.ts +238 -0
- package/src/compat/client/errors/install.ts +217 -0
- package/src/compat/client/errors/lazy.ts +53 -0
- package/src/compat/client/errors/primitive-throw.ts +126 -0
- package/src/compat/client/errors/soft-refresh.ts +14 -0
- package/src/compat/client/link-status.ts +86 -0
- package/src/compat/client/nav-compat-runtime.ts +57 -0
- package/src/compat/client/nav-compat.ts +42 -0
- package/src/compat/client/navigation-scroll.ts +154 -0
- package/src/compat/client/optimistic-routing.ts +206 -0
- package/src/compat/client/prefetch-cache.ts +111 -0
- package/src/compat/client/route-announcer.ts +72 -0
- package/src/compat/client/segment-cache-policy.ts +159 -0
- package/src/compat/client/segment-cache.ts +1077 -0
- package/src/compat/client/segment-prefetch.ts +375 -0
- package/src/compat/client/trailing-slash.ts +24 -0
- package/src/compat/css/chunking.ts +254 -0
- package/src/compat/css/inline-css.ts +73 -0
- package/src/compat/css/lightningcss.ts +90 -0
- package/src/compat/css/modules.ts +373 -0
- package/src/compat/css/nonce.ts +30 -0
- package/src/compat/css/sass-plugin.ts +65 -0
- package/src/compat/css/sass.ts +392 -0
- package/src/compat/css/styled-jsx-runtime.ts +80 -0
- package/src/compat/css/styled-jsx.ts +49 -0
- package/src/compat/edge-runtime.ts +71 -0
- package/src/compat/export/client.ts +112 -0
- package/src/compat/export/index.ts +272 -0
- package/src/compat/export/standalone.ts +207 -0
- package/src/compat/image-optimizer/cache.ts +119 -0
- package/src/compat/image-optimizer/detect.ts +143 -0
- package/src/compat/image-optimizer/index.ts +601 -0
- package/src/compat/image-optimizer/source.ts +243 -0
- package/src/compat/index.ts +458 -0
- package/src/compat/lifecycle/after-scope.ts +86 -0
- package/src/compat/lifecycle/after.ts +173 -0
- package/src/compat/lifecycle/error-funnel.ts +306 -0
- package/src/compat/lifecycle/error-serialize.ts +87 -0
- package/src/compat/lifecycle/error-ui.ts +167 -0
- package/src/compat/lifecycle/instrumentation-client.ts +138 -0
- package/src/compat/lifecycle/instrumentation.ts +277 -0
- package/src/compat/lifecycle/node-console.ts +19 -0
- package/src/compat/lifecycle/testmode.ts +263 -0
- package/src/compat/mdx/compile.ts +219 -0
- package/src/compat/mdx/next-mdx-stub.ts +46 -0
- package/src/compat/mdx/plugin.ts +37 -0
- package/src/compat/metadata-route-artifacts.ts +458 -0
- package/src/compat/metadata.ts +295 -0
- package/src/compat/middleware/manifest.ts +210 -0
- package/src/compat/misc/action-return.ts +173 -0
- package/src/compat/next/cache.ts +211 -0
- package/src/compat/next/canonical-url.ts +35 -0
- package/src/compat/next/client-cache.ts +57 -0
- package/src/compat/next/client-navigation.ts +313 -0
- package/src/compat/next/client-only.ts +3 -0
- package/src/compat/next/client-script.tsx +215 -0
- package/src/compat/next/client-server.ts +39 -0
- package/src/compat/next/config-loader.ts +569 -0
- package/src/compat/next/config.ts +29 -0
- package/src/compat/next/constants.cjs +6 -0
- package/src/compat/next/constants.ts +6 -0
- package/src/compat/next/custom-server.ts +236 -0
- package/src/compat/next/dist/client/components/app-router-headers.ts +32 -0
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +38 -0
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -0
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -0
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -0
- package/src/compat/next/dynamic.tsx +46 -0
- package/src/compat/next/error.tsx +148 -0
- package/src/compat/next/font/cache.ts +171 -0
- package/src/compat/next/font/google.ts +2 -0
- package/src/compat/next/font/index.ts +8 -0
- package/src/compat/next/font/local.ts +5 -0
- package/src/compat/next/font/runtime-client.ts +71 -0
- package/src/compat/next/font/runtime.ts +974 -0
- package/src/compat/next/font/shared.ts +281 -0
- package/src/compat/next/form.tsx +156 -0
- package/src/compat/next/head.tsx +10 -0
- package/src/compat/next/headers.ts +247 -0
- package/src/compat/next/image/config.ts +196 -0
- package/src/compat/next/image/optimizer.ts +96 -0
- package/src/compat/next/image/patterns.ts +103 -0
- package/src/compat/next/image/shared.ts +141 -0
- package/src/compat/next/image/static-metadata.ts +283 -0
- package/src/compat/next/image/validate.ts +269 -0
- package/src/compat/next/image-client.tsx +215 -0
- package/src/compat/next/image-props.ts +575 -0
- package/src/compat/next/image-usage.ts +102 -0
- package/src/compat/next/image.tsx +56 -0
- package/src/compat/next/index.ts +1 -0
- package/src/compat/next/legacy-image.tsx +97 -0
- package/src/compat/next/link-usage.ts +29 -0
- package/src/compat/next/link-validation-transform.ts +200 -0
- package/src/compat/next/link.tsx +466 -0
- package/src/compat/next/navigation.cjs +21 -0
- package/src/compat/next/navigation.ts +188 -0
- package/src/compat/next/offline.ts +51 -0
- package/src/compat/next/og.ts +324 -0
- package/src/compat/next/optimistic-route-state.ts +188 -0
- package/src/compat/next/preferred-region.ts +39 -0
- package/src/compat/next/redirects.ts +131 -0
- package/src/compat/next/resource-hints.ts +136 -0
- package/src/compat/next/rewrites.ts +350 -0
- package/src/compat/next/root-params.ts +142 -0
- package/src/compat/next/router.cjs +49 -0
- package/src/compat/next/router.ts +143 -0
- package/src/compat/next/script.tsx +355 -0
- package/src/compat/next/server-only.ts +3 -0
- package/src/compat/next/server.ts +28 -0
- package/src/compat/next/svgr.ts +58 -0
- package/src/compat/next/telemetry.ts +77 -0
- package/src/compat/next/user-agent.ts +100 -0
- package/src/compat/next/web-vitals.ts +56 -0
- package/src/compat/otel/api.ts +95 -0
- package/src/compat/otel/client-trace-metadata.ts +71 -0
- package/src/compat/otel/fetch-span.ts +77 -0
- package/src/compat/otel/tracer.ts +944 -0
- package/src/compat/pages/client-plugin.ts +108 -0
- package/src/compat/pages/index.ts +527 -0
- package/src/compat/pages/router-state.ts +94 -0
- package/src/compat/ppr/io.ts +38 -0
- package/src/compat/ppr/missing-root-params.ts +105 -0
- package/src/compat/ppr/root-params-scan.ts +164 -0
- package/src/compat/ppr/root-params-transform.ts +75 -0
- package/src/compat/ppr/root-params.ts +129 -0
- package/src/compat/ppr/segment-config-incompat.ts +34 -0
- package/src/compat/protocol.ts +202 -0
- package/src/compat/react/client.ts +59 -0
- package/src/compat/react/compiler-runtime.ts +60 -0
- package/src/compat/react/dom-client.ts +115 -0
- package/src/compat/react/dom-react-server.ts +20 -0
- package/src/compat/react/dom-server.ts +40 -0
- package/src/compat/react/dom.ts +154 -0
- package/src/compat/react/preact.ts +522 -0
- package/src/compat/react/react-server.ts +84 -0
- package/src/compat/react/router-shim.ts +26 -0
- package/src/compat/react/server-component-use.ts +48 -0
- package/src/compat/react/server-inserted-html.ts +87 -0
- package/src/compat/react/server.ts +156 -0
- package/src/compat/react/view-transition.ts +60 -0
- package/src/compat/register/actions.ts +875 -0
- package/src/compat/register/boot.ts +141 -0
- package/src/compat/register/build-tier.ts +11 -0
- package/src/compat/register/build.ts +182 -0
- package/src/compat/register/bundler.ts +587 -0
- package/src/compat/register/cache.ts +85 -0
- package/src/compat/register/client-errors.ts +18 -0
- package/src/compat/register/config.ts +17 -0
- package/src/compat/register/css-extras.ts +120 -0
- package/src/compat/register/edge-runtime.ts +6 -0
- package/src/compat/register/errors.ts +46 -0
- package/src/compat/register/export.ts +23 -0
- package/src/compat/register/font.ts +36 -0
- package/src/compat/register/hooks.ts +34 -0
- package/src/compat/register/image.ts +133 -0
- package/src/compat/register/index.ts +111 -0
- package/src/compat/register/instrumentation-client.ts +35 -0
- package/src/compat/register/lifecycle.ts +86 -0
- package/src/compat/register/mdx.ts +48 -0
- package/src/compat/register/middleware.ts +36 -0
- package/src/compat/register/misc.ts +44 -0
- package/src/compat/register/otel.ts +288 -0
- package/src/compat/register/pages-api.ts +473 -0
- package/src/compat/register/ppr.ts +56 -0
- package/src/compat/register/protocol.ts +57 -0
- package/src/compat/register/proxy.ts +127 -0
- package/src/compat/register/render.ts +268 -0
- package/src/compat/register/routing.ts +410 -0
- package/src/compat/register/segment.ts +1903 -0
- package/src/compat/register/static-image.ts +21 -0
- package/src/compat/register/typed-routes.ts +35 -0
- package/src/compat/register/usecache.ts +131 -0
- package/src/compat/register/validation.ts +56 -0
- package/src/compat/segment/loading-boundary.ts +113 -0
- package/src/compat/segment/page-slot.ts +200 -0
- package/src/compat/segment/tree.ts +481 -0
- package/src/compat/segment/vary-key.ts +102 -0
- package/src/compat/segment/vary-params.ts +551 -0
- package/src/compat/static-params.ts +33 -0
- package/src/compat/tsconfig-defaults.ts +301 -0
- package/src/compat/typecheck/index.ts +1481 -0
- package/src/compat/typecheck/worker.ts +26 -0
- package/src/compat/typed-routes/index.ts +92 -0
- package/src/compat/typed-routes/manifest.ts +356 -0
- package/src/compat/typed-routes/typegen.ts +566 -0
- package/src/compat/validation/errors.ts +159 -0
- package/src/compat/validation/index.ts +1770 -0
- package/src/compat/validation/prerender-diagnostics.ts +1508 -0
- package/src/compat-bootstrap.ts +67 -0
- package/src/config.ts +218 -0
- package/src/css/build.ts +697 -0
- package/src/css/index.ts +2 -0
- package/src/css/postcss.ts +236 -0
- package/src/css/worker.ts +34 -0
- package/src/dev/client-actions.ts +35 -0
- package/src/dev/client-chunk-store.ts +92 -0
- package/src/dev/client-key-cache.ts +178 -0
- package/src/dev/global-css-cache.ts +212 -0
- package/src/dev/imports.ts +2430 -0
- package/src/dev/module-cache.ts +721 -0
- package/src/dev/module-generations.ts +38 -0
- package/src/dev/module-transform.ts +188 -0
- package/src/dev/node-module-bundle-cache.ts +63 -0
- package/src/dev/restart-cache.ts +10 -0
- package/src/dev/route-bundle-key-cache.ts +154 -0
- package/src/dev/route-facts-cache.ts +223 -0
- package/src/dev/server.ts +1710 -0
- package/src/dynamic/source.ts +307 -0
- package/src/dynamic/tree-shake.ts +262 -0
- package/src/env.ts +92 -0
- package/src/extensions.ts +1898 -0
- package/src/index.ts +34 -0
- package/src/internal.ts +43 -0
- package/src/islands/boundary-error.ts +8 -0
- package/src/islands/static-children.ts +37 -0
- package/src/islands/static-slots.ts +106 -0
- package/src/ppr-postpone.ts +24 -0
- package/src/ppr.ts +784 -0
- package/src/proxy.ts +752 -0
- package/src/render/hooks.ts +384 -0
- package/src/render/index.ts +1 -0
- package/src/render/island-context.ts +47 -0
- package/src/render/metadata.ts +857 -0
- package/src/render/renderer.ts +7391 -0
- package/src/render/resource-hints.ts +44 -0
- package/src/render/slots.tsx +679 -0
- package/src/request/context.ts +396 -0
- package/src/resolve/engine.ts +219 -0
- package/src/resolve/imports.ts +1104 -0
- package/src/resolve/scan-facts.ts +474 -0
- package/src/resolve/source-text.ts +86 -0
- package/src/routing/forwarded.ts +41 -0
- package/src/routing/handler.ts +271 -0
- package/src/routing/href.ts +203 -0
- package/src/routing/metadata.ts +1018 -0
- package/src/routing/request-runtime.ts +43 -0
- package/src/routing/routes.ts +2560 -0
- package/src/routing/slots.ts +432 -0
- package/src/runtime/server.ts +3453 -0
- package/src/runtime/vendor.ts +1160 -0
- package/src/style-modules.d.ts +9 -0
- package/src/typegen.ts +151 -0
- package/src/types.ts +725 -0
- package/src/utils/ansi.ts +9 -0
- package/src/utils/content-type.ts +31 -0
- package/src/utils/decode.ts +7 -0
- package/src/utils/dev-profile.ts +31 -0
- package/src/utils/error-log.ts +29 -0
- package/src/utils/fs-cache.ts +31 -0
- package/src/utils/fs.ts +119 -0
- package/src/utils/html.ts +46 -0
- package/src/utils/serialize.ts +378 -0
- package/src/utils/source.ts +35 -0
- package/src/utils/verbose.ts +39 -0
- package/tsconfig.json +10 -0
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
// Bundler-feature registration (COMPAT - may import core freely).
|
|
2
|
+
//
|
|
3
|
+
// Wires the bundler features into core's bundler seams. All are gated on compat.next, so a pure-core app
|
|
4
|
+
// registers nothing.
|
|
5
|
+
//
|
|
6
|
+
// Features wired here:
|
|
7
|
+
// react-server / next-js conditions -> setServerBundleConditions (core always adds `react-server`;
|
|
8
|
+
// `next-js` gates on cacheComponents)
|
|
9
|
+
// compiler.define / defineServer -> registerServerSourceTransforms (the server graph inlines both;
|
|
10
|
+
// the client graph, owned elsewhere, inlines only `define`)
|
|
11
|
+
// serverExternalPackages/transpile -> setExternalPackagePolicy
|
|
12
|
+
// resolveExtensions -> setResolveExtensions
|
|
13
|
+
//
|
|
14
|
+
// Ownership boundary: the CLIENT-side `compiler.define` merge lives in client/build.ts, not here - this
|
|
15
|
+
// file only handles the SERVER graph.
|
|
16
|
+
|
|
17
|
+
import { realpathSync } from 'node:fs';
|
|
18
|
+
import { readFile } from 'node:fs/promises';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
import type { OnLoadResult, Plugin } from 'esbuild';
|
|
21
|
+
import type { ResolvedConfig } from '../../config';
|
|
22
|
+
import type { ServerEsbuildPluginOptions } from '../../extensions';
|
|
23
|
+
import { compatAliases, nextCompatEnabled, rewriteNextFontSource } from '../../compat';
|
|
24
|
+
import {
|
|
25
|
+
getBundlerExtensions,
|
|
26
|
+
getCompatModeExtensions,
|
|
27
|
+
registerClientSourceAsyncPreTransforms,
|
|
28
|
+
registerClientSourceTransforms,
|
|
29
|
+
registerServerSourcePreTransforms,
|
|
30
|
+
registerServerSourceTransforms,
|
|
31
|
+
setAssetExtensions,
|
|
32
|
+
setBundlerExtensions,
|
|
33
|
+
setCompatModeExtensions,
|
|
34
|
+
withSniff,
|
|
35
|
+
} from '../../extensions';
|
|
36
|
+
import {
|
|
37
|
+
isEsmModuleFile,
|
|
38
|
+
isWorkspacePackage,
|
|
39
|
+
packageNameForFile,
|
|
40
|
+
packageNameOfSpecifier,
|
|
41
|
+
resolvePackageImportSpecifier,
|
|
42
|
+
resolvePackageSpecifier,
|
|
43
|
+
setExternalLoadResolver,
|
|
44
|
+
setExternalPackagePolicy,
|
|
45
|
+
setResolveExtensions,
|
|
46
|
+
setTsConfigPath,
|
|
47
|
+
} from '../../resolve/imports';
|
|
48
|
+
import { setServerBundleConditions } from '../../runtime/server';
|
|
49
|
+
import { escapeRegex, specifierSniffTokens } from '../../utils/source';
|
|
50
|
+
import {
|
|
51
|
+
cacheComponentsEnabled,
|
|
52
|
+
compilerDefines,
|
|
53
|
+
esmExternals,
|
|
54
|
+
modularizeImports,
|
|
55
|
+
optimizePackageImports,
|
|
56
|
+
publicRuntimeConfig,
|
|
57
|
+
reactCompilerEnabled,
|
|
58
|
+
relayCompilerConfig,
|
|
59
|
+
removeConsoleTargets,
|
|
60
|
+
resolveExtensions,
|
|
61
|
+
serverExternalPackages,
|
|
62
|
+
swcEnvUsageMode,
|
|
63
|
+
tsconfigPath,
|
|
64
|
+
transpilePackages,
|
|
65
|
+
turbopackResolveAlias,
|
|
66
|
+
} from '../bundler/config';
|
|
67
|
+
import { createModularizeImportsTransform } from '../bundler/modularize-imports';
|
|
68
|
+
import {
|
|
69
|
+
createOptimizePackageImportsTransform,
|
|
70
|
+
optimizedPackageSet,
|
|
71
|
+
} from '../bundler/optimize-package-imports';
|
|
72
|
+
import { createRelayTransform } from '../bundler/relay-transform';
|
|
73
|
+
import {
|
|
74
|
+
polyfillsChunkFileName,
|
|
75
|
+
POLYFILLS_NOMODULE_SOURCE,
|
|
76
|
+
POLYFILL_USAGE_TOKENS,
|
|
77
|
+
rewriteUsagePolyfillImports,
|
|
78
|
+
} from '../bundler/polyfill';
|
|
79
|
+
import { rewriteBunBuiltinExternals } from '../bundler/bun-externals';
|
|
80
|
+
import { clientExternalPackageResolvePlugin } from '../bundler/externals';
|
|
81
|
+
import {
|
|
82
|
+
clientDynamicCommonJsImportsPlugin,
|
|
83
|
+
clientReferenceLoad,
|
|
84
|
+
commonJsDefaultInteropPlugin,
|
|
85
|
+
commonJsInteropEntry,
|
|
86
|
+
recoverCommonJsNamedExportsPlugin,
|
|
87
|
+
rewriteClientDynamicImportPromises,
|
|
88
|
+
rewriteStaticCommonJsNamespaceImports,
|
|
89
|
+
} from '../bundler/cjs-exports';
|
|
90
|
+
import { rewriteImportMetaUrlSource } from '../bundler/import-meta-url';
|
|
91
|
+
import {
|
|
92
|
+
rewriteNewUrlAssetClientSource,
|
|
93
|
+
rewriteNewUrlAssetSource,
|
|
94
|
+
} from '../bundler/new-url-asset';
|
|
95
|
+
import { rewriteReactProfilerImport } from '../bundler/react-compiler';
|
|
96
|
+
import { rewriteRequireContextSource } from '../bundler/require-context';
|
|
97
|
+
import { clientResolveExtensionsPlugin } from '../bundler/resolve-extensions';
|
|
98
|
+
import { tsconfigPathsPlugin } from '../bundler/tsconfig-paths';
|
|
99
|
+
import { fileMemoAsync } from '../bundler/source-cache';
|
|
100
|
+
import { serverSymlinkImportPlugin, symlinkedImportsPossible } from '../bundler/symlink-imports';
|
|
101
|
+
import { registerWasmModuleRuntime, wasmModulePlugin } from '../bundler/wasm';
|
|
102
|
+
import {
|
|
103
|
+
hasWebpackLoaderRuleFor,
|
|
104
|
+
registerWebpackLoaderRuleRuntime,
|
|
105
|
+
rewriteResolveAliasImports,
|
|
106
|
+
webpackLoaderRuleModule,
|
|
107
|
+
webpackLoaderRulesPlugin,
|
|
108
|
+
} from '../bundler/webpack-loaders';
|
|
109
|
+
import { rewriteStaticCompatImports } from '../bundler/static-imports';
|
|
110
|
+
import { createClientWorkerTransform } from '../bundler/worker';
|
|
111
|
+
import { rewriteStyledJsxSource } from '../css/styled-jsx';
|
|
112
|
+
import { getImagesConfig } from '../next/image/config';
|
|
113
|
+
import { appUsesBlurPlaceholder } from '../next/image-usage';
|
|
114
|
+
import { appUsesLegacyLink } from '../next/link-usage';
|
|
115
|
+
import { rewriteLegacyLinkValidation } from '../next/link-validation-transform';
|
|
116
|
+
import { pagesClientModulePlugin } from '../pages/client-plugin';
|
|
117
|
+
|
|
118
|
+
export function registerBundlerExtensions(config: ResolvedConfig): void {
|
|
119
|
+
// The alias registries (setImportAliasExtensions + setModuleAliases) are boot
|
|
120
|
+
// facts — the route scanner and the server runtime latch them before the
|
|
121
|
+
// first compile, so register-boot.ts owns them.
|
|
122
|
+
if (!nextCompatEnabled(config)) return;
|
|
123
|
+
|
|
124
|
+
// B3: user-configured resolver extension order (empty -> core default). The
|
|
125
|
+
// server resolver consumes it via setResolveExtensions; the client esbuild
|
|
126
|
+
// graph gets a probe plugin applying the same order (registered further down
|
|
127
|
+
// with the other client plugins, only when configured).
|
|
128
|
+
const configuredExtensions = resolveExtensions();
|
|
129
|
+
setResolveExtensions(configuredExtensions);
|
|
130
|
+
// A custom `typescript.tsconfigPath` keeps compiler `paths` in a
|
|
131
|
+
// non-default file esbuild never discovers; the client build then needs an
|
|
132
|
+
// explicit resolver plugin (server graph consults setTsConfigPath directly).
|
|
133
|
+
const customTsconfigPath = tsconfigPath();
|
|
134
|
+
setTsConfigPath(customTsconfigPath ? path.resolve(config.root, customTsconfigPath) : undefined);
|
|
135
|
+
|
|
136
|
+
// `turbopack.rules` loader chains: the esbuild-plugin form (webpackLoaderPlugins
|
|
137
|
+
// below) only covers the vendor/client build() passes. The server runtime's
|
|
138
|
+
// per-file SSR loading goes through Bun's own require hooks instead, so a
|
|
139
|
+
// configured rule extension without other pnext handling (e.g. `*.txt`) needs
|
|
140
|
+
// its own registration to preempt Bun's native fallback loader.
|
|
141
|
+
registerWebpackLoaderRuleRuntime(config);
|
|
142
|
+
// Same story for a bare `.wasm` import the server runtime loads directly (a
|
|
143
|
+
// `this.importModule()` target's graph): Bun's native loader has no named
|
|
144
|
+
// exports, so the runtime needs its own instantiating hook.
|
|
145
|
+
registerWasmModuleRuntime(config);
|
|
146
|
+
// A configured loader rule for an image/asset extension must preempt core's generic image/asset
|
|
147
|
+
// resolver so the loader chain runs; core consults `hasLoaderRuleFor` before claiming the extension for
|
|
148
|
+
// its own pipeline, then pulls the chain's output through `loaderRuleModule` - the server graph compiles
|
|
149
|
+
// module-by-module, so there is no onLoad to run it in.
|
|
150
|
+
setAssetExtensions({
|
|
151
|
+
hasLoaderRuleFor: hasWebpackLoaderRuleFor,
|
|
152
|
+
loaderRuleModule: (specifier, importer) => webpackLoaderRuleModule(config, specifier, importer),
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// B7: external/transpile package policy consulted by the server compile sites.
|
|
156
|
+
const externals = serverExternalPackages();
|
|
157
|
+
const transpile = new Set(transpilePackages());
|
|
158
|
+
setExternalPackagePolicy({
|
|
159
|
+
external: name => externals.has(name),
|
|
160
|
+
transpile: name =>
|
|
161
|
+
!externals.has(name) && (transpile.has(name) || isLinkedWorkspacePackage(config, name)),
|
|
162
|
+
// Linked workspace packages are deliberately absent: esbuild resolves their
|
|
163
|
+
// symlinks to real paths, so they never reach a filter as node_modules.
|
|
164
|
+
transpiled: () => [...transpile].filter(name => !externals.has(name)),
|
|
165
|
+
esmExternals,
|
|
166
|
+
});
|
|
167
|
+
setExternalLoadResolver(({ root, fromFile, specifier, target }) => {
|
|
168
|
+
const packageName = specifier.startsWith('#')
|
|
169
|
+
? packageNameForFile(fromFile)
|
|
170
|
+
: packageNameOfSpecifier(specifier);
|
|
171
|
+
if (!packageName || !externals.has(packageName)) return undefined;
|
|
172
|
+
|
|
173
|
+
const conditions =
|
|
174
|
+
target === 'client'
|
|
175
|
+
? ['import', 'browser', 'require', 'default']
|
|
176
|
+
: target === 'edge'
|
|
177
|
+
? ['react-server', 'edge-light', 'browser', 'module', 'import', 'default']
|
|
178
|
+
: ['node', 'import', 'default'];
|
|
179
|
+
if (specifier.startsWith('#')) {
|
|
180
|
+
return resolvePackageImportSpecifier(root, fromFile, specifier, conditions);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const imported = resolvePackageSpecifier(root, fromFile, specifier, conditions);
|
|
184
|
+
if (target === 'client' || !imported || esmExternals() !== true || isEsmModuleFile(imported)) {
|
|
185
|
+
return imported;
|
|
186
|
+
}
|
|
187
|
+
const requireConditions =
|
|
188
|
+
target === 'edge'
|
|
189
|
+
? ['react-server', 'edge-light', 'browser', 'module', 'require', 'import', 'default']
|
|
190
|
+
: ['node', 'require', 'default'];
|
|
191
|
+
return resolvePackageSpecifier(root, fromFile, specifier, requireConditions) ?? imported;
|
|
192
|
+
});
|
|
193
|
+
// B4/B5(next-js): rendering follows it only with Cache Components; core
|
|
194
|
+
// adds react-server for server vendor bundles.
|
|
195
|
+
setServerBundleConditions(() => (cacheComponentsEnabled() ? ['next-js'] : []));
|
|
196
|
+
|
|
197
|
+
// modularizeImports: split barrel `import { A, B } from '<spec>'` into
|
|
198
|
+
// per-member imports BEFORE path-alias resolution, so the emitted specifiers
|
|
199
|
+
// still flow through tsconfig `paths`. Registered as a server pre-transform
|
|
200
|
+
// (runs ahead of the static-compat alias rewrites below) and a client
|
|
201
|
+
// transform; a no-op when unconfigured.
|
|
202
|
+
const modularize = modularizeImports();
|
|
203
|
+
if (Object.keys(modularize).length > 0) {
|
|
204
|
+
const modularizeTransform = createModularizeImportsTransform(modularize);
|
|
205
|
+
registerServerSourcePreTransforms(modularizeTransform);
|
|
206
|
+
registerClientSourceTransforms(modularizeTransform);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// optimizePackageImports: rewrite a barrel package's named imports to the leaf modules its entry
|
|
210
|
+
// re-exports them from, so the vendor pipeline compiles - and the server evaluates - only what the
|
|
211
|
+
// route named. Same chain position as modularizeImports, so the emitted leaf specifiers still flow
|
|
212
|
+
// through alias/path resolution.
|
|
213
|
+
const optimizedPackages = optimizedPackageSet(optimizePackageImports());
|
|
214
|
+
const optimizeTransform = createOptimizePackageImportsTransform(optimizedPackages, config.root);
|
|
215
|
+
registerServerSourcePreTransforms(optimizeTransform);
|
|
216
|
+
registerClientSourceTransforms(optimizeTransform);
|
|
217
|
+
|
|
218
|
+
// compiler.relay: replace `graphql`...`` tagged templates with the artifact
|
|
219
|
+
// relay-compiler generated for the operation. Registered as a pre-transform
|
|
220
|
+
// for the same reason modularizeImports is — the injected artifact imports
|
|
221
|
+
// must still flow through alias/path resolution.
|
|
222
|
+
const relay = relayCompilerConfig();
|
|
223
|
+
if (relay) {
|
|
224
|
+
const relayTransform = createRelayTransform(relay);
|
|
225
|
+
registerServerSourcePreTransforms(relayTransform);
|
|
226
|
+
registerClientSourceTransforms(relayTransform);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Next font/root-params rewrites must precede generic server transforms.
|
|
230
|
+
const fontSniff = ['next/font', 'next/root-params'];
|
|
231
|
+
registerServerSourcePreTransforms(
|
|
232
|
+
withSniff(fontSniff, (source, file, root) =>
|
|
233
|
+
rewriteNextFontSource(source, file, 'server', root),
|
|
234
|
+
),
|
|
235
|
+
);
|
|
236
|
+
registerClientSourceTransforms(
|
|
237
|
+
withSniff(fontSniff, (source, file, root) =>
|
|
238
|
+
rewriteNextFontSource(source, file, 'client', root),
|
|
239
|
+
),
|
|
240
|
+
);
|
|
241
|
+
const linkSniff = ['Link', 'legacyBehavior'];
|
|
242
|
+
registerServerSourcePreTransforms(withSniff(linkSniff, rewriteLegacyLinkValidation));
|
|
243
|
+
registerClientSourceTransforms(withSniff(linkSniff, rewriteLegacyLinkValidation));
|
|
244
|
+
registerServerSourcePreTransforms(withSniff(['<style'], rewriteStyledJsxSource));
|
|
245
|
+
registerClientSourceTransforms(withSniff(['<style'], rewriteStyledJsxSource));
|
|
246
|
+
registerServerSourceTransforms(withSniff(["'bun", '"bun'], rewriteBunBuiltinExternals));
|
|
247
|
+
// Materialized fixtures can re-import original sources outside esbuild's
|
|
248
|
+
// alias graph. Keep their static compat imports on the registered facades.
|
|
249
|
+
// Leave React entrypoints for the resolver: RSC/proxy/middleware needs the
|
|
250
|
+
// stricter react-server-layer overrides instead of the ordinary shims.
|
|
251
|
+
const staticServerAliases = compatAliases(config, 'server');
|
|
252
|
+
delete staticServerAliases.react;
|
|
253
|
+
delete staticServerAliases['react-dom'];
|
|
254
|
+
// The CJS facades live in compat/next, one level up from this register dir.
|
|
255
|
+
const nextRoot = path.resolve(import.meta.dirname, '..', 'next');
|
|
256
|
+
const requireAliases = {
|
|
257
|
+
'next/navigation': path.join(nextRoot, 'navigation.cjs'),
|
|
258
|
+
'next/router': path.join(nextRoot, 'router.cjs'),
|
|
259
|
+
};
|
|
260
|
+
registerServerSourceTransforms(
|
|
261
|
+
withSniff(
|
|
262
|
+
specifierSniffTokens([...Object.keys(staticServerAliases), ...Object.keys(requireAliases)]),
|
|
263
|
+
(source, file) => rewriteStaticCompatImports(source, file, staticServerAliases, requireAliases),
|
|
264
|
+
),
|
|
265
|
+
);
|
|
266
|
+
const namespaceImportSniff = [/import\s+\*/];
|
|
267
|
+
registerServerSourceTransforms(withSniff(namespaceImportSniff, rewriteStaticCommonJsNamespaceImports));
|
|
268
|
+
// `turbopack.resolveAlias` bare specifiers: the esbuild/Bun onResolve hooks
|
|
269
|
+
// cover the graphs they own, but Bun's runtime resolver rejects an unknown
|
|
270
|
+
// bare package before plugins run, so modules the server runtime loads
|
|
271
|
+
// directly (a `this.importModule()` target's transitive imports) need the
|
|
272
|
+
// alias applied in source.
|
|
273
|
+
registerServerSourceTransforms(
|
|
274
|
+
withSniff(specifierSniffTokens(Object.keys(turbopackResolveAlias())), (source, file) =>
|
|
275
|
+
rewriteResolveAliasImports(source, file, config.root),
|
|
276
|
+
),
|
|
277
|
+
);
|
|
278
|
+
registerClientSourceTransforms(withSniff(namespaceImportSniff, rewriteStaticCommonJsNamespaceImports));
|
|
279
|
+
|
|
280
|
+
// B5: compiler.define + compiler.defineServer, both graphs, through the
|
|
281
|
+
// bundler's own `define`. The server graph inlines both; the client graph
|
|
282
|
+
// inlines `define` and folds `defineServer` keys to `undefined` so client
|
|
283
|
+
// fallback branches stay reachable. `define` wins a key present in both.
|
|
284
|
+
const { define, defineServer } = compilerDefines();
|
|
285
|
+
const serverDefines = { ...define, ...defineServer };
|
|
286
|
+
const clientDefines = {
|
|
287
|
+
...Object.fromEntries(Object.keys(defineServer).map(key => [key, 'undefined'])),
|
|
288
|
+
...define,
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// B5: compiler.removeConsole — strip console.* calls from the client graph
|
|
292
|
+
// via esbuild's `pure` option (unused-result calls are dropped in the
|
|
293
|
+
// minified production build).
|
|
294
|
+
const removeConsole = removeConsoleTargets();
|
|
295
|
+
|
|
296
|
+
// experimental.swcEnvOptions: core-js polyfills for the targeted features, on
|
|
297
|
+
// the client graph only — the server graph runs on the current Node/Bun and
|
|
298
|
+
// needs no polyfill.
|
|
299
|
+
if (swcEnvUsageMode()) {
|
|
300
|
+
registerClientSourceTransforms(
|
|
301
|
+
withSniff(POLYFILL_USAGE_TOKENS, (source, file) =>
|
|
302
|
+
rewriteUsagePolyfillImports(source, file, config),
|
|
303
|
+
),
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// B: `new URL('./asset.png', import.meta.url)` -> emitted /_next/static/media
|
|
308
|
+
// URL (matching `import img from './asset.png'`.src). Both graphs via a source
|
|
309
|
+
// transform; the client one skips the middleware form and the Profiler pass
|
|
310
|
+
// (registered on its own below).
|
|
311
|
+
registerServerSourceTransforms(
|
|
312
|
+
// `Profiler` too: the new-URL pass front-runs the react-profiler rewrite.
|
|
313
|
+
withSniff(['import.meta.url', 'Profiler'], (source, file) =>
|
|
314
|
+
rewriteNewUrlAssetSource(source, file),
|
|
315
|
+
),
|
|
316
|
+
);
|
|
317
|
+
registerServerSourceTransforms(withSniff(['import.meta.url'], rewriteImportMetaUrlSource));
|
|
318
|
+
// Client order is load-bearing: the worker pass (async, registered below) and
|
|
319
|
+
// the new-URL asset pass both read `import.meta.url`, which this one inlines.
|
|
320
|
+
registerClientSourceTransforms(
|
|
321
|
+
withSniff(['import.meta.url'], rewriteNewUrlAssetClientSource),
|
|
322
|
+
withSniff(['Profiler'], rewriteReactProfilerImport),
|
|
323
|
+
withSniff([/\.then\s*\(/], source => rewriteClientDynamicImportPromises(source)),
|
|
324
|
+
withSniff(['import.meta.url'], rewriteImportMetaUrlSource),
|
|
325
|
+
);
|
|
326
|
+
// webpack's `require.context(dir, recursive, regExp)`: expanded on disk into static imports plus a
|
|
327
|
+
// synthesized context object. Registered as a source transform, not an esbuild onLoad plugin, so it
|
|
328
|
+
// reaches every consumer of the compiled source without preempting the extension-specific loaders -
|
|
329
|
+
// the server graph through `rewriteServerSource` and the client graph through
|
|
330
|
+
// `applyClientSourceTransforms`.
|
|
331
|
+
const requireContextPaths = { outPath: config.outPath, workspaceRoot: config.workspaceRoot };
|
|
332
|
+
registerServerSourceTransforms(
|
|
333
|
+
withSniff(['.context('], (source, file) =>
|
|
334
|
+
rewriteRequireContextSource(source, file, requireContextPaths),
|
|
335
|
+
),
|
|
336
|
+
);
|
|
337
|
+
registerClientSourceTransforms(
|
|
338
|
+
withSniff(['.context('], (source, file) =>
|
|
339
|
+
rewriteRequireContextSource(source, file, requireContextPaths),
|
|
340
|
+
),
|
|
341
|
+
);
|
|
342
|
+
// Web Worker bundling: an async pre-transform, so it sees `import.meta.url`
|
|
343
|
+
// before the sync chain above inlines it. The rest of the chain then runs on
|
|
344
|
+
// its output — no companion re-application needed.
|
|
345
|
+
const workerTransform = createClientWorkerTransform(config, configuredExtensions);
|
|
346
|
+
registerClientSourceAsyncPreTransforms(
|
|
347
|
+
withSniff(['new Worker(', 'new SharedWorker('], (source, file) => workerTransform(source, file)),
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
// next.config's `reactCompiler` is the same switch as pnext's own
|
|
351
|
+
// `compat.reactCompiler`: fold it into the compat-mode options so the single
|
|
352
|
+
// compiler pass (core's client-source loader) sees one answer.
|
|
353
|
+
const priorReactCompilerOptions = getCompatModeExtensions().reactCompilerOptions;
|
|
354
|
+
setCompatModeExtensions({
|
|
355
|
+
reactCompilerOptions: cfg =>
|
|
356
|
+
priorReactCompilerOptions(cfg) ?? (reactCompilerEnabled() ? { target: '18' } : undefined),
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// Created once, not per build: the memo spans the hundreds of server builds
|
|
360
|
+
// a vendor pass runs over the same workspace sources.
|
|
361
|
+
const firstPartyRewrite = createFirstPartySourceRewrite(config, {
|
|
362
|
+
transform: optimizeTransform,
|
|
363
|
+
sniff: specifierSniffTokens(optimizedPackages),
|
|
364
|
+
});
|
|
365
|
+
const priorClient = getBundlerExtensions().clientEsbuildPlugins;
|
|
366
|
+
const priorServer = getBundlerExtensions().serverEsbuildPlugins;
|
|
367
|
+
const priorPure = getBundlerExtensions().clientPureFunctions;
|
|
368
|
+
setBundlerExtensions({
|
|
369
|
+
clientPureFunctions: cfg => [...priorPure(cfg), ...(removeConsole ?? [])],
|
|
370
|
+
serverDefines: () => serverDefines,
|
|
371
|
+
// The blur gate reads app source, so it is computed on the first client
|
|
372
|
+
// build that asks — never at registration, which runs inside the boot
|
|
373
|
+
// budget. `appUsesBlurPlaceholder` memoizes per root.
|
|
374
|
+
clientDefines: () => ({
|
|
375
|
+
...clientDefines,
|
|
376
|
+
__PNEXT_IMAGE_BLUR__: String(appUsesBlurPlaceholder(config.root)),
|
|
377
|
+
// Same one-sided source scan for `<Link legacyBehavior>` (link-usage.ts).
|
|
378
|
+
__PNEXT_LINK_LEGACY__: String(appUsesLegacyLink(config.root)),
|
|
379
|
+
// next.config `images` only ever reached the server global, so the client
|
|
380
|
+
// fell back to the defaults — config-dependent props (path, qualities,
|
|
381
|
+
// sizes) mismatched on hydration. Inlining the resolved config also drops
|
|
382
|
+
// the defaults + resolver from every client bundle.
|
|
383
|
+
__PNEXT_IMAGE_CONFIG_INLINE__: JSON.stringify(getImagesConfig()),
|
|
384
|
+
__PNEXT_IMAGE_CONFIG_INLINED__: 'true',
|
|
385
|
+
// publicRuntimeConfig inlined the same way; omitted entirely when unset so an app that
|
|
386
|
+
// never configures it adds zero bytes (unlike images, there is no default to drop).
|
|
387
|
+
...(Object.keys(publicRuntimeConfig()).length > 0
|
|
388
|
+
? {
|
|
389
|
+
__PNEXT_PUBLIC_RUNTIME_CONFIG_INLINE__: JSON.stringify(publicRuntimeConfig()),
|
|
390
|
+
__PNEXT_PUBLIC_RUNTIME_CONFIG_INLINED__: 'true',
|
|
391
|
+
}
|
|
392
|
+
: {}),
|
|
393
|
+
}),
|
|
394
|
+
// Next ships a `polyfills-<hash>.js` chunk + a `<script noModule>` tag; the
|
|
395
|
+
// body is inert for pnext's module-capable targets (see polyfill.ts).
|
|
396
|
+
staticClientChunks: () => [
|
|
397
|
+
{ name: polyfillsChunkFileName(), contents: POLYFILLS_NOMODULE_SOURCE },
|
|
398
|
+
],
|
|
399
|
+
clientEsbuildPlugins: (cfg: ResolvedConfig): Plugin[] => [
|
|
400
|
+
...webpackLoaderPlugins(cfg, 'client'),
|
|
401
|
+
pagesClientModulePlugin(cfg),
|
|
402
|
+
wasmModulePlugin(cfg),
|
|
403
|
+
// tsconfig `paths` resolution for the client graph, whenever any reachable tsconfig declares them:
|
|
404
|
+
// esbuild's native discovery misses standard `tsconfig.json` paths for stdin-based builds and never
|
|
405
|
+
// skips `.d.ts`-first array targets. Everything else stays on esbuild's native resolution.
|
|
406
|
+
...optional(tsconfigPathsPlugin(cfg)),
|
|
407
|
+
...(configuredExtensions ? [clientResolveExtensionsPlugin(configuredExtensions)] : []),
|
|
408
|
+
...optional(clientExternalPackageResolvePlugin(cfg, externals)),
|
|
409
|
+
// First-party source outside every source root gets no
|
|
410
|
+
// registerClientSourceTransforms pass — the OPI rewrite must live here too.
|
|
411
|
+
firstPartyClientOptimizeImportsLoadPlugin(
|
|
412
|
+
cfg,
|
|
413
|
+
optimizeTransform,
|
|
414
|
+
specifierSniffTokens(optimizedPackages),
|
|
415
|
+
),
|
|
416
|
+
clientDynamicCommonJsImportsPlugin(cfg.root),
|
|
417
|
+
...priorClient(cfg),
|
|
418
|
+
],
|
|
419
|
+
serverEsbuildPlugins: (cfg: ResolvedConfig, opts?: ServerEsbuildPluginOptions): Plugin[] => [
|
|
420
|
+
...webpackLoaderPlugins(cfg, 'server'),
|
|
421
|
+
wasmModulePlugin(cfg),
|
|
422
|
+
...optional(tsconfigPathsPlugin(cfg)),
|
|
423
|
+
...(symlinkedImportsPossible(cfg, opts?.realPathEntries)
|
|
424
|
+
? [serverSymlinkImportPlugin(cfg)]
|
|
425
|
+
: []),
|
|
426
|
+
serverSourceLoadPlugin(firstPartyRewrite, opts?.vendorClientBoundary),
|
|
427
|
+
commonJsDefaultInteropPlugin(),
|
|
428
|
+
recoverCommonJsNamedExportsPlugin(),
|
|
429
|
+
...priorServer(cfg, opts),
|
|
430
|
+
],
|
|
431
|
+
serverBundleEntry: commonJsInteropEntry,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/** Spread helper for the plugins that skip registration when unconfigured. */
|
|
436
|
+
function optional(plugin: Plugin | undefined): Plugin[] {
|
|
437
|
+
return plugin ? [plugin] : [];
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function webpackLoaderPlugins(cfg: ResolvedConfig, target: 'client' | 'server'): Plugin[] {
|
|
441
|
+
const plugin = webpackLoaderRulesPlugin(cfg, target);
|
|
442
|
+
return plugin ? [plugin] : [];
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Source rewrites a bundle has to get BEFORE resolution, applied where esbuild reads the file:
|
|
446
|
+
// - next/font: vendor bundles transform esbuild's OUTPUT, where `next/font/google` has already been
|
|
447
|
+
// alias-rewritten to a file:// path, so the font rewrite no-ops there and the untouched named imports
|
|
448
|
+
// hit the empty shim.
|
|
449
|
+
// - optimizePackageImports: a `'use client'` component in a LINKED workspace package is compiled by the
|
|
450
|
+
// vendor bundler, which never runs the source-transform chain, so its barrel imports bypassed the
|
|
451
|
+
// rewrite and the whole catalogue was compiled and evaluated.
|
|
452
|
+
// Both are idempotent: re-running either on already-rewritten source is a no-op.
|
|
453
|
+
interface FirstPartySourceRewrite {
|
|
454
|
+
rewrite: (file: string) => Promise<OnLoadResult | undefined>;
|
|
455
|
+
/** node_modules dirs transpilePackages opts back into the rewrite. */
|
|
456
|
+
transpiledFilter?: RegExp;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function createFirstPartySourceRewrite(
|
|
460
|
+
config: ResolvedConfig,
|
|
461
|
+
optimize: { transform: (source: string, file: string) => string; sniff: readonly string[] },
|
|
462
|
+
): FirstPartySourceRewrite {
|
|
463
|
+
const transpiled = transpilePackages();
|
|
464
|
+
const rewrite = fileMemoAsync(async (file: string): Promise<OnLoadResult | undefined> => {
|
|
465
|
+
let source: string;
|
|
466
|
+
try {
|
|
467
|
+
source = await readFile(file, 'utf8');
|
|
468
|
+
} catch {
|
|
469
|
+
return undefined;
|
|
470
|
+
}
|
|
471
|
+
let contents = source;
|
|
472
|
+
if (contents.includes('next/font/')) {
|
|
473
|
+
contents = rewriteNextFontSource(contents, file, 'server', config.root);
|
|
474
|
+
}
|
|
475
|
+
// TS only: what reaches this hook is first-party or transpiled source, and
|
|
476
|
+
// both ship .ts/.tsx. The sniff keeps the parse off everything else.
|
|
477
|
+
if (/\.tsx?$/.test(file) && optimize.sniff.some(token => contents.includes(token))) {
|
|
478
|
+
contents = optimize.transform(contents, file);
|
|
479
|
+
}
|
|
480
|
+
if (contents === source) return undefined;
|
|
481
|
+
// Keep the file's own syntax: `.ts` must not parse as `.tsx` (`<T>`
|
|
482
|
+
// casts), and .js/.mjs/.cjs app source may legitimately contain JSX.
|
|
483
|
+
return { contents, loader: file.endsWith('.ts') ? 'ts' : 'tsx' };
|
|
484
|
+
});
|
|
485
|
+
return {
|
|
486
|
+
rewrite,
|
|
487
|
+
transpiledFilter:
|
|
488
|
+
transpiled.length > 0
|
|
489
|
+
? new RegExp(`[\\\\/]node_modules[\\\\/](?:${transpiled.map(escapeRegex).join('|')})[\\\\/]`)
|
|
490
|
+
: undefined,
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* The server chain's ONE claiming onLoad over JS/TS sources. esbuild hands a file to the FIRST onLoad
|
|
496
|
+
* that claims it, so the three passes that used to be separate plugins - CJS client references, the
|
|
497
|
+
* first-party font/OPI rewrite, and the vendor client-boundary stub - each cost a full callback round
|
|
498
|
+
* trip per input file per build. Composed here in their original registration order, they share one
|
|
499
|
+
* callback.
|
|
500
|
+
*/
|
|
501
|
+
function serverSourceLoadPlugin(
|
|
502
|
+
firstParty: FirstPartySourceRewrite,
|
|
503
|
+
vendorClientBoundary?: (file: string) => Promise<OnLoadResult | undefined>,
|
|
504
|
+
): Plugin {
|
|
505
|
+
return {
|
|
506
|
+
name: 'pnext-server-source-load',
|
|
507
|
+
setup(build) {
|
|
508
|
+
build.onLoad({ filter: /\.[cm]?[jt]sx?$/, namespace: 'file' }, async args => {
|
|
509
|
+
// `use client` in a CommonJS file -> tag its exports as references.
|
|
510
|
+
if (/\.c?js$/.test(args.path)) {
|
|
511
|
+
const references = await clientReferenceLoad(args.path);
|
|
512
|
+
if (references) return references;
|
|
513
|
+
}
|
|
514
|
+
// First-party (or transpilePackages-opted) source: font/OPI rewrites.
|
|
515
|
+
// Everything else under node_modules keeps esbuild's native load path.
|
|
516
|
+
if (
|
|
517
|
+
!args.path.includes(`${path.sep}node_modules${path.sep}`) ||
|
|
518
|
+
firstParty.transpiledFilter?.test(args.path)
|
|
519
|
+
) {
|
|
520
|
+
const rewritten = await firstParty.rewrite(args.path);
|
|
521
|
+
if (rewritten) return rewritten;
|
|
522
|
+
}
|
|
523
|
+
return vendorClientBoundary?.(args.path);
|
|
524
|
+
});
|
|
525
|
+
},
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Client twin of firstPartySourceLoadPlugin, OPI rewrite only (the client pipeline handles next/font
|
|
530
|
+
// itself); same outside-node_modules claim boundary, minus what core's client-source loader already owns.
|
|
531
|
+
// esbuild gives a file to the FIRST onLoad that claims it, and this plugin is registered ahead of that
|
|
532
|
+
// loader - claiming a source root file here would silently drop the whole client chain on it (React
|
|
533
|
+
// Compiler, `dynamic()` rewrite, defines). Under a root the chain applies this same transform anyway;
|
|
534
|
+
// only source living outside every root needs the hook.
|
|
535
|
+
function firstPartyClientOptimizeImportsLoadPlugin(
|
|
536
|
+
config: ResolvedConfig,
|
|
537
|
+
transform: (source: string, file: string) => string,
|
|
538
|
+
sniff: readonly string[],
|
|
539
|
+
): Plugin {
|
|
540
|
+
const roots = clientSourceRootPrefixes(config);
|
|
541
|
+
const rewriteFile = fileMemoAsync(async (file: string) => {
|
|
542
|
+
let source: string;
|
|
543
|
+
try {
|
|
544
|
+
source = await readFile(file, 'utf8');
|
|
545
|
+
} catch {
|
|
546
|
+
return undefined;
|
|
547
|
+
}
|
|
548
|
+
if (!/\.tsx?$/.test(file) || !sniff.some(token => source.includes(token))) return undefined;
|
|
549
|
+
const contents = transform(source, file);
|
|
550
|
+
if (contents === source) return undefined;
|
|
551
|
+
return { contents, loader: file.endsWith('.ts') ? ('ts' as const) : ('tsx' as const) };
|
|
552
|
+
});
|
|
553
|
+
return {
|
|
554
|
+
name: 'pnext-first-party-client-optimize-imports-load',
|
|
555
|
+
setup(build) {
|
|
556
|
+
build.onLoad({ filter: /\.tsx?$/, namespace: 'file' }, args =>
|
|
557
|
+
args.path.includes(`${path.sep}node_modules${path.sep}`) ||
|
|
558
|
+
roots.some(root => args.path.startsWith(root))
|
|
559
|
+
? undefined
|
|
560
|
+
: rewriteFile(args.path),
|
|
561
|
+
);
|
|
562
|
+
},
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// The roots core's client-source loader claims under (client/build.ts
|
|
567
|
+
// `clientSourceRoots`), each with a trailing separator so a sibling directory
|
|
568
|
+
// sharing the prefix is not swallowed.
|
|
569
|
+
function clientSourceRootPrefixes(config: ResolvedConfig): string[] {
|
|
570
|
+
const roots = new Set<string>();
|
|
571
|
+
for (const root of [config.root, config.workspaceRoot]) {
|
|
572
|
+
const resolved = path.resolve(root);
|
|
573
|
+
roots.add(resolved + path.sep);
|
|
574
|
+
try {
|
|
575
|
+
roots.add(realpathSync.native(resolved) + path.sep);
|
|
576
|
+
} catch {
|
|
577
|
+
// Unresolvable root: its literal form already covers the files under it.
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return [...roots];
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// First-party workspace source is implicitly transpiled. Hoisting puts the
|
|
584
|
+
// package only in the workspace root's node_modules, so both roots are asked.
|
|
585
|
+
function isLinkedWorkspacePackage(config: ResolvedConfig, name: string) {
|
|
586
|
+
return isWorkspacePackage(config.root, name) || isWorkspacePackage(config.workspaceRoot, name);
|
|
587
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Cache extension registration (COMPAT - may import core freely).
|
|
2
|
+
//
|
|
3
|
+
// Wires the next/cache compat behavior into the core extension registries so core never statically
|
|
4
|
+
// imports compat/cache/*:
|
|
5
|
+
// - renderExtensions.collectRenderMeta <- collectRenderCacheMeta
|
|
6
|
+
// - requestExtensions.staticStaleness <- pathRevalidatedSince + tagsRevalidatedSince
|
|
7
|
+
// - buildExtensions.initHooks <- installCompatFetchCache (next only)
|
|
8
|
+
// - bundlerExtensions.serverSourceTransforms <- rewriteUseCacheSource
|
|
9
|
+
//
|
|
10
|
+
// Ordering: registerCompatExtensions runs cache BEFORE actions, so the use-cache source transform is
|
|
11
|
+
// registered ahead of the inline-action-tag transform, matching the old rewriteServerSource order.
|
|
12
|
+
|
|
13
|
+
import type { ResolvedConfig } from '../../config';
|
|
14
|
+
import { nextCompatEnabled } from '../../compat';
|
|
15
|
+
import {
|
|
16
|
+
registerBundledSourceTransforms,
|
|
17
|
+
registerInitHooks,
|
|
18
|
+
registerServerSourceTransforms,
|
|
19
|
+
setRenderExtensions,
|
|
20
|
+
setRequestExtensions,
|
|
21
|
+
withSniff,
|
|
22
|
+
} from '../../extensions';
|
|
23
|
+
import {
|
|
24
|
+
collectRenderCacheMeta,
|
|
25
|
+
currentRenderCacheMeta,
|
|
26
|
+
pathRevalidatedSince,
|
|
27
|
+
pathRevalidationReasonSince,
|
|
28
|
+
tagsRevalidatedSince,
|
|
29
|
+
tagsRevalidationReasonSince,
|
|
30
|
+
tagsStaleSince,
|
|
31
|
+
} from '../cache/revalidate';
|
|
32
|
+
import { setBuildFlagsOutPath } from '../cache/build-flags';
|
|
33
|
+
import { installCompatFetchCache } from '../cache/fetch-patch';
|
|
34
|
+
import { installCustomCacheHandler } from '../cache/custom-handler';
|
|
35
|
+
import { installModernCacheHandlers } from '../cache/modern-handler';
|
|
36
|
+
import { rewriteUseCacheSource } from '../cache/use-cache-transform';
|
|
37
|
+
import { resumeDataCacheExtension } from '../cache/resume-data-cache';
|
|
38
|
+
|
|
39
|
+
export function registerCacheExtensions(config: ResolvedConfig): void {
|
|
40
|
+
// Render cache-meta collection scope (tags/revalidate/no-store) wrapped
|
|
41
|
+
// around every prerender + dynamic render; signature matches the registry.
|
|
42
|
+
setRenderExtensions({
|
|
43
|
+
collectRenderMeta: collectRenderCacheMeta,
|
|
44
|
+
// Peek (never consume) the render's aggregated cacheLife stale window, so
|
|
45
|
+
// the document can inline its own reuse window for hard loads.
|
|
46
|
+
currentCacheStaleSeconds: () => currentRenderCacheMeta()?.staleSeconds,
|
|
47
|
+
prerenderSidecar: resumeDataCacheExtension,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// ISR on-demand staleness: fold the path + tag revalidation checks start.ts
|
|
51
|
+
// used to OR together into the single registry predicate.
|
|
52
|
+
setRequestExtensions({
|
|
53
|
+
staticStaleness: (pathname, mtimeMs, tags) =>
|
|
54
|
+
pathRevalidatedSince(pathname, mtimeMs) || tagsRevalidatedSince(tags, mtimeMs),
|
|
55
|
+
staticStalenessReason: (pathname, mtimeMs, tags) =>
|
|
56
|
+
pathRevalidationReasonSince(pathname, mtimeMs) ??
|
|
57
|
+
tagsRevalidationReasonSince(tags, mtimeMs) ??
|
|
58
|
+
(tagsStaleSince(tags, mtimeMs) ? 'soft' : undefined),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// 'use cache' source rewrite (server bundles): registered first so it runs
|
|
62
|
+
// before the inline-action-tag transform, exactly as before. Also registered
|
|
63
|
+
// over bundled vendor output — a package can ship 'use cache' functions, and
|
|
64
|
+
// the directive is the one trigger in the chain that survives bundling.
|
|
65
|
+
const useCache = withSniff(['use cache'], (source, file, root) =>
|
|
66
|
+
rewriteUseCacheSource(source, file, root),
|
|
67
|
+
);
|
|
68
|
+
registerServerSourceTransforms(useCache);
|
|
69
|
+
registerBundledSourceTransforms(useCache);
|
|
70
|
+
|
|
71
|
+
// Prerenders + runtime renders must observe Next fetch-cache options
|
|
72
|
+
// (force-cache, next: { revalidate, tags }). Idempotent; next-compat only.
|
|
73
|
+
if (nextCompatEnabled(config)) {
|
|
74
|
+
registerInitHooks(cfg => {
|
|
75
|
+
installCompatFetchCache();
|
|
76
|
+
// Where `pnext start` reads the build's --debug-prerender flag back from
|
|
77
|
+
// (the runtime 'use cache' error funnel shapes its log around it).
|
|
78
|
+
setBuildFlagsOutPath(cfg.outPath);
|
|
79
|
+
// Load + instantiate the configured `cacheHandler` (next.config) and
|
|
80
|
+
// install it into the core cache seam so the data cache defers to it.
|
|
81
|
+
installCustomCacheHandler(cfg.root);
|
|
82
|
+
installModernCacheHandlers(cfg.root);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|