@wular/pnext 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/pnext +9 -2
- package/dist/server/_chunks/aliases-pycbtjt1.js +46 -0
- package/dist/server/_chunks/analyze-4d9e00g9.js +449 -0
- package/dist/server/_chunks/boot-bhemypxz.js +38 -0
- package/dist/server/_chunks/build-c991dv65.js +86 -0
- package/dist/server/_chunks/build-kh5e3x48.js +3341 -0
- package/dist/server/_chunks/build-tier-0a96kmx3.js +2456 -0
- package/dist/server/_chunks/compile-040r79gj.js +22 -0
- package/dist/server/_chunks/config-0tvz03a6.js +24 -0
- package/dist/server/_chunks/config-27rj7830.js +36 -0
- package/dist/server/_chunks/create-9rvwshsp.js +135 -0
- package/dist/server/_chunks/dev-ex9exynt.js +220 -0
- package/dist/server/_chunks/esbuild-yyktfrtt.js +15 -0
- package/dist/server/_chunks/generate-myw9hef7.js +22 -0
- package/dist/server/_chunks/index-0r5eqfc7.js +279 -0
- package/dist/server/_chunks/index-0yjv5v47.js +105 -0
- package/dist/server/_chunks/index-11xpbfej.js +17 -0
- package/dist/server/_chunks/index-141vcwk6.js +109 -0
- package/dist/server/_chunks/index-1pzm1hdy.js +4130 -0
- package/dist/server/_chunks/index-29pq0kax.js +590 -0
- package/dist/server/_chunks/index-2vz0wzdn.js +59 -0
- package/dist/server/_chunks/index-2wfv4kvx.js +182 -0
- package/dist/server/_chunks/index-38xpdxwd.js +194 -0
- package/dist/server/_chunks/index-3e075kny.js +128 -0
- package/dist/server/_chunks/index-3ycf5ckv.js +472 -0
- package/dist/server/_chunks/index-4399bvd2.js +18 -0
- package/dist/server/_chunks/index-4da76t62.js +297 -0
- package/dist/server/_chunks/index-4t92hdxd.js +172 -0
- package/dist/server/_chunks/index-4zzebszd.js +10 -0
- package/dist/server/_chunks/index-52k54ykj.js +95 -0
- package/dist/server/_chunks/index-5hr4062s.js +70 -0
- package/dist/server/_chunks/index-68m3mwbd.js +84 -0
- package/dist/server/_chunks/index-6b009mt0.js +56 -0
- package/dist/server/_chunks/index-6gex3pfa.js +15 -0
- package/dist/server/_chunks/index-6kp9r0d9.js +11 -0
- package/dist/server/_chunks/index-6q7zvrap.js +134 -0
- package/dist/server/_chunks/index-71885zaq.js +284 -0
- package/dist/server/_chunks/index-73z4esab.js +38 -0
- package/dist/server/_chunks/index-79ngvam8.js +60 -0
- package/dist/server/_chunks/index-7wc9n8be.js +25 -0
- package/dist/server/_chunks/index-8ct7rqy3.js +198 -0
- package/dist/server/_chunks/index-8kcxdfya.js +206 -0
- package/dist/server/_chunks/index-9ch50vtq.js +18 -0
- package/dist/server/_chunks/index-9f49w76j.js +213 -0
- package/dist/server/_chunks/index-9hz3s0m8.js +851 -0
- package/dist/server/_chunks/index-akkrvjn6.js +535 -0
- package/dist/server/_chunks/index-b6wtkdp4.js +24 -0
- package/dist/server/_chunks/index-b7j671dj.js +207 -0
- package/dist/server/_chunks/index-bcws5eh2.js +35 -0
- package/dist/server/_chunks/index-bzd2ef7t.js +10 -0
- package/dist/server/_chunks/index-cjgqs13g.js +65 -0
- package/dist/server/_chunks/index-ckkdpht5.js +41 -0
- package/dist/server/_chunks/index-cn86z041.js +296 -0
- package/dist/server/_chunks/index-cvr4z22m.js +92 -0
- package/dist/server/_chunks/index-cyfednwb.js +87 -0
- package/dist/server/_chunks/index-d158y67j.js +152 -0
- package/dist/server/_chunks/index-d1jsmhhk.js +955 -0
- package/dist/server/_chunks/index-dg0f05zs.js +199 -0
- package/dist/server/_chunks/index-dgr390q7.js +9438 -0
- package/dist/server/_chunks/index-drwv61cc.js +185 -0
- package/dist/server/_chunks/index-e3a6yx84.js +18 -0
- package/dist/server/_chunks/index-e88tyv35.js +45 -0
- package/dist/server/_chunks/index-en7n9f7m.js +22 -0
- package/dist/server/_chunks/index-entm8bmz.js +28 -0
- package/dist/server/_chunks/index-evhd413j.js +57 -0
- package/dist/server/_chunks/index-ezgj0tr1.js +88 -0
- package/dist/server/_chunks/index-fjv96re1.js +5295 -0
- package/dist/server/_chunks/index-fn1chkkd.js +214 -0
- package/dist/server/_chunks/index-fp8r0sqs.js +64 -0
- package/dist/server/_chunks/index-gcmj16xy.js +92 -0
- package/dist/server/_chunks/index-gkndxkxf.js +736 -0
- package/dist/server/_chunks/index-grta8ap3.js +238 -0
- package/dist/server/_chunks/index-h2a70tg4.js +7 -0
- package/dist/server/_chunks/index-h4xy648y.js +51 -0
- package/dist/server/_chunks/index-hdbwtdv2.js +352 -0
- package/dist/server/_chunks/index-he6n2bvp.js +1270 -0
- package/dist/server/_chunks/index-j0m1jxqa.js +1253 -0
- package/dist/server/_chunks/index-j2zrcp1k.js +66 -0
- package/dist/server/_chunks/index-j681c48a.js +2530 -0
- package/dist/server/_chunks/index-jbj7ehef.js +50 -0
- package/dist/server/_chunks/index-jcsjq3d1.js +20 -0
- package/dist/server/_chunks/index-jks0x0a1.js +14 -0
- package/dist/server/_chunks/index-jn9rbhrx.js +1599 -0
- package/dist/server/_chunks/index-jt8e1pje.js +12 -0
- package/dist/server/_chunks/index-kdhxpwyq.js +483 -0
- package/dist/server/_chunks/index-knp0s912.js +7 -0
- package/dist/server/_chunks/index-kqyy1d4f.js +50 -0
- package/dist/server/_chunks/index-kresp2n8.js +445 -0
- package/dist/server/_chunks/index-m63czgq5.js +590 -0
- package/dist/server/_chunks/index-ms9v9tnx.js +31 -0
- package/dist/server/_chunks/index-n4hxpng2.js +11 -0
- package/dist/server/_chunks/index-n629dy38.js +1071 -0
- package/dist/server/_chunks/index-nf3df4jy.js +266 -0
- package/dist/server/_chunks/index-nqh3xhdc.js +57 -0
- package/dist/server/_chunks/index-pym1cezq.js +39 -0
- package/dist/server/_chunks/index-q3r9z8mq.js +213 -0
- package/dist/server/_chunks/index-q738kkhj.js +100 -0
- package/dist/server/_chunks/index-qcrvt6er.js +112 -0
- package/dist/server/_chunks/index-qjj6gddn.js +54 -0
- package/dist/server/_chunks/index-qpwsgt3a.js +158 -0
- package/dist/server/_chunks/index-r97ptz1q.js +97 -0
- package/dist/server/_chunks/index-ras0sdab.js +26 -0
- package/dist/server/_chunks/index-rcs322t1.js +19 -0
- package/dist/server/_chunks/index-rgj5mx84.js +101 -0
- package/dist/server/_chunks/index-rjegyfx4.js +1435 -0
- package/dist/server/_chunks/index-rt9qq1va.js +4 -0
- package/dist/server/_chunks/index-rthrsed5.js +356 -0
- package/dist/server/_chunks/index-sq3kvz3g.js +200 -0
- package/dist/server/_chunks/index-stbk3jhn.js +31 -0
- package/dist/server/_chunks/index-tf4j19ge.js +130 -0
- package/dist/server/_chunks/index-tgcakdxc.js +125 -0
- package/dist/server/_chunks/index-tgsfjmep.js +74 -0
- package/dist/server/_chunks/index-tq1f96v7.js +51 -0
- package/dist/server/_chunks/index-tq3b39a5.js +107 -0
- package/dist/server/_chunks/index-typcbcsv.js +819 -0
- package/dist/server/_chunks/index-v1ags1na.js +132 -0
- package/dist/server/_chunks/index-vmr35jjw.js +170 -0
- package/dist/server/_chunks/index-vvq7rqtn.js +329 -0
- package/dist/server/_chunks/index-vz0km5qk.js +33 -0
- package/dist/server/_chunks/index-w6h8m6vp.js +138 -0
- package/dist/server/_chunks/index-web361b8.js +138 -0
- package/dist/server/_chunks/index-wm36rj4v.js +311 -0
- package/dist/server/_chunks/index-x0y005nh.js +283 -0
- package/dist/server/_chunks/index-x2m17v9c.js +6166 -0
- package/dist/server/_chunks/index-x3yn4ywm.js +22 -0
- package/dist/server/_chunks/index-x9c55pzy.js +871 -0
- package/dist/server/_chunks/index-xh1nbk46.js +1299 -0
- package/dist/server/_chunks/index-xvj80c3a.js +30 -0
- package/dist/server/_chunks/index-xywjg2vc.js +100 -0
- package/dist/server/_chunks/index-y4d02znn.js +66 -0
- package/dist/server/_chunks/index-y7mzvq2q.js +110 -0
- package/dist/server/_chunks/index-ye9hmsvf.js +47 -0
- package/dist/server/_chunks/index-yhxkxghe.js +56 -0
- package/dist/server/_chunks/index-yrjkqtfj.js +86 -0
- package/dist/server/_chunks/index-z88qv16t.js +11 -0
- package/dist/server/_chunks/index-zfrwq472.js +154 -0
- package/dist/server/_chunks/index-zqpqyg8p.js +666 -0
- package/dist/server/_chunks/loader-5en7wpt5.js +80 -0
- package/dist/server/_chunks/modules-t92favpj.js +76 -0
- package/dist/server/_chunks/pipeline-4t9q43ht.js +836 -0
- package/dist/server/_chunks/production-385bw8df.js +55 -0
- package/dist/server/_chunks/proxy-config-60gprphe.js +23 -0
- package/dist/server/_chunks/proxy-gfhmktbk.js +35 -0
- package/dist/server/_chunks/router-xnrva921.js +501 -0
- package/dist/server/_chunks/routes-ht868pdc.js +66 -0
- package/dist/server/_chunks/run-d40d63ag.js +697 -0
- package/dist/server/_chunks/server-2p8fgqq2.js +1839 -0
- package/dist/server/_chunks/tsconfig-defaults-bcn34eqb.js +21 -0
- package/dist/server/_chunks/typegen-dvtcjtaw.js +37 -0
- package/dist/server/api/client-cache.js +14 -0
- package/dist/server/cli/index.js +375 -0
- package/dist/server/cli/start.js +158 -0
- package/dist/server/client/reference.js +16 -0
- package/dist/server/compat/next/cache.js +56 -0
- package/dist/server/compat/next/canonical-url.js +13 -0
- package/dist/server/compat/next/client-cache.js +57 -0
- package/dist/server/compat/next/client-navigation.js +232 -0
- package/dist/server/compat/next/client-only.js +1 -0
- package/dist/server/compat/next/client-script.js +178 -0
- package/dist/server/compat/next/client-server.js +34 -0
- package/dist/server/compat/next/config-headers.js +34 -0
- package/dist/server/compat/next/config-loader.js +25 -0
- package/dist/server/compat/next/config.js +10 -0
- package/dist/server/compat/next/constants.js +18 -0
- package/dist/server/compat/next/custom-server.js +10 -0
- package/dist/server/compat/next/dist/client/components/app-router-headers.js +48 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/revalidate.js +27 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-cache.js +25 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-no-store.js +25 -0
- package/dist/server/compat/next/dynamic.js +21 -0
- package/dist/server/compat/next/error.js +112 -0
- package/dist/server/compat/next/font/cache.js +16 -0
- package/dist/server/compat/next/font/google.js +3 -0
- package/dist/server/compat/next/font/index.js +1 -0
- package/dist/server/compat/next/font/local.js +24 -0
- package/dist/server/compat/next/font/runtime-client.js +33 -0
- package/dist/server/compat/next/font/runtime.js +43 -0
- package/dist/server/compat/next/font/shared.js +22 -0
- package/dist/server/compat/next/form.js +129 -0
- package/dist/server/compat/next/head.js +10 -0
- package/dist/server/compat/next/headers.js +30 -0
- package/dist/server/compat/next/image/client.js +11 -0
- package/dist/server/compat/next/image/config.js +18 -0
- package/dist/server/compat/next/image/optimizer.js +25 -0
- package/dist/server/compat/next/image/patterns.js +12 -0
- package/dist/server/compat/next/image/props.js +16 -0
- package/dist/server/compat/next/image/shared.js +86 -0
- package/dist/server/compat/next/image/static-metadata.js +32 -0
- package/dist/server/compat/next/image/validate.js +8 -0
- package/dist/server/compat/next/image.js +59 -0
- package/dist/server/compat/next/index.js +1 -0
- package/dist/server/compat/next/legacy-image.js +78 -0
- package/dist/server/compat/next/legacy-request-apis.js +24 -0
- package/dist/server/compat/next/link-transform.js +15 -0
- package/dist/server/compat/next/link.js +14 -0
- package/dist/server/compat/next/navigation.js +191 -0
- package/dist/server/compat/next/offline.js +45 -0
- package/dist/server/compat/next/og.js +8 -0
- package/dist/server/compat/next/preferred-region.js +8 -0
- package/dist/server/compat/next/redirects.js +32 -0
- package/dist/server/compat/next/resource-hints.js +30 -0
- package/dist/server/compat/next/rewrites.js +43 -0
- package/dist/server/compat/next/root-params.js +121 -0
- package/dist/server/compat/next/route-state.js +23 -0
- package/dist/server/compat/next/router.js +103 -0
- package/dist/server/compat/next/script.js +37 -0
- package/dist/server/compat/next/server-only.js +1 -0
- package/dist/server/compat/next/server.js +131 -0
- package/dist/server/compat/next/svgr.js +14 -0
- package/dist/server/compat/next/telemetry.js +10 -0
- package/dist/server/compat/next/usage.js +13 -0
- package/dist/server/compat/next/user-agent.js +12 -0
- package/dist/server/compat/next/web-vitals.js +35 -0
- package/dist/server/compat/react/action-state.js +11 -0
- package/dist/server/compat/react/client-lite.js +83 -0
- package/dist/server/compat/react/client.js +131 -0
- package/dist/server/compat/react/compiler-runtime.js +42 -0
- package/dist/server/compat/react/dom-client.js +106 -0
- package/dist/server/compat/react/dom-react-server.js +37 -0
- package/dist/server/compat/react/dom-server.js +40 -0
- package/dist/server/compat/react/dom.js +52 -0
- package/dist/server/compat/react/hooks-extra.js +12 -0
- package/dist/server/compat/react/internals.js +14 -0
- package/dist/server/compat/react/parity.js +11 -0
- package/dist/server/compat/react/preact.js +113 -0
- package/dist/server/compat/react/react-server.js +133 -0
- package/dist/server/compat/react/router-shim.js +8 -0
- package/dist/server/compat/react/server-component-use.js +14 -0
- package/dist/server/compat/react/server-inserted-html.js +14 -0
- package/dist/server/compat/react/server.js +194 -0
- package/dist/server/compat/react/style-values.js +10 -0
- package/dist/server/compat/react/use.js +10 -0
- package/dist/server/compat/react/view-transition.js +12 -0
- package/dist/server/generation.json +1 -0
- package/package.json +4 -1
- package/reference/compat.md +1 -1
- package/reference/config.md +2 -2
- package/reference/dev.md +1 -1
- package/reference/getting-started.md +1 -1
- package/reference/rendering.md +4 -4
- package/src/api/dynamic.tsx +86 -4
- package/src/api/server.ts +24 -6
- package/src/cli/adapters/vercel-warm.ts +327 -62
- package/src/cli/adapters/vercel.ts +164 -1054
- package/src/cli/analyze.ts +3 -2
- package/src/cli/build/cache.ts +6 -6
- package/src/cli/build.ts +78 -45
- package/src/cli/index.ts +21 -3
- package/src/cli/serve/immutable.ts +31 -0
- package/src/cli/serve/pipeline.ts +97 -93
- package/src/cli/serve/standalone-worker.ts +8 -0
- package/src/cli/serve/standalone.ts +703 -0
- package/src/cli/start.ts +31 -8
- package/src/client/build.ts +1 -1
- package/src/client/chunk-fold.ts +19 -6
- package/src/client/react-tier.ts +3 -2
- package/src/client/reference-stub.ts +23 -36
- package/src/compat/actions/client-plugin.ts +4 -2
- package/src/compat/actions/config.ts +6 -5
- package/src/compat/actions/extensions.ts +5 -5
- package/src/compat/aliases.ts +8 -1
- package/src/compat/bundler/config.ts +88 -0
- package/src/compat/bundler/optimize-package-imports.ts +86 -26
- package/src/compat/bundler/relay-transform.ts +15 -3
- package/src/compat/bundler/require-context.ts +2 -1
- package/src/compat/bundler/webpack-loaders.ts +3 -2
- package/src/compat/bundler/worker.ts +2 -2
- package/src/compat/cache-control.ts +16 -8
- package/src/compat/css/inline-css.ts +1 -1
- package/src/compat/css/modules.ts +18 -5
- package/src/compat/export/build-complete.ts +1 -1
- package/src/compat/export/emit.ts +4 -4
- package/src/compat/export/standalone.ts +30 -65
- package/src/compat/image-optimizer/optimize.ts +1 -1
- package/src/compat/lifecycle/error-funnel.ts +1 -1
- package/src/compat/lifecycle/instrumentation-client.ts +4 -3
- package/src/compat/lifecycle/instrumentation.ts +117 -24
- package/src/compat/lifecycle/testmode.ts +3 -2
- package/src/compat/metadata-artifacts.ts +1 -1
- package/src/compat/next/config-loader.ts +140 -13
- package/src/compat/next/dynamic.tsx +10 -23
- package/src/compat/next/font/cache.ts +2 -1
- package/src/compat/next/font/runtime.ts +23 -3
- package/src/compat/next/og.ts +3 -3
- package/src/compat/next/usage.ts +3 -2
- package/src/compat/pages/api.ts +83 -14
- package/src/compat/pages/router.ts +30 -14
- package/src/compat/register/bundler.ts +3 -1
- package/src/compat/register/image.ts +1 -1
- package/src/compat/register/middleware.ts +1 -1
- package/src/compat/register/otel.ts +5 -9
- package/src/compat/register/render.ts +3 -1
- package/src/compat/register/use-cache.ts +3 -1
- package/src/compat/release.ts +46 -0
- package/src/compat/segment/serve.ts +1 -1
- package/src/compat/typecheck/check.ts +6 -4
- package/src/compat/validation/validate.ts +10 -7
- package/src/config.ts +76 -9
- package/src/css/assets.ts +213 -0
- package/src/css/build.ts +190 -247
- package/src/dev/client-chunk-store.ts +2 -1
- package/src/dev/restart/client-key.ts +2 -1
- package/src/dev/restart/global-css.ts +2 -1
- package/src/dev/restart/route-bundle-key.ts +2 -1
- package/src/dev/restart/route-facts.ts +2 -1
- package/src/dev/server.ts +34 -14
- package/src/extensions.ts +4 -0
- package/src/out-paths.ts +10 -0
- package/src/render/hooks.ts +13 -0
- package/src/render/renderer.ts +53 -33
- package/src/request/context.ts +9 -0
- package/src/resolve/dynamic.ts +7 -1
- package/src/resolve/engine.ts +2 -12
- package/src/resolve/imports.ts +12 -52
- package/src/resolve/package-json.ts +56 -0
- package/src/resolve/scan-facts.ts +250 -1
- package/src/routing/href.ts +10 -3
- package/src/routing/match.ts +287 -0
- package/src/routing/metadata-files.ts +20 -6
- package/src/routing/proxy-config.ts +137 -0
- package/src/routing/proxy.ts +35 -134
- package/src/routing/routes.ts +22 -281
- package/src/runtime/fingerprint.ts +23 -8
- package/src/runtime/load.ts +170 -0
- package/src/runtime/loader.ts +218 -44
- package/src/runtime/module-cache.ts +15 -1
- package/src/runtime/modules.ts +405 -82
- package/src/runtime/prebundle.ts +101 -0
- package/src/runtime/production.ts +456 -0
- package/src/runtime/release-graph.ts +342 -0
- package/src/runtime/vendor-build.ts +750 -17
- package/src/runtime/vendor.ts +16 -3
- package/src/types.ts +4 -3
- package/src/utils/directive.ts +40 -0
- package/src/utils/fs.ts +95 -4
- package/src/utils/resource-query.ts +12 -0
- package/src/cli/serve/entry.ts +0 -45
package/src/runtime/modules.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { builtinModules } from 'node:module'
|
|
2
2
|
import os from 'node:os'
|
|
3
3
|
import path from 'node:path'
|
|
4
|
-
import { existsSync, readFileSync, type Dirent } from 'node:fs'
|
|
4
|
+
import { existsSync, readFileSync, readdirSync, realpathSync, statSync, type Dirent } from 'node:fs'
|
|
5
5
|
import { fileURLToPath } from 'node:url'
|
|
6
6
|
import { copyFile, mkdir, readdir, readlink, rm, symlink, writeFile } from 'node:fs/promises'
|
|
7
7
|
import type { OnResolveResult, Plugin } from 'esbuild'
|
|
@@ -23,7 +23,13 @@ import {
|
|
|
23
23
|
serverBundleRequireConditions,
|
|
24
24
|
type ServerBundleTarget,
|
|
25
25
|
} from './loader'
|
|
26
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
clearReleaseDependencyLog,
|
|
28
|
+
externalServerPackageHref,
|
|
29
|
+
noteReleaseModuleLayer,
|
|
30
|
+
runtimeServerImportTarget,
|
|
31
|
+
type ReleaseDependencyLayer,
|
|
32
|
+
} from '../runtime/vendor-build'
|
|
27
33
|
import { writeFileAtomic } from '../utils/fs'
|
|
28
34
|
import { traceEnabled, traceValue } from '../utils/trace-flags'
|
|
29
35
|
import { createHash } from 'node:crypto'
|
|
@@ -55,9 +61,12 @@ import {
|
|
|
55
61
|
resolvePackageSpecifier,
|
|
56
62
|
} from '../resolve/imports'
|
|
57
63
|
import {
|
|
64
|
+
absolutePathLiterals,
|
|
58
65
|
importSpecifiers,
|
|
66
|
+
lineComments,
|
|
59
67
|
moduleSpecifierEdges,
|
|
60
68
|
rewriteSpecifierLiterals,
|
|
69
|
+
stripJsonImportAttributes,
|
|
61
70
|
} from '../resolve/scan-facts'
|
|
62
71
|
import {
|
|
63
72
|
cacheRoot,
|
|
@@ -76,7 +85,20 @@ import {
|
|
|
76
85
|
transformServerModule,
|
|
77
86
|
type SpecifierKind,
|
|
78
87
|
} from './module-transform'
|
|
88
|
+
import { splitResourceQuery } from '../resolve/engine'
|
|
79
89
|
import { findShakeableDynamicImports } from '../resolve/tree-shake'
|
|
90
|
+
import { productionRelease, releaseModuleHref } from './production'
|
|
91
|
+
import {
|
|
92
|
+
clearModuleGraphFailure,
|
|
93
|
+
forgetModuleEvalError,
|
|
94
|
+
importModuleOnce,
|
|
95
|
+
isReleaseCompile,
|
|
96
|
+
noteModuleGraphFailure,
|
|
97
|
+
setReleaseCompileFlag,
|
|
98
|
+
throwIfModuleEvalFailed,
|
|
99
|
+
} from './load'
|
|
100
|
+
|
|
101
|
+
export { importModuleOnce, isReleaseCompile, throwIfModuleGraphFailed } from './load'
|
|
80
102
|
import type { RouteManifestEntry } from '../types'
|
|
81
103
|
import { uniqueIdentifier } from '../utils/code'
|
|
82
104
|
import { formatDuration } from '../utils/verbose'
|
|
@@ -114,37 +136,13 @@ const routeBundleBuilds = new Map<string, Promise<string>>()
|
|
|
114
136
|
// present during an earlier check. This avoids repeated reads/parses without
|
|
115
137
|
// turning one observation into a permanent claim that the closure still exists.
|
|
116
138
|
const completeArtifactClosures = new Map<string, readonly string[]>()
|
|
117
|
-
let moduleGraphFailure: Error | undefined
|
|
118
139
|
|
|
119
140
|
/** Reset build-only graph state before starting another build in this process. */
|
|
120
141
|
export function resetModuleGraphFailure(): void {
|
|
121
|
-
|
|
142
|
+
clearModuleGraphFailure()
|
|
122
143
|
completeArtifactClosures.clear()
|
|
123
144
|
}
|
|
124
145
|
|
|
125
|
-
/**
|
|
126
|
-
* Fail a build even when its renderer converted a module-resolution exception
|
|
127
|
-
* into a 500 response. Rendering may recover from user-code errors, but a
|
|
128
|
-
* missing content-addressed artifact means the build output itself is broken.
|
|
129
|
-
*/
|
|
130
|
-
export function throwIfModuleGraphFailed(): void {
|
|
131
|
-
if (moduleGraphFailure !== undefined) throw moduleGraphFailure
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function noteModuleGraphFailure(error: unknown): void {
|
|
135
|
-
moduleGraphFailure ??= error instanceof Error ? error : new Error(String(error))
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function isCompiledModuleResolutionError(error: unknown, href: string): boolean {
|
|
139
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
140
|
-
if (!message.includes('Cannot find module')) return false
|
|
141
|
-
return (
|
|
142
|
-
href.includes('/cache/server/') ||
|
|
143
|
-
/[/\\]cache[/\\]server[/\\]/.test(message) ||
|
|
144
|
-
message.includes('/cache/server/')
|
|
145
|
-
)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
146
|
// PNEXT_TRACE=server: attribute every per-module compile to its profile,
|
|
149
147
|
// so cross-profile duplicate work is countable rather than inferred. Counts are
|
|
150
148
|
// load-insensitive, which is what makes them usable on a contended box.
|
|
@@ -222,35 +220,10 @@ function reportModuleStats() {
|
|
|
222
220
|
}
|
|
223
221
|
const routeModuleLoaders = new Map<string, Promise<DevRouteModuleLoaders>>()
|
|
224
222
|
|
|
225
|
-
// A module that throws while evaluating stays failed in Bun's registry for the process lifetime, and
|
|
226
|
-
// re-importing it surfaces downstream symptoms (a missing bundle entry, TDZ on an export) instead of
|
|
227
|
-
// the original error. Record the first failure per compiled href and re-throw THAT on every later
|
|
228
|
-
// request. Compiled hrefs are content-addressed, so a save that fixes the module yields a new href
|
|
229
|
-
// and the entry is never consulted again.
|
|
230
|
-
const moduleEvalErrors = new Map<string, unknown>()
|
|
231
223
|
const warmRetryHrefs = new Map<string, Promise<string>>()
|
|
232
224
|
const warmImports = new Map<string, Promise<void>>()
|
|
233
225
|
let warmRetryGeneration = 0
|
|
234
226
|
|
|
235
|
-
/**
|
|
236
|
-
* Import a compiled module, re-throwing its first evaluation error on later imports.
|
|
237
|
-
*
|
|
238
|
-
* Production needs this as much as dev: a re-import resolves with a half-evaluated namespace whose
|
|
239
|
-
* `export const` bindings are still in TDZ, so the render's next read (`module.metadata`) throws
|
|
240
|
-
* `Cannot access 'metadata' before initialization` and that replaces the real error in the response.
|
|
241
|
-
* Prod hrefs are content-addressed too, so the entry keys the same way dev's does.
|
|
242
|
-
*/
|
|
243
|
-
export async function importModuleOnce<T>(href: string): Promise<T> {
|
|
244
|
-
if (moduleEvalErrors.has(href)) throw moduleEvalErrors.get(href)
|
|
245
|
-
try {
|
|
246
|
-
return (await import(href)) as T
|
|
247
|
-
} catch (error) {
|
|
248
|
-
if (isCompiledModuleResolutionError(error, href)) noteModuleGraphFailure(error)
|
|
249
|
-
moduleEvalErrors.set(href, error)
|
|
250
|
-
throw error
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
227
|
interface ImportDevModuleOptions {
|
|
255
228
|
/** A speculative import whose evaluation failure must not become render state. */
|
|
256
229
|
warm?: boolean
|
|
@@ -298,7 +271,7 @@ export async function importDevModule<T>(
|
|
|
298
271
|
let attemptedEvaluation = false
|
|
299
272
|
try {
|
|
300
273
|
importHref = (await warmRetryHrefs.get(href)) ?? href
|
|
301
|
-
|
|
274
|
+
throwIfModuleEvalFailed(importHref)
|
|
302
275
|
// Pre-planned vendor builds are enqueued without an awaiter; nothing
|
|
303
276
|
// evaluates until they all settle (no-op when the pipeline is empty).
|
|
304
277
|
await drainPreplanBuilds()
|
|
@@ -312,7 +285,7 @@ export async function importDevModule<T>(
|
|
|
312
285
|
// the real render a fresh module identity, so speculative work can never poison the request.
|
|
313
286
|
const retryHref = nextWarmRetryHref(href)
|
|
314
287
|
warmRetryHrefs.set(href, retryHref)
|
|
315
|
-
|
|
288
|
+
forgetModuleEvalError(importHref, error)
|
|
316
289
|
await retryHref
|
|
317
290
|
}
|
|
318
291
|
throw error
|
|
@@ -338,6 +311,7 @@ const moduleCaches = new WeakMap<ResolvedConfig, DevModuleCache>()
|
|
|
338
311
|
export function devModuleGraph(config: ResolvedConfig): DevModuleCache {
|
|
339
312
|
const existing = moduleCaches.get(config)
|
|
340
313
|
if (existing) return existing
|
|
314
|
+
if (isReleaseCompile()) releaseAnchors.set(cacheRoot(config.outPath), portableAnchors(config))
|
|
341
315
|
const cache = devModuleCache(config, {
|
|
342
316
|
compileKey: devCompileKey(config),
|
|
343
317
|
edges: (file, source) => graphEdges(config, file, source),
|
|
@@ -429,6 +403,14 @@ function devAliasKeys(config: ResolvedConfig) {
|
|
|
429
403
|
return keys
|
|
430
404
|
}
|
|
431
405
|
|
|
406
|
+
/** The out dir is compiled output, save the pages sources a build materializes into it. */
|
|
407
|
+
function isCompiledOutput(config: ResolvedConfig, file: string) {
|
|
408
|
+
return (
|
|
409
|
+
isInside(config.outPath, file) &&
|
|
410
|
+
!isInside(path.join(config.outRootPath, 'pnext-pages-compat'), file)
|
|
411
|
+
)
|
|
412
|
+
}
|
|
413
|
+
|
|
432
414
|
/**
|
|
433
415
|
* Source edges the graph hash follows. A superset of the compiled graph is safe - it only widens what
|
|
434
416
|
* a save invalidates - but a subset would leave a dependent holding a name that no longer describes
|
|
@@ -444,7 +426,7 @@ function graphEdges(config: ResolvedConfig, file: string, source: string) {
|
|
|
444
426
|
const resolved = resolveLocalImport(config, file, sourcePath.replace(/\?.*$/, ''))
|
|
445
427
|
const isLocalSource = sourcePath.startsWith('.') || path.isAbsolute(sourcePath)
|
|
446
428
|
// Compiled output is never a source of the graph that produced it.
|
|
447
|
-
if (resolved &&
|
|
429
|
+
if (resolved && isCompiledOutput(config, resolved)) continue
|
|
448
430
|
if (resolved && (isLocalSource || isInside(config.workspaceRoot, resolved))) {
|
|
449
431
|
imports.push(path.resolve(resolved))
|
|
450
432
|
continue
|
|
@@ -547,6 +529,9 @@ export async function devServerModuleHref(
|
|
|
547
529
|
_version?: string,
|
|
548
530
|
moduleOptions: DevServerModuleOptions = {},
|
|
549
531
|
) {
|
|
532
|
+
const served = productionRelease(config)
|
|
533
|
+
if (served)
|
|
534
|
+
return releaseModuleHref(served, 'server', moduleOptions.conditionTarget ?? 'server', file)
|
|
550
535
|
const conditionTarget = pagesLayerConditionTarget(
|
|
551
536
|
config,
|
|
552
537
|
file,
|
|
@@ -585,6 +570,8 @@ export async function devClientModuleHref(
|
|
|
585
570
|
_version?: string,
|
|
586
571
|
serverTarget?: ServerBundleTarget,
|
|
587
572
|
) {
|
|
573
|
+
const served = productionRelease(config)
|
|
574
|
+
if (served) return releaseModuleHref(served, 'client', serverTarget ?? 'server', file)
|
|
588
575
|
const conditionTarget = clientLayerConditionTarget(config, file, serverTarget ?? 'server')
|
|
589
576
|
const throughPackage = await packageClientModuleHref(config, file, conditionTarget)
|
|
590
577
|
if (throughPackage) return throughPackage
|
|
@@ -1414,30 +1401,284 @@ export function setEmitCompiledSpecifiersManifest(enabled: boolean) {
|
|
|
1414
1401
|
}
|
|
1415
1402
|
}
|
|
1416
1403
|
|
|
1404
|
+
// A production build compiles for its release: `.js` artifact names, one asset-context link per
|
|
1405
|
+
// directory, core CSS module class maps. Dev keeps its own compile.
|
|
1406
|
+
// A build's sources do not change under it, so each directory's asset context links once; dev relinks.
|
|
1407
|
+
const linkedAssetContexts = new Map<string, Promise<void>>()
|
|
1408
|
+
|
|
1409
|
+
/** @internal The build sets this for its own duration. Returns a restore function. */
|
|
1410
|
+
export function setReleaseCompile(enabled: boolean) {
|
|
1411
|
+
const previous = isReleaseCompile()
|
|
1412
|
+
setReleaseCompileFlag(enabled)
|
|
1413
|
+
// Each build starts from an emptied out dir, so nothing linked or stubbed before still stands.
|
|
1414
|
+
linkedAssetContexts.clear()
|
|
1415
|
+
assetStubs.clear()
|
|
1416
|
+
releaseAnchors.clear()
|
|
1417
|
+
packageCandidates.clear()
|
|
1418
|
+
packageSpecifiers.clear()
|
|
1419
|
+
clearReleaseDependencyLog()
|
|
1420
|
+
return () => setReleaseCompileFlag(previous)
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1417
1423
|
/** Sidecar suffix for a compiled artifact's recorded specifiers. */
|
|
1418
1424
|
export const compiledSpecifiersManifestSuffix = '.pnext-specifiers.json'
|
|
1419
1425
|
|
|
1420
1426
|
const compiledScriptFilePattern = /\.(?:m?js|cjs|jsx|tsx?)$/
|
|
1421
1427
|
|
|
1428
|
+
/** Where a release may move with its app: the root, its node_modules links, the workspace. */
|
|
1429
|
+
interface PortableAnchors {
|
|
1430
|
+
roots: string[]
|
|
1431
|
+
/** Real directory -> the logical path the app's node_modules names it by. */
|
|
1432
|
+
links: Map<string, string>
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
const releaseAnchors = new Map<string, PortableAnchors>()
|
|
1436
|
+
|
|
1437
|
+
function portableAnchors(config: ResolvedConfig): PortableAnchors {
|
|
1438
|
+
const links = new Map<string, string>()
|
|
1439
|
+
const link = (logical: string) => {
|
|
1440
|
+
try {
|
|
1441
|
+
const real = realpathSync(logical)
|
|
1442
|
+
if (real !== logical && !links.has(real)) links.set(real, logical)
|
|
1443
|
+
} catch {
|
|
1444
|
+
// A dangling entry links nothing.
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
const nodeModules = path.join(config.root, 'node_modules')
|
|
1448
|
+
link(nodeModules)
|
|
1449
|
+
for (const name of listDirectory(nodeModules)) {
|
|
1450
|
+
const entry = path.join(nodeModules, name)
|
|
1451
|
+
if (name.startsWith('@'))
|
|
1452
|
+
for (const scoped of listDirectory(entry)) link(path.join(entry, scoped))
|
|
1453
|
+
else link(entry)
|
|
1454
|
+
}
|
|
1455
|
+
return { roots: [config.root, config.workspaceRoot], links }
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
function listDirectory(dir: string) {
|
|
1459
|
+
try {
|
|
1460
|
+
return readdirSync(dir)
|
|
1461
|
+
} catch {
|
|
1462
|
+
return []
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
/**
|
|
1467
|
+
* Rewrite `file://` URLs in compiled output relative to `file`: import specifiers become relative
|
|
1468
|
+
* specifiers, and (for a release) inlined URL literals become `new URL(<relative>, import.meta.url)`.
|
|
1469
|
+
* `locate` maps an absolute target to the path to link, or undefined to leave it. A release names an
|
|
1470
|
+
* installed package file by the bare specifier that resolves back to it, so the serving install wins.
|
|
1471
|
+
*/
|
|
1472
|
+
function relocateSource(
|
|
1473
|
+
file: string,
|
|
1474
|
+
contents: string,
|
|
1475
|
+
locate: (absolute: string) => string | undefined,
|
|
1476
|
+
installed: (absolute: string) => boolean = () => false,
|
|
1477
|
+
) {
|
|
1478
|
+
const relativeTo = (target: string) => {
|
|
1479
|
+
const relative = toPosixPath(path.relative(path.dirname(file), target))
|
|
1480
|
+
return relative.startsWith('.') ? relative : `./${relative}`
|
|
1481
|
+
}
|
|
1482
|
+
const edits: { start: number; end: number; value: string }[] = []
|
|
1483
|
+
for (const found of outputSpecifiers(contents)) {
|
|
1484
|
+
const { sourcePath, hash } = splitHash(found.value)
|
|
1485
|
+
const url = sourcePath.startsWith('file://')
|
|
1486
|
+
// A release also re-links plain absolute specifiers (a bundled `require('/abs/path')`).
|
|
1487
|
+
if (!url && !(isReleaseCompile() && path.isAbsolute(sourcePath))) continue
|
|
1488
|
+
const absolute = url ? fileURLToPath(sourcePath) : sourcePath
|
|
1489
|
+
const target = locate(absolute)
|
|
1490
|
+
const bare = isReleaseCompile() && installed(absolute) && packageSpecifier(file, absolute)
|
|
1491
|
+
const value = bare || (target && relativeTo(target))
|
|
1492
|
+
if (!value) continue
|
|
1493
|
+
const query = url ? new URL(sourcePath).search : ''
|
|
1494
|
+
edits.push({
|
|
1495
|
+
start: found.start,
|
|
1496
|
+
end: found.end,
|
|
1497
|
+
value: JSON.stringify(`${value}${query}${hash}`),
|
|
1498
|
+
})
|
|
1499
|
+
}
|
|
1500
|
+
const specifiers = spliceSource(contents, edits)
|
|
1501
|
+
if (!isReleaseCompile()) return specifiers
|
|
1502
|
+
// Path literals (client-reference targets, module URLs) resolve beside the artifact at runtime.
|
|
1503
|
+
const expression = (value: string) => {
|
|
1504
|
+
const url = value.startsWith('file:')
|
|
1505
|
+
const target = locate(url ? fileURLToPath(value) : value)
|
|
1506
|
+
if (!target) return undefined
|
|
1507
|
+
const href = `new URL(${JSON.stringify(relativeTo(target))}, import.meta.url)`
|
|
1508
|
+
return url ? `${href}.href` : `decodeURIComponent(${href}.pathname)`
|
|
1509
|
+
}
|
|
1510
|
+
const literals = absolutePathLiterals(file, specifiers)
|
|
1511
|
+
if (!literals) {
|
|
1512
|
+
// A recovered parse: the textual form, double-quoted literals only.
|
|
1513
|
+
return specifiers.replace(
|
|
1514
|
+
/(?<!\\)"((?:file:\/\/)?\/[^"\\\n]+)"(\s*:)?/g,
|
|
1515
|
+
(literal, value: string, key: string | undefined) => {
|
|
1516
|
+
const replacement = expression(value)
|
|
1517
|
+
if (!replacement) return literal
|
|
1518
|
+
return key ? `[${replacement}]${key}` : replacement
|
|
1519
|
+
},
|
|
1520
|
+
)
|
|
1521
|
+
}
|
|
1522
|
+
return spliceSource(
|
|
1523
|
+
specifiers,
|
|
1524
|
+
literals.flatMap(literal => {
|
|
1525
|
+
const replacement = expression(literal.value)
|
|
1526
|
+
if (!replacement) return []
|
|
1527
|
+
return [
|
|
1528
|
+
{
|
|
1529
|
+
start: literal.start,
|
|
1530
|
+
end: literal.end,
|
|
1531
|
+
value: literal.key ? `[${replacement}]` : replacement,
|
|
1532
|
+
},
|
|
1533
|
+
]
|
|
1534
|
+
}),
|
|
1535
|
+
)
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
const isInstalled = (file: string) => file.includes(`${path.sep}node_modules${path.sep}`)
|
|
1539
|
+
const packageCandidates = new Map<string, string | null>()
|
|
1540
|
+
const packageSpecifiers = new Map<string, boolean>()
|
|
1541
|
+
|
|
1542
|
+
/** The bare specifier that resolves from `from` back to installed `file`, if one does. */
|
|
1543
|
+
function packageSpecifier(from: string, file: string) {
|
|
1544
|
+
const candidate = packageCandidate(file)
|
|
1545
|
+
// One miss settles it: the fallback path is always correct, only less portable.
|
|
1546
|
+
if (!candidate || packageSpecifiers.get(candidate) === false) return undefined
|
|
1547
|
+
const key = `${path.dirname(from)}\0${candidate}`
|
|
1548
|
+
let resolves = packageSpecifiers.get(key)
|
|
1549
|
+
if (resolves === undefined) {
|
|
1550
|
+
try {
|
|
1551
|
+
resolves = realpathSync(Bun.resolveSync(candidate, path.dirname(from))) === realpathSync(file)
|
|
1552
|
+
} catch {
|
|
1553
|
+
resolves = false
|
|
1554
|
+
}
|
|
1555
|
+
packageSpecifiers.set(key, resolves)
|
|
1556
|
+
if (!resolves) packageSpecifiers.set(candidate, false)
|
|
1557
|
+
}
|
|
1558
|
+
return resolves ? candidate : undefined
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
/** How installed `file` is named bare: the exports subpath that targets it, else its deep path. */
|
|
1562
|
+
function packageCandidate(file: string) {
|
|
1563
|
+
let candidate = packageCandidates.get(file)
|
|
1564
|
+
if (candidate !== undefined) return candidate
|
|
1565
|
+
candidate = null
|
|
1566
|
+
const packageDir = nodeModulesPackageDir(file)
|
|
1567
|
+
const name = packageDir && packageNameOfDirectory(packageDir)
|
|
1568
|
+
if (packageDir && name) {
|
|
1569
|
+
const subpath = `./${toPosixPath(path.relative(packageDir, file))}`
|
|
1570
|
+
const exports = packageExportsMap(packageDir)
|
|
1571
|
+
if (!exports) candidate = `${name}/${subpath.slice(2)}`
|
|
1572
|
+
for (const [key, value] of Object.entries(exports ?? {})) {
|
|
1573
|
+
if (key.includes('*') || !exportTargets(value).includes(subpath)) continue
|
|
1574
|
+
candidate = key === '.' ? name : `${name}/${key.slice(2)}`
|
|
1575
|
+
break
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
packageCandidates.set(file, candidate)
|
|
1579
|
+
return candidate
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
/** A package's exports as a subpath map (`"."` for a bare entry), or undefined when it has none. */
|
|
1583
|
+
function packageExportsMap(packageDir: string): Record<string, unknown> | undefined {
|
|
1584
|
+
try {
|
|
1585
|
+
const { exports } = JSON.parse(readFileSync(path.join(packageDir, 'package.json'), 'utf8')) as {
|
|
1586
|
+
exports?: unknown
|
|
1587
|
+
}
|
|
1588
|
+
if (exports === undefined || exports === null) return undefined
|
|
1589
|
+
if (typeof exports !== 'object' || Array.isArray(exports)) return { '.': exports }
|
|
1590
|
+
return Object.keys(exports).some(key => key.startsWith('.'))
|
|
1591
|
+
? (exports as Record<string, unknown>)
|
|
1592
|
+
: { '.': exports }
|
|
1593
|
+
} catch {
|
|
1594
|
+
return undefined
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
function exportTargets(value: unknown): string[] {
|
|
1599
|
+
if (typeof value === 'string') return [value]
|
|
1600
|
+
if (Array.isArray(value)) return value.flatMap(exportTargets)
|
|
1601
|
+
return value && typeof value === 'object' ? Object.values(value).flatMap(exportTargets) : []
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
/** A release bundle emitted outside the module graph, rewritten to reach its targets relatively. */
|
|
1605
|
+
export function relocateReleaseBundle(config: ResolvedConfig, file: string, contents: string) {
|
|
1606
|
+
const anchors = portableAnchors(config)
|
|
1607
|
+
return relocateSource(file, contents, absolute => portableTarget(anchors, absolute), isInstalled)
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
/** A release artifact written outside writeCompiledFile (vendor bundles), re-linked like one. */
|
|
1611
|
+
export function releaseArtifactSource(file: string, contents: string) {
|
|
1612
|
+
if (!isReleaseCompile()) return contents
|
|
1613
|
+
const cacheRoot = [...releaseAnchors.keys()].find(root => isInside(root, file))
|
|
1614
|
+
const anchors = cacheRoot && releaseAnchors.get(cacheRoot)
|
|
1615
|
+
if (!cacheRoot || !anchors) return contents
|
|
1616
|
+
return relocateSource(
|
|
1617
|
+
file,
|
|
1618
|
+
releaseInputComments(file, contents),
|
|
1619
|
+
absolute => (isInside(cacheRoot, absolute) ? absolute : portableTarget(anchors, absolute)),
|
|
1620
|
+
absolute => !isInside(cacheRoot, absolute) && isInstalled(absolute),
|
|
1621
|
+
)
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
/**
|
|
1625
|
+
* esbuild's per-input `// <path>` comments, cut to the file name (or its `node_modules/` path, which
|
|
1626
|
+
* names a vendored font caller): their paths walk the build machine.
|
|
1627
|
+
*/
|
|
1628
|
+
function releaseInputComments(file: string, contents: string) {
|
|
1629
|
+
const shorten = (comment: string) => {
|
|
1630
|
+
const installed = comment.indexOf('node_modules/')
|
|
1631
|
+
return `// ${installed === -1 ? path.basename(comment) : comment.slice(installed)}`
|
|
1632
|
+
}
|
|
1633
|
+
const inputPath = /^ (?:[\w-]+:)?\.{0,2}\/\S*$/
|
|
1634
|
+
const comments = lineComments(file, contents)
|
|
1635
|
+
// A recovered parse: the textual form, whole lines only.
|
|
1636
|
+
if (!comments) return contents.replace(/^\/\/ (?:[\w-]+:)?\.{0,2}\/[^\s]*$/gm, shorten)
|
|
1637
|
+
return spliceSource(
|
|
1638
|
+
contents,
|
|
1639
|
+
comments
|
|
1640
|
+
.filter(comment => inputPath.test(comment.value))
|
|
1641
|
+
.map(comment => ({ ...comment, value: shorten(`//${comment.value}`) })),
|
|
1642
|
+
)
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
/** `target` as a path a moved release still reaches: through the app's own tree, never the machine's. */
|
|
1646
|
+
function portableTarget(anchors: PortableAnchors, target: string) {
|
|
1647
|
+
if (anchors.roots.some(root => isInside(root, target))) return target
|
|
1648
|
+
// Nearest linked ancestor first, so a package link wins over the node_modules link that holds it.
|
|
1649
|
+
for (let dir = path.dirname(target); dir !== path.dirname(dir); dir = path.dirname(dir)) {
|
|
1650
|
+
const logical = anchors.links.get(dir)
|
|
1651
|
+
if (logical) return path.join(logical, path.relative(dir, target))
|
|
1652
|
+
}
|
|
1653
|
+
return undefined
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
const compiledJsonModule = /\.json\.js(?:[?#]|$)/
|
|
1657
|
+
|
|
1422
1658
|
async function writeCompiledFile(file: string, contents: string) {
|
|
1423
1659
|
const profileRoot = compiledArtifactProfileRoot(file)
|
|
1424
|
-
|
|
1660
|
+
const anchors =
|
|
1661
|
+
profileRoot && isReleaseCompile() ? releaseAnchors.get(path.dirname(profileRoot)) : undefined
|
|
1662
|
+
if (
|
|
1663
|
+
profileRoot &&
|
|
1664
|
+
(anchors
|
|
1665
|
+
? /["'](?:file:\/\/)?\/|^\/\/ (?:[\w-]+:)?\.{0,2}\//m.test(contents)
|
|
1666
|
+
: contents.includes('file://'))
|
|
1667
|
+
) {
|
|
1425
1668
|
const cacheRoot = path.dirname(profileRoot)
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
edits.push({
|
|
1434
|
-
start: found.start,
|
|
1435
|
-
end: found.end,
|
|
1436
|
-
value: JSON.stringify(`${relative.startsWith('.') ? relative : `./${relative}`}${hash}`),
|
|
1437
|
-
})
|
|
1438
|
-
}
|
|
1439
|
-
contents = spliceSource(contents, edits)
|
|
1669
|
+
contents = relocateSource(
|
|
1670
|
+
file,
|
|
1671
|
+
anchors ? releaseInputComments(file, contents) : contents,
|
|
1672
|
+
absolute =>
|
|
1673
|
+
isInside(cacheRoot, absolute) ? absolute : anchors && portableTarget(anchors, absolute),
|
|
1674
|
+
absolute => !isInside(cacheRoot, absolute) && isInstalled(absolute),
|
|
1675
|
+
)
|
|
1440
1676
|
}
|
|
1677
|
+
// A compiled `.json.js` is JS: a release loads it natively, where `type: "json"` would parse it as JSON.
|
|
1678
|
+
if (anchors && contents.includes('.json.js'))
|
|
1679
|
+
contents = stripJsonImportAttributes(contents, file, specifier =>
|
|
1680
|
+
compiledJsonModule.test(specifier),
|
|
1681
|
+
)
|
|
1441
1682
|
await writeFileAtomic(file, contents)
|
|
1442
1683
|
noteDevArtifactWritten(file)
|
|
1443
1684
|
if (emitCompiledSpecifiersManifest && compiledScriptFilePattern.test(file)) {
|
|
@@ -1497,7 +1738,7 @@ function missingCompiledArtifact(entry: string): string | undefined {
|
|
|
1497
1738
|
try {
|
|
1498
1739
|
target = sourcePath.startsWith('file://')
|
|
1499
1740
|
? fileURLToPath(sourcePath)
|
|
1500
|
-
: path.resolve(path.dirname(file), sourcePath)
|
|
1741
|
+
: path.resolve(path.dirname(file), splitResourceQuery(sourcePath).path)
|
|
1501
1742
|
} catch {
|
|
1502
1743
|
return sourcePath
|
|
1503
1744
|
}
|
|
@@ -1668,6 +1909,9 @@ async function writeDevModuleUncached(
|
|
|
1668
1909
|
clientLayerConditionTarget(config, file, options.conditionTarget),
|
|
1669
1910
|
)
|
|
1670
1911
|
: options
|
|
1912
|
+
if (effectiveOptions !== options) {
|
|
1913
|
+
noteReleaseModuleLayer(config, outFile, 'client', effectiveOptions.conditionTarget)
|
|
1914
|
+
}
|
|
1671
1915
|
// The asset-context link walk is pure I/O against directories nothing below
|
|
1672
1916
|
// reads, so it overlaps the shaking/scan/child-compile work and is only
|
|
1673
1917
|
// awaited before the write.
|
|
@@ -2212,7 +2456,7 @@ async function assetStubModule(config: ResolvedConfig, resolved: string, profile
|
|
|
2212
2456
|
if (existing) return existing
|
|
2213
2457
|
const next = (async () => {
|
|
2214
2458
|
const contents =
|
|
2215
|
-
|
|
2459
|
+
(await serverCssModuleSource(config, resolved)) ??
|
|
2216
2460
|
(isCssFile(base)
|
|
2217
2461
|
? ''
|
|
2218
2462
|
: isStaticImageFile(base)
|
|
@@ -2309,7 +2553,7 @@ function serverAssetPlugin(config: ResolvedConfig): Plugin {
|
|
|
2309
2553
|
build.onLoad({ filter: /.*/, namespace: serverAssetNamespace }, async args => {
|
|
2310
2554
|
// Registry-provided CSS modules (e.g. *.module.scss) export their class
|
|
2311
2555
|
// map on the server instead of the empty-asset stub.
|
|
2312
|
-
const cssModule =
|
|
2556
|
+
const cssModule = await serverCssModuleSource(config, args.path)
|
|
2313
2557
|
return {
|
|
2314
2558
|
contents:
|
|
2315
2559
|
cssModule ??
|
|
@@ -2347,7 +2591,7 @@ async function resolveDevModuleSpecifier(
|
|
|
2347
2591
|
if (
|
|
2348
2592
|
options.stubClientImports &&
|
|
2349
2593
|
!isCssFile(target) &&
|
|
2350
|
-
!
|
|
2594
|
+
!isCompiledOutput(config, target) &&
|
|
2351
2595
|
existsSync(target) &&
|
|
2352
2596
|
(await fileHasUseClientDirective(target))
|
|
2353
2597
|
) {
|
|
@@ -2374,6 +2618,23 @@ async function resolveDevModuleSpecifier(
|
|
|
2374
2618
|
|
|
2375
2619
|
const { sourcePath, hash } = splitHash(specifier)
|
|
2376
2620
|
|
|
2621
|
+
// A release compiles an unclaimed `?query` import's base module; the query keeps its own instance.
|
|
2622
|
+
const queried = splitResourceQuery(sourcePath)
|
|
2623
|
+
if (
|
|
2624
|
+
isReleaseCompile() &&
|
|
2625
|
+
queried.query &&
|
|
2626
|
+
sourcePath.startsWith('.') &&
|
|
2627
|
+
compiledScriptFilePattern.test(queried.path)
|
|
2628
|
+
) {
|
|
2629
|
+
const from = importer && !importer.startsWith('<') ? importer : file
|
|
2630
|
+
const base = resolveImport(config.root, from, queried.path, config.workspaceRoot)
|
|
2631
|
+
if (base && isInside(config.workspaceRoot, base)) {
|
|
2632
|
+
await writeDevModule(config, base, visited, options)
|
|
2633
|
+
const href = pathToFileHref(await devModulePath(config, base, options))
|
|
2634
|
+
return { path: `${href}${queried.query}${hash}`, external: true }
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2377
2638
|
const compatAlias =
|
|
2378
2639
|
pagesCompatSourceAlias(config, specifier, importer, options) ?? options.aliases[specifier]
|
|
2379
2640
|
if (compatAlias) {
|
|
@@ -2893,7 +3154,7 @@ function localImportTargets(
|
|
|
2893
3154
|
// vendor bundle) are already compiled modules Bun imports directly. Feeding one back through the
|
|
2894
3155
|
// pipeline compiles it a SECOND time, splitting module identity and pulling artifact names into the
|
|
2895
3156
|
// source graph, where every boot's fresh names look like edits.
|
|
2896
|
-
if (resolved && !
|
|
3157
|
+
if (resolved && !isCompiledOutput(config, resolved)) {
|
|
2897
3158
|
targets.push({
|
|
2898
3159
|
target: resolved,
|
|
2899
3160
|
isLocalSource: sourcePath.startsWith('.') || path.isAbsolute(sourcePath),
|
|
@@ -2941,9 +3202,20 @@ async function writeClientReferenceModules(
|
|
|
2941
3202
|
return { specifiers, files }
|
|
2942
3203
|
}
|
|
2943
3204
|
|
|
3205
|
+
/** How a release's stub names its source portably (see ClientReferenceModuleOptions.portable). */
|
|
3206
|
+
function portableReference(file: string, sourceFile: string) {
|
|
3207
|
+
const profileRoot = compiledArtifactProfileRoot(file)
|
|
3208
|
+
const anchors = isReleaseCompile() && profileRoot && releaseAnchors.get(path.dirname(profileRoot))
|
|
3209
|
+
const target = anchors && portableTarget(anchors, sourceFile)
|
|
3210
|
+
return target ? { portable: { from: file, target, real: target !== sourceFile } } : {}
|
|
3211
|
+
}
|
|
3212
|
+
|
|
2944
3213
|
async function writeClientReferenceModule(file: string, sourceFile: string, exportNames: string[]) {
|
|
2945
3214
|
await mkdir(path.dirname(file), { recursive: true })
|
|
2946
|
-
await writeCompiledFile(
|
|
3215
|
+
await writeCompiledFile(
|
|
3216
|
+
file,
|
|
3217
|
+
clientReferenceModuleSource(sourceFile, exportNames, portableReference(file, sourceFile)),
|
|
3218
|
+
)
|
|
2947
3219
|
}
|
|
2948
3220
|
|
|
2949
3221
|
async function fileHasUseClientDirective(file: string) {
|
|
@@ -2964,6 +3236,20 @@ function isInside(root: string, file: string) {
|
|
|
2964
3236
|
return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))
|
|
2965
3237
|
}
|
|
2966
3238
|
|
|
3239
|
+
/** Where an App Router layer's release modules compile to. */
|
|
3240
|
+
export function releaseLayerArtifactDir(config: ResolvedConfig, layer: ReleaseDependencyLayer) {
|
|
3241
|
+
const profile =
|
|
3242
|
+
layer === 'client:client'
|
|
3243
|
+
? devModuleProfile(clientLayerOptions(config))
|
|
3244
|
+
: devModuleProfile({
|
|
3245
|
+
profile: 'compat',
|
|
3246
|
+
conditionTarget: 'server',
|
|
3247
|
+
externalLoadTarget: externalLoadTargetForConditionTarget('server'),
|
|
3248
|
+
reactServerLayer: true,
|
|
3249
|
+
} as DevModuleOptions)
|
|
3250
|
+
return path.join(cacheRoot(config.outPath), `modules-${profile}`)
|
|
3251
|
+
}
|
|
3252
|
+
|
|
2967
3253
|
function devModuleProfile(options: DevModuleOptions) {
|
|
2968
3254
|
if (options.profile === 'client') {
|
|
2969
3255
|
// Pages-router SSR layers ('pages'/'pages-edge') resolve package exports
|
|
@@ -2989,7 +3275,13 @@ function devServerPath(config: ResolvedConfig, file: string, profile: string, ha
|
|
|
2989
3275
|
// A compiled `.json` module is JS (esbuild's json loader wraps it in exports),
|
|
2990
3276
|
// so it must not keep the `.json` name — the runtime would parse the artifact
|
|
2991
3277
|
// as JSON. Keeping the source name in front of `.js` keeps it collision-free.
|
|
2992
|
-
|
|
3278
|
+
// Build output names compiled scripts `.js`, so production imports them without a TS/MDX loader.
|
|
3279
|
+
const outExt =
|
|
3280
|
+
ext === '.json'
|
|
3281
|
+
? '.json.js'
|
|
3282
|
+
: isReleaseCompile() && /\.(?:[jt]sx?|mdx?)$/.test(ext)
|
|
3283
|
+
? '.js'
|
|
3284
|
+
: ext
|
|
2993
3285
|
return path.join(
|
|
2994
3286
|
cacheRoot(config.outPath),
|
|
2995
3287
|
profile === 'server' ? 'modules' : `modules-${profile}`,
|
|
@@ -3082,6 +3374,15 @@ function isCssFile(file: string) {
|
|
|
3082
3374
|
return file.endsWith('.css')
|
|
3083
3375
|
}
|
|
3084
3376
|
|
|
3377
|
+
/** A CSS module's class map as a build's server output imports it; core's plain CSS modules map here. */
|
|
3378
|
+
async function serverCssModuleSource(config: ResolvedConfig, file: string) {
|
|
3379
|
+
const registered = getCssExtensions().loadCssModuleForClient(file)
|
|
3380
|
+
const coreBuild = isReleaseCompile() && !reactCompatEnabled(config)
|
|
3381
|
+
if (registered !== undefined || !coreBuild || !file.endsWith('.module.css')) return registered
|
|
3382
|
+
const { cssModuleMapping } = await import('../css/build')
|
|
3383
|
+
return `export default ${JSON.stringify(await cssModuleMapping(file))};`
|
|
3384
|
+
}
|
|
3385
|
+
|
|
3085
3386
|
function isStaticImageFile(file: string) {
|
|
3086
3387
|
return /\.(?:png|jpe?g|gif|webp|avif|svg|ico|bmp)(?:$|[?#])/.test(file)
|
|
3087
3388
|
}
|
|
@@ -3133,9 +3434,20 @@ function resolveLocalImport(config: ResolvedConfig, fromFile: string, specifier:
|
|
|
3133
3434
|
|
|
3134
3435
|
async function linkAssetContext(config: ResolvedConfig, file: string, profile: string) {
|
|
3135
3436
|
if (!isInside(config.root, file)) return
|
|
3136
|
-
const sourceDirs = ancestorDirs(config.root, path.dirname(file))
|
|
3437
|
+
const sourceDirs = ancestorDirs(config.root, path.dirname(file)).filter(
|
|
3438
|
+
dir => !isCompiledOutput(config, dir),
|
|
3439
|
+
)
|
|
3137
3440
|
await Promise.all(
|
|
3138
|
-
sourceDirs.map(sourceDir =>
|
|
3441
|
+
sourceDirs.map(sourceDir => {
|
|
3442
|
+
if (!isReleaseCompile()) return linkDirectoryAssetContext(config, sourceDir, profile)
|
|
3443
|
+
const key = `${config.outPath}\0${profile}\0${sourceDir}`
|
|
3444
|
+
let linked = linkedAssetContexts.get(key)
|
|
3445
|
+
if (!linked) {
|
|
3446
|
+
linked = linkDirectoryAssetContext(config, sourceDir, profile)
|
|
3447
|
+
linkedAssetContexts.set(key, linked)
|
|
3448
|
+
}
|
|
3449
|
+
return linked
|
|
3450
|
+
}),
|
|
3139
3451
|
)
|
|
3140
3452
|
}
|
|
3141
3453
|
|
|
@@ -3168,6 +3480,14 @@ async function linkDirectoryAssetContext(
|
|
|
3168
3480
|
if (!assetContextEntry(config, sourceDir, entry.name, entry.isDirectory())) return
|
|
3169
3481
|
const source = path.join(sourceDir, entry.name)
|
|
3170
3482
|
const target = path.join(targetDir, entry.name)
|
|
3483
|
+
// A linked directory below the root (pages-compat's `source-pages`) compiles on its own path:
|
|
3484
|
+
// staging the link would write its artifacts through it, into the source tree.
|
|
3485
|
+
if (
|
|
3486
|
+
entry.isSymbolicLink() &&
|
|
3487
|
+
sourceDir !== config.root &&
|
|
3488
|
+
statSync(source, { throwIfNoEntry: false })?.isDirectory()
|
|
3489
|
+
)
|
|
3490
|
+
return
|
|
3171
3491
|
// Root-level sibling asset directories are mirrored, not symlinked wholesale: a `dir` symlink
|
|
3172
3492
|
// would make every path beneath it - including code modules that must be compiled through the
|
|
3173
3493
|
// alias transform - resolve straight back to raw source, shadowing the staged compile.
|
|
@@ -3208,9 +3528,11 @@ async function stagedManifestSource(file: string) {
|
|
|
3208
3528
|
async function linkOrCopyAsset(source: string, target: string) {
|
|
3209
3529
|
const resolvedSource = path.resolve(source)
|
|
3210
3530
|
// Concurrent walkers keep a repaired link and remove only the stale target.
|
|
3531
|
+
// A release links relatively: moved with its app, it names no build-machine path.
|
|
3532
|
+
const linkTarget = isReleaseCompile() ? path.relative(path.dirname(target), source) : source
|
|
3211
3533
|
for (let attempt = 0; attempt < 4; attempt += 1) {
|
|
3212
3534
|
try {
|
|
3213
|
-
await symlink(
|
|
3535
|
+
await symlink(linkTarget, target, 'file')
|
|
3214
3536
|
return
|
|
3215
3537
|
} catch (error) {
|
|
3216
3538
|
if ((error as NodeJS.ErrnoException).code !== 'EEXIST') break
|
|
@@ -3266,7 +3588,8 @@ function assetContextEntry(
|
|
|
3266
3588
|
'pages',
|
|
3267
3589
|
'public',
|
|
3268
3590
|
'node_modules',
|
|
3269
|
-
|
|
3591
|
+
// The out dir's top segment (`dist` for `dist/build`): mirroring it would recurse into its own output.
|
|
3592
|
+
path.relative(config.root, config.outRootPath).split(path.sep)[0],
|
|
3270
3593
|
]).has(name)
|
|
3271
3594
|
}
|
|
3272
3595
|
|
|
@@ -3296,7 +3619,7 @@ async function staticImageModuleSource(config: ResolvedConfig, file: string) {
|
|
|
3296
3619
|
const compat = await getAssetExtensions().staticAssetModule({ sourcePath, bytes, emit })
|
|
3297
3620
|
const source = compat ?? coreStaticAssetModule(sourcePath, bytes, emit)
|
|
3298
3621
|
for (const relative of emitted) {
|
|
3299
|
-
const target = path.join(config.outPath, '
|
|
3622
|
+
const target = path.join(config.outPath, 'static', ...relative.split('/'))
|
|
3300
3623
|
await mkdir(path.dirname(target), { recursive: true })
|
|
3301
3624
|
if (!existsSync(target)) await copyFile(sourcePath, target)
|
|
3302
3625
|
}
|