@wular/pnext 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/pnext +9 -2
- package/dist/server/_chunks/aliases-j47a10ce.js +44 -0
- package/dist/server/_chunks/analyze-arswqe6s.js +445 -0
- package/dist/server/_chunks/boot-af0mv3dy.js +36 -0
- package/dist/server/_chunks/build-spy3dxp4.js +84 -0
- package/dist/server/_chunks/build-t9h0hec3.js +3550 -0
- package/dist/server/_chunks/build-tier-m7yvqz61.js +2472 -0
- package/dist/server/_chunks/compile-53j02j27.js +22 -0
- package/dist/server/_chunks/config-1yzwexq6.js +27 -0
- package/dist/server/_chunks/config-n2z7yxps.js +22 -0
- package/dist/server/_chunks/create-meec9hs6.js +134 -0
- package/dist/server/_chunks/dev-fjmqg6en.js +220 -0
- package/dist/server/_chunks/esbuild-yyktfrtt.js +15 -0
- package/dist/server/_chunks/generate-n9sh6hzt.js +21 -0
- package/dist/server/_chunks/index-0374j2b9.js +66 -0
- package/dist/server/_chunks/index-06nyqntx.js +213 -0
- package/dist/server/_chunks/index-1011cscr.js +5263 -0
- package/dist/server/_chunks/index-11sfk4hb.js +170 -0
- package/dist/server/_chunks/index-20ppawv7.js +297 -0
- package/dist/server/_chunks/index-2dv4y4wd.js +1065 -0
- package/dist/server/_chunks/index-2vz0wzdn.js +59 -0
- package/dist/server/_chunks/index-2wfv4kvx.js +182 -0
- package/dist/server/_chunks/index-357na4a8.js +109 -0
- package/dist/server/_chunks/index-3b3at80h.js +109 -0
- package/dist/server/_chunks/index-3tf1xjsp.js +6166 -0
- package/dist/server/_chunks/index-3xbr4eyv.js +105 -0
- package/dist/server/_chunks/index-4399bvd2.js +18 -0
- package/dist/server/_chunks/index-4hgjrqh7.js +851 -0
- package/dist/server/_chunks/index-4q2gbfwk.js +2530 -0
- package/dist/server/_chunks/index-4t92hdxd.js +172 -0
- package/dist/server/_chunks/index-4zzebszd.js +10 -0
- package/dist/server/_chunks/index-5gyr4emz.js +107 -0
- package/dist/server/_chunks/index-5hr4062s.js +70 -0
- package/dist/server/_chunks/index-68m3mwbd.js +84 -0
- package/dist/server/_chunks/index-6b009mt0.js +56 -0
- package/dist/server/_chunks/index-6e4fqv30.js +588 -0
- package/dist/server/_chunks/index-6gex3pfa.js +15 -0
- package/dist/server/_chunks/index-6kp9r0d9.js +11 -0
- package/dist/server/_chunks/index-6q7zvrap.js +134 -0
- package/dist/server/_chunks/index-73z4esab.js +38 -0
- package/dist/server/_chunks/index-79ngvam8.js +60 -0
- package/dist/server/_chunks/index-7wc9n8be.js +25 -0
- package/dist/server/_chunks/index-8k7pfejn.js +1599 -0
- package/dist/server/_chunks/index-8kcxdfya.js +206 -0
- package/dist/server/_chunks/index-91x12ykq.js +274 -0
- package/dist/server/_chunks/index-9ch50vtq.js +18 -0
- package/dist/server/_chunks/index-9hx2641q.js +28 -0
- package/dist/server/_chunks/index-9n2914ww.js +535 -0
- package/dist/server/_chunks/index-9ych9ma8.js +207 -0
- package/dist/server/_chunks/index-b6wtkdp4.js +24 -0
- package/dist/server/_chunks/index-bcws5eh2.js +35 -0
- package/dist/server/_chunks/index-c0g2wf3z.js +92 -0
- package/dist/server/_chunks/index-cf4rvxv6.js +95 -0
- package/dist/server/_chunks/index-cjgqs13g.js +65 -0
- package/dist/server/_chunks/index-ckkdpht5.js +41 -0
- package/dist/server/_chunks/index-cyfednwb.js +87 -0
- package/dist/server/_chunks/index-danncfhy.js +311 -0
- package/dist/server/_chunks/index-dg0f05zs.js +199 -0
- package/dist/server/_chunks/index-e3a6yx84.js +18 -0
- package/dist/server/_chunks/index-e88tyv35.js +45 -0
- package/dist/server/_chunks/index-eajaspjk.js +1253 -0
- package/dist/server/_chunks/index-eeaanp2e.js +483 -0
- package/dist/server/_chunks/index-egykcqg3.js +101 -0
- package/dist/server/_chunks/index-en7n9f7m.js +22 -0
- package/dist/server/_chunks/index-ezgj0tr1.js +88 -0
- package/dist/server/_chunks/index-fkp000p1.js +590 -0
- package/dist/server/_chunks/index-fn1chkkd.js +214 -0
- package/dist/server/_chunks/index-fp8r0sqs.js +64 -0
- package/dist/server/_chunks/index-ggk2j965.js +9432 -0
- package/dist/server/_chunks/index-grta8ap3.js +238 -0
- package/dist/server/_chunks/index-h2a70tg4.js +7 -0
- package/dist/server/_chunks/index-h4xy648y.js +51 -0
- package/dist/server/_chunks/index-hkdfj58q.js +92 -0
- package/dist/server/_chunks/index-j2zrcp1k.js +66 -0
- package/dist/server/_chunks/index-jcsjq3d1.js +20 -0
- package/dist/server/_chunks/index-jepjvcrf.js +198 -0
- package/dist/server/_chunks/index-jks0x0a1.js +14 -0
- package/dist/server/_chunks/index-jx7bqvw1.js +57 -0
- package/dist/server/_chunks/index-k1g3epw0.js +1299 -0
- package/dist/server/_chunks/index-knp0s912.js +7 -0
- package/dist/server/_chunks/index-kq8kpzye.js +472 -0
- package/dist/server/_chunks/index-kqyy1d4f.js +50 -0
- package/dist/server/_chunks/index-kresp2n8.js +445 -0
- package/dist/server/_chunks/index-ms9v9tnx.js +31 -0
- package/dist/server/_chunks/index-n4hxpng2.js +11 -0
- package/dist/server/_chunks/index-ncnes8c6.js +17 -0
- package/dist/server/_chunks/index-nqh3xhdc.js +57 -0
- package/dist/server/_chunks/index-nyrba2kr.js +4130 -0
- package/dist/server/_chunks/index-p77b4kcx.js +296 -0
- package/dist/server/_chunks/index-pym1cezq.js +39 -0
- package/dist/server/_chunks/index-q738kkhj.js +100 -0
- package/dist/server/_chunks/index-qjj6gddn.js +54 -0
- package/dist/server/_chunks/index-qm6kmhqs.js +110 -0
- package/dist/server/_chunks/index-qn4z5s3c.js +819 -0
- package/dist/server/_chunks/index-qpwsgt3a.js +158 -0
- package/dist/server/_chunks/index-r97ptz1q.js +97 -0
- package/dist/server/_chunks/index-ras0sdab.js +26 -0
- package/dist/server/_chunks/index-rcs322t1.js +19 -0
- package/dist/server/_chunks/index-rn8dyr1f.js +126 -0
- package/dist/server/_chunks/index-rt9qq1va.js +4 -0
- package/dist/server/_chunks/index-rthrsed5.js +356 -0
- package/dist/server/_chunks/index-sctcgyvv.js +185 -0
- package/dist/server/_chunks/index-sjpckxqn.js +213 -0
- package/dist/server/_chunks/index-sq3kvz3g.js +200 -0
- package/dist/server/_chunks/index-stbk3jhn.js +31 -0
- package/dist/server/_chunks/index-sv8m6789.js +266 -0
- package/dist/server/_chunks/index-tgcakdxc.js +125 -0
- package/dist/server/_chunks/index-tgsfjmep.js +74 -0
- package/dist/server/_chunks/index-tq0pc7eg.js +154 -0
- package/dist/server/_chunks/index-tq1f96v7.js +51 -0
- package/dist/server/_chunks/index-tqn2qnnn.js +241 -0
- package/dist/server/_chunks/index-tvqkq6e6.js +128 -0
- package/dist/server/_chunks/index-v1ags1na.js +132 -0
- package/dist/server/_chunks/index-vvmmknm1.js +1431 -0
- package/dist/server/_chunks/index-vvq7rqtn.js +329 -0
- package/dist/server/_chunks/index-vz0km5qk.js +33 -0
- package/dist/server/_chunks/index-w6h8m6vp.js +138 -0
- package/dist/server/_chunks/index-web361b8.js +138 -0
- package/dist/server/_chunks/index-wpfhfbs4.js +194 -0
- package/dist/server/_chunks/index-x0y005nh.js +283 -0
- package/dist/server/_chunks/index-x3yn4ywm.js +22 -0
- package/dist/server/_chunks/index-x93hv0sc.js +271 -0
- package/dist/server/_chunks/index-xvj80c3a.js +30 -0
- package/dist/server/_chunks/index-xywjg2vc.js +100 -0
- package/dist/server/_chunks/index-y2jr2n72.js +152 -0
- package/dist/server/_chunks/index-y36a0ybw.js +57 -0
- package/dist/server/_chunks/index-ye9hmsvf.js +47 -0
- package/dist/server/_chunks/index-yhxkxghe.js +56 -0
- package/dist/server/_chunks/index-ym67zqxp.js +130 -0
- package/dist/server/_chunks/index-ytjvpbm2.js +736 -0
- package/dist/server/_chunks/index-yz54pxrh.js +960 -0
- package/dist/server/_chunks/index-z4z9zv3b.js +733 -0
- package/dist/server/_chunks/index-z84ab1w0.js +1270 -0
- package/dist/server/_chunks/index-z88qv16t.js +11 -0
- package/dist/server/_chunks/index-zqpqyg8p.js +666 -0
- package/dist/server/_chunks/loader-7yw0j98z.js +78 -0
- package/dist/server/_chunks/modules-jn8bmbn8.js +74 -0
- package/dist/server/_chunks/pipeline-yy9jhydf.js +832 -0
- package/dist/server/_chunks/production-jar9ztm3.js +44 -0
- package/dist/server/_chunks/proxy-config-j84dgksn.js +21 -0
- package/dist/server/_chunks/proxy-w1d0wmsn.js +33 -0
- package/dist/server/_chunks/router-k1reahfn.js +498 -0
- package/dist/server/_chunks/routes-2s277fc6.js +64 -0
- package/dist/server/_chunks/run-pvd8bs1t.js +696 -0
- package/dist/server/_chunks/server-mt4a994c.js +1835 -0
- package/dist/server/_chunks/tsconfig-defaults-1nb3308g.js +20 -0
- package/dist/server/_chunks/typegen-0qr0459b.js +35 -0
- package/dist/server/api/client-cache.js +14 -0
- package/dist/server/cli/index.js +378 -0
- package/dist/server/cli/start.js +137 -0
- package/dist/server/client/reference.js +16 -0
- package/dist/server/compat/next/cache.js +56 -0
- package/dist/server/compat/next/canonical-url.js +13 -0
- package/dist/server/compat/next/client-cache.js +57 -0
- package/dist/server/compat/next/client-navigation.js +232 -0
- package/dist/server/compat/next/client-only.js +1 -0
- package/dist/server/compat/next/client-script.js +178 -0
- package/dist/server/compat/next/client-server.js +34 -0
- package/dist/server/compat/next/config-headers.js +32 -0
- package/dist/server/compat/next/config-loader.js +25 -0
- package/dist/server/compat/next/config.js +10 -0
- package/dist/server/compat/next/constants.js +18 -0
- package/dist/server/compat/next/custom-server.js +10 -0
- package/dist/server/compat/next/dist/client/components/app-router-headers.js +48 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/revalidate.js +27 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-cache.js +25 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-no-store.js +25 -0
- package/dist/server/compat/next/dynamic.js +32 -0
- package/dist/server/compat/next/error.js +112 -0
- package/dist/server/compat/next/font/cache.js +14 -0
- package/dist/server/compat/next/font/google.js +3 -0
- package/dist/server/compat/next/font/index.js +1 -0
- package/dist/server/compat/next/font/local.js +22 -0
- package/dist/server/compat/next/font/runtime-client.js +33 -0
- package/dist/server/compat/next/font/runtime.js +41 -0
- package/dist/server/compat/next/font/shared.js +22 -0
- package/dist/server/compat/next/form.js +129 -0
- package/dist/server/compat/next/head.js +10 -0
- package/dist/server/compat/next/headers.js +30 -0
- package/dist/server/compat/next/image/client.js +11 -0
- package/dist/server/compat/next/image/config.js +18 -0
- package/dist/server/compat/next/image/optimizer.js +25 -0
- package/dist/server/compat/next/image/patterns.js +12 -0
- package/dist/server/compat/next/image/props.js +16 -0
- package/dist/server/compat/next/image/shared.js +86 -0
- package/dist/server/compat/next/image/static-metadata.js +32 -0
- package/dist/server/compat/next/image/validate.js +8 -0
- package/dist/server/compat/next/image.js +59 -0
- package/dist/server/compat/next/index.js +1 -0
- package/dist/server/compat/next/legacy-image.js +78 -0
- package/dist/server/compat/next/legacy-request-apis.js +24 -0
- package/dist/server/compat/next/link-transform.js +14 -0
- package/dist/server/compat/next/link.js +14 -0
- package/dist/server/compat/next/navigation.js +190 -0
- package/dist/server/compat/next/offline.js +45 -0
- package/dist/server/compat/next/og.js +8 -0
- package/dist/server/compat/next/preferred-region.js +8 -0
- package/dist/server/compat/next/redirects.js +30 -0
- package/dist/server/compat/next/resource-hints.js +30 -0
- package/dist/server/compat/next/rewrites.js +41 -0
- package/dist/server/compat/next/root-params.js +121 -0
- package/dist/server/compat/next/route-state.js +23 -0
- package/dist/server/compat/next/router.js +103 -0
- package/dist/server/compat/next/script.js +37 -0
- package/dist/server/compat/next/server-only.js +1 -0
- package/dist/server/compat/next/server.js +131 -0
- package/dist/server/compat/next/svgr.js +14 -0
- package/dist/server/compat/next/telemetry.js +10 -0
- package/dist/server/compat/next/usage.js +13 -0
- package/dist/server/compat/next/user-agent.js +12 -0
- package/dist/server/compat/next/web-vitals.js +35 -0
- package/dist/server/compat/react/action-state.js +11 -0
- package/dist/server/compat/react/client-lite.js +83 -0
- package/dist/server/compat/react/client.js +131 -0
- package/dist/server/compat/react/compiler-runtime.js +42 -0
- package/dist/server/compat/react/dom-client.js +106 -0
- package/dist/server/compat/react/dom-react-server.js +37 -0
- package/dist/server/compat/react/dom-server.js +40 -0
- package/dist/server/compat/react/dom.js +52 -0
- package/dist/server/compat/react/hooks-extra.js +12 -0
- package/dist/server/compat/react/internals.js +14 -0
- package/dist/server/compat/react/parity.js +11 -0
- package/dist/server/compat/react/preact.js +113 -0
- package/dist/server/compat/react/react-server.js +133 -0
- package/dist/server/compat/react/router-shim.js +8 -0
- package/dist/server/compat/react/server-component-use.js +14 -0
- package/dist/server/compat/react/server-inserted-html.js +14 -0
- package/dist/server/compat/react/server.js +194 -0
- package/dist/server/compat/react/style-values.js +10 -0
- package/dist/server/compat/react/use.js +10 -0
- package/dist/server/compat/react/view-transition.js +12 -0
- package/dist/server/generation.json +1 -0
- package/package.json +4 -1
- package/src/api/dynamic.tsx +2 -0
- package/src/api/server.ts +24 -6
- package/src/cli/adapters/vercel-warm.ts +315 -61
- package/src/cli/adapters/vercel.ts +348 -71
- package/src/cli/build.ts +58 -33
- package/src/cli/index.ts +23 -10
- package/src/cli/serve/entry.ts +21 -159
- package/src/cli/serve/immutable.ts +31 -0
- package/src/cli/serve/pipeline.ts +82 -84
- package/src/cli/start.ts +3 -1
- package/src/client/chunk-fold.ts +19 -6
- package/src/client/react-tier.ts +3 -2
- package/src/client/reference-stub.ts +21 -2
- package/src/compat/actions/client-plugin.ts +4 -2
- package/src/compat/actions/config.ts +6 -5
- package/src/compat/actions/extensions.ts +2 -3
- package/src/compat/aliases.ts +8 -1
- package/src/compat/bundler/config.ts +88 -0
- package/src/compat/bundler/optimize-package-imports.ts +86 -26
- package/src/compat/bundler/relay-transform.ts +15 -3
- package/src/compat/cache-control.ts +16 -8
- package/src/compat/css/modules.ts +18 -5
- package/src/compat/lifecycle/error-funnel.ts +1 -1
- package/src/compat/lifecycle/instrumentation.ts +117 -24
- package/src/compat/lifecycle/testmode.ts +3 -2
- package/src/compat/next/config-loader.ts +137 -13
- package/src/compat/next/font/runtime.ts +22 -2
- package/src/compat/next/og.ts +3 -3
- package/src/compat/next/usage.ts +3 -2
- package/src/compat/pages/api.ts +83 -14
- package/src/compat/pages/router.ts +30 -14
- package/src/compat/register/bundler.ts +3 -1
- package/src/compat/register/middleware.ts +1 -1
- package/src/compat/register/otel.ts +5 -9
- package/src/compat/register/render.ts +3 -1
- package/src/compat/register/use-cache.ts +3 -1
- package/src/compat/release.ts +46 -0
- package/src/compat/segment/serve.ts +1 -1
- package/src/compat/validation/validate.ts +10 -7
- package/src/config.ts +51 -7
- package/src/css/assets.ts +213 -0
- package/src/css/build.ts +174 -238
- package/src/dev/server.ts +27 -8
- package/src/extensions.ts +4 -0
- package/src/render/hooks.ts +13 -0
- package/src/render/renderer.ts +52 -32
- package/src/request/context.ts +9 -0
- package/src/resolve/dynamic.ts +3 -1
- package/src/resolve/imports.ts +12 -52
- package/src/resolve/package-json.ts +56 -0
- package/src/resolve/scan-facts.ts +65 -0
- package/src/routing/href.ts +10 -3
- package/src/routing/match.ts +287 -0
- package/src/routing/metadata-files.ts +19 -5
- package/src/routing/proxy-config.ts +137 -0
- package/src/routing/proxy.ts +35 -134
- package/src/routing/routes.ts +22 -281
- package/src/runtime/fingerprint.ts +23 -8
- package/src/runtime/load.ts +170 -0
- package/src/runtime/loader.ts +215 -43
- package/src/runtime/module-cache.ts +13 -0
- package/src/runtime/modules.ts +370 -81
- package/src/runtime/prebundle.ts +81 -0
- package/src/runtime/production.ts +391 -0
- package/src/runtime/release-graph.ts +334 -0
- package/src/runtime/vendor-build.ts +724 -13
- package/src/runtime/vendor.ts +16 -3
- package/src/types.ts +2 -0
- package/src/utils/fs.ts +89 -3
|
@@ -20,6 +20,89 @@ const PREDEFINED_SERVER_EXTERNAL_PACKAGES = [
|
|
|
20
20
|
'@node-rs/bcrypt',
|
|
21
21
|
]
|
|
22
22
|
|
|
23
|
+
/** Next's `next/dist/lib/server-external-packages.jsonc`. */
|
|
24
|
+
const NEXT_SERVER_EXTERNAL_PACKAGES = new Set([
|
|
25
|
+
'@alinea/generated',
|
|
26
|
+
'@appsignal/nodejs',
|
|
27
|
+
'@aws-sdk/client-s3',
|
|
28
|
+
'@aws-sdk/s3-presigned-post',
|
|
29
|
+
'@blockfrost/blockfrost-js',
|
|
30
|
+
'@highlight-run/node',
|
|
31
|
+
'@huggingface/transformers',
|
|
32
|
+
'@jpg-store/lucid-cardano',
|
|
33
|
+
'@libsql/client',
|
|
34
|
+
'@mikro-orm/core',
|
|
35
|
+
'@mikro-orm/knex',
|
|
36
|
+
'@node-rs/argon2',
|
|
37
|
+
'@node-rs/bcrypt',
|
|
38
|
+
'@prisma/client',
|
|
39
|
+
'@react-pdf/renderer',
|
|
40
|
+
'@sentry/profiling-node',
|
|
41
|
+
'@sparticuz/chromium',
|
|
42
|
+
'@sparticuz/chromium-min',
|
|
43
|
+
'@statsig/statsig-node-core',
|
|
44
|
+
'@swc/core',
|
|
45
|
+
'@xenova/transformers',
|
|
46
|
+
'@zenstackhq/runtime',
|
|
47
|
+
'argon2',
|
|
48
|
+
'autoprefixer',
|
|
49
|
+
'aws-crt',
|
|
50
|
+
'bcrypt',
|
|
51
|
+
'better-sqlite3',
|
|
52
|
+
'canvas',
|
|
53
|
+
'chromadb-default-embed',
|
|
54
|
+
'config',
|
|
55
|
+
'cpu-features',
|
|
56
|
+
'cypress',
|
|
57
|
+
'dd-trace',
|
|
58
|
+
'eslint',
|
|
59
|
+
'express',
|
|
60
|
+
'firebase-admin',
|
|
61
|
+
'htmlrewriter',
|
|
62
|
+
'import-in-the-middle',
|
|
63
|
+
'isolated-vm',
|
|
64
|
+
'jest',
|
|
65
|
+
'jsdom',
|
|
66
|
+
'keyv',
|
|
67
|
+
'libsql',
|
|
68
|
+
'mdx-bundler',
|
|
69
|
+
'mongodb',
|
|
70
|
+
'mongoose',
|
|
71
|
+
'newrelic',
|
|
72
|
+
'next-mdx-remote',
|
|
73
|
+
'next-seo',
|
|
74
|
+
'node-cron',
|
|
75
|
+
'node-pty',
|
|
76
|
+
'node-web-audio-api',
|
|
77
|
+
'onnxruntime-node',
|
|
78
|
+
'oslo',
|
|
79
|
+
'pg',
|
|
80
|
+
'pino',
|
|
81
|
+
'pino-pretty',
|
|
82
|
+
'pino-roll',
|
|
83
|
+
'playwright',
|
|
84
|
+
'playwright-core',
|
|
85
|
+
'postcss',
|
|
86
|
+
'prettier',
|
|
87
|
+
'prisma',
|
|
88
|
+
'puppeteer',
|
|
89
|
+
'puppeteer-core',
|
|
90
|
+
'ravendb',
|
|
91
|
+
'require-in-the-middle',
|
|
92
|
+
'rimraf',
|
|
93
|
+
'sharp',
|
|
94
|
+
'shiki',
|
|
95
|
+
'sqlite3',
|
|
96
|
+
'thread-stream',
|
|
97
|
+
'ts-morph',
|
|
98
|
+
'ts-node',
|
|
99
|
+
'typescript',
|
|
100
|
+
'vscode-oniguruma',
|
|
101
|
+
'webpack',
|
|
102
|
+
'websocket',
|
|
103
|
+
'zeromq',
|
|
104
|
+
])
|
|
105
|
+
|
|
23
106
|
function stringArray(value: unknown): string[] {
|
|
24
107
|
return Array.isArray(value)
|
|
25
108
|
? value.filter((item): item is string => typeof item === 'string')
|
|
@@ -51,6 +134,11 @@ export function deploymentId(): string | undefined {
|
|
|
51
134
|
return fromEnv && fromEnv.length > 0 ? fromEnv : undefined
|
|
52
135
|
}
|
|
53
136
|
|
|
137
|
+
/** Next's built-in server externals, which a release keeps out of its dependency graph. */
|
|
138
|
+
export function builtInServerExternalPackages(): ReadonlySet<string> {
|
|
139
|
+
return NEXT_SERVER_EXTERNAL_PACKAGES
|
|
140
|
+
}
|
|
141
|
+
|
|
54
142
|
/** `publicRuntimeConfig`: the subset of runtime config safe to inline into client bundles. */
|
|
55
143
|
export function publicRuntimeConfig(): Record<string, unknown> {
|
|
56
144
|
const config = getNextConfig().publicRuntimeConfig
|
|
@@ -181,9 +181,33 @@ function parseGeneratedBarrel(entry: string): BarrelMap | undefined {
|
|
|
181
181
|
if (isGeneratedFontAwesomePackage(packageDir)) {
|
|
182
182
|
return parseGeneratedFontAwesomeBarrel(entry, source)
|
|
183
183
|
}
|
|
184
|
+
const plain = plainReExports(source)
|
|
185
|
+
const exported = plain
|
|
186
|
+
? { exports: plain, count: plain.size, reExportsOnly: () => true }
|
|
187
|
+
: parsedReExports(entry, source)
|
|
188
|
+
if (!exported || exported.count < GENERATED_BARREL_MIN_EXPORTS) return undefined
|
|
189
|
+
const { exports, count: exportCount } = exported
|
|
190
|
+
const siblings = siblingFilesByStem(path.dirname(entry), entry)
|
|
191
|
+
const members = new Map<string, BarrelMember>()
|
|
192
|
+
for (const [name, member] of exports) {
|
|
193
|
+
const files = siblings.get(name)
|
|
194
|
+
const file = files?.[0]
|
|
195
|
+
if (
|
|
196
|
+
file &&
|
|
197
|
+
files.length === 1 &&
|
|
198
|
+
path.resolve(path.dirname(entry), member.source) === path.resolve(path.dirname(entry), file)
|
|
199
|
+
) {
|
|
200
|
+
members.set(name, member)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (members.size / exportCount >= GENERATED_BARREL_LEAF_RATIO) return members
|
|
204
|
+
return exported.reExportsOnly() ? manyToFewBarrelMembers(exports, entry) : undefined
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** The entry's re-export records off oxc's module record; the AST is read only if asked for. */
|
|
208
|
+
function parsedReExports(entry: string, source: string) {
|
|
184
209
|
const parsed = parseSync(entry, source, { lang: 'js' })
|
|
185
210
|
if (parsed.errors.length > 0) return undefined
|
|
186
|
-
const siblings = siblingFilesByStem(path.dirname(entry), entry)
|
|
187
211
|
const exports = new Map<string, BarrelMember>()
|
|
188
212
|
const exportNames = new Set<string>()
|
|
189
213
|
let exportCount = 0
|
|
@@ -206,22 +230,56 @@ function parseGeneratedBarrel(entry: string): BarrelMap | undefined {
|
|
|
206
230
|
exports.set(name, { source: request, imported })
|
|
207
231
|
}
|
|
208
232
|
}
|
|
209
|
-
|
|
233
|
+
return {
|
|
234
|
+
exports,
|
|
235
|
+
count: exportCount,
|
|
236
|
+
// Re-exports and nothing else: no statement runs code or declares a binding.
|
|
237
|
+
reExportsOnly: () =>
|
|
238
|
+
parsed.program.body.every(
|
|
239
|
+
node => node.type === 'ExportNamedDeclaration' && !node.declaration,
|
|
240
|
+
),
|
|
241
|
+
}
|
|
242
|
+
}
|
|
210
243
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
244
|
+
const PLAIN_RE_EXPORT = /export\s*\{([^{}]*)\}\s*from\s*(['"])([^'"\\\n]*)\2[ \t]*;?/y
|
|
245
|
+
const PLAIN_GAP = /(?:\s+|\/\/[^\n]*|\/\*[\s\S]*?\*\/)*/y
|
|
246
|
+
const PLAIN_SPECIFIER = /^([A-Za-z_$][\w$]*)(?:\s+as\s+([A-Za-z_$][\w$]*))?$/
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* A generated catalogue is usually nothing but `export { a as b } from './x'` lines. Read that
|
|
250
|
+
* exact shape without building an AST (oxc's module record alone costs more than the parse on a
|
|
251
|
+
* 1 MB entry); anything else - or a repeated name - answers undefined and takes the oxc path.
|
|
252
|
+
*/
|
|
253
|
+
function plainReExports(source: string): Map<string, BarrelMember> | undefined {
|
|
254
|
+
// The scan knows only LF as a line end; CR, U+2028 and U+2029 also end a `//` comment.
|
|
255
|
+
if (/[\r\u2028\u2029]/.test(source)) return undefined
|
|
256
|
+
const exports = new Map<string, BarrelMember>()
|
|
257
|
+
let at = 0
|
|
258
|
+
for (;;) {
|
|
259
|
+
PLAIN_GAP.lastIndex = at
|
|
260
|
+
PLAIN_GAP.exec(source)
|
|
261
|
+
if (PLAIN_GAP.lastIndex >= source.length) break
|
|
262
|
+
// Without a `;`, only a line break can end the statement before the next one.
|
|
263
|
+
if (at > 0 && source[at - 1] !== ';' && !source.slice(at, PLAIN_GAP.lastIndex).includes('\n'))
|
|
264
|
+
return undefined
|
|
265
|
+
PLAIN_RE_EXPORT.lastIndex = PLAIN_GAP.lastIndex
|
|
266
|
+
const statement = PLAIN_RE_EXPORT.exec(source)
|
|
267
|
+
if (!statement) return undefined
|
|
268
|
+
at = PLAIN_RE_EXPORT.lastIndex
|
|
269
|
+
const parts = statement[1]!.split(',')
|
|
270
|
+
for (const [index, part] of parts.entries()) {
|
|
271
|
+
const specifier = PLAIN_SPECIFIER.exec(part.trim())
|
|
272
|
+
if (!specifier) {
|
|
273
|
+
if (part.trim() === '' && index === parts.length - 1 && index > 0) continue
|
|
274
|
+
return undefined
|
|
275
|
+
}
|
|
276
|
+
const imported = specifier[1]!
|
|
277
|
+
const name = specifier[2] ?? imported
|
|
278
|
+
if (exports.has(name)) return undefined
|
|
279
|
+
exports.set(name, { source: statement[3]!, imported })
|
|
221
280
|
}
|
|
222
281
|
}
|
|
223
|
-
|
|
224
|
-
return manyToFewBarrelMembers(parsed.program.body, exports, entry)
|
|
282
|
+
return exports
|
|
225
283
|
}
|
|
226
284
|
|
|
227
285
|
/**
|
|
@@ -234,26 +292,28 @@ function parseGeneratedBarrel(entry: string): BarrelMap | undefined {
|
|
|
234
292
|
* read for demanded members.
|
|
235
293
|
*/
|
|
236
294
|
function manyToFewBarrelMembers(
|
|
237
|
-
body: readonly { type: string; declaration?: unknown }[],
|
|
238
295
|
exports: ReadonlyMap<string, BarrelMember>,
|
|
239
296
|
entry: string,
|
|
240
297
|
): BarrelMap | undefined {
|
|
241
|
-
for (const node of body) {
|
|
242
|
-
if (node.type !== 'ExportNamedDeclaration' || node.declaration) return undefined
|
|
243
|
-
}
|
|
244
298
|
const byDirectory = new Map<string, Map<string, string[]>>()
|
|
299
|
+
// Thousands of names share a handful of leaves: judge each leaf once.
|
|
300
|
+
const unambiguous = new Map<string, boolean>()
|
|
245
301
|
const members = new Map<string, BarrelMember>()
|
|
246
302
|
for (const [name, member] of exports) {
|
|
247
303
|
if (!member.source.startsWith('.')) continue
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
siblings =
|
|
253
|
-
|
|
304
|
+
let leaf = unambiguous.get(member.source)
|
|
305
|
+
if (leaf === undefined) {
|
|
306
|
+
const file = path.resolve(path.dirname(entry), member.source)
|
|
307
|
+
const directory = path.dirname(file)
|
|
308
|
+
let siblings = byDirectory.get(directory)
|
|
309
|
+
if (!siblings) {
|
|
310
|
+
siblings = siblingFilesByStem(directory, entry)
|
|
311
|
+
byDirectory.set(directory, siblings)
|
|
312
|
+
}
|
|
313
|
+
leaf = siblings.get(path.basename(file).replace(/\.(?:c|m)?js$/, ''))?.length === 1
|
|
314
|
+
unambiguous.set(member.source, leaf)
|
|
254
315
|
}
|
|
255
|
-
if (
|
|
256
|
-
members.set(name, member)
|
|
316
|
+
if (leaf) members.set(name, member)
|
|
257
317
|
}
|
|
258
318
|
return members.size > 0 ? members : undefined
|
|
259
319
|
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// Everything is resolved relative to `process.cwd()`, matching the SWC transform's root. That is what
|
|
15
15
|
// makes the multi-project fixture work: each sub-project is built with its own cwd.
|
|
16
16
|
|
|
17
|
-
import { existsSync } from 'node:fs'
|
|
17
|
+
import { existsSync, realpathSync } from 'node:fs'
|
|
18
18
|
import path from 'node:path'
|
|
19
19
|
import { withSniff, type ServerSourceTransform } from '../../extensions'
|
|
20
20
|
import type { RelayCompilerConfig } from './config'
|
|
@@ -35,6 +35,14 @@ function relayTagPattern(): RegExp {
|
|
|
35
35
|
|
|
36
36
|
const OPERATION_NAME = /\b(?:query|mutation|subscription|fragment)\s+([A-Za-z_][\w]*)/
|
|
37
37
|
|
|
38
|
+
function realFile(file: string): string {
|
|
39
|
+
try {
|
|
40
|
+
return realpathSync(file)
|
|
41
|
+
} catch {
|
|
42
|
+
return file
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
38
46
|
function isUnder(dir: string, file: string): boolean {
|
|
39
47
|
const relative = path.relative(dir, file)
|
|
40
48
|
return relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative)
|
|
@@ -61,6 +69,7 @@ export function createRelayTransform(
|
|
|
61
69
|
|
|
62
70
|
const cwd = path.resolve(process.cwd())
|
|
63
71
|
const srcDir = path.resolve(cwd, relay.src)
|
|
72
|
+
const realSrcDir = realFile(srcDir)
|
|
64
73
|
const artifactDir = relay.artifactDirectory
|
|
65
74
|
? path.resolve(cwd, relay.artifactDirectory)
|
|
66
75
|
: undefined
|
|
@@ -88,11 +97,14 @@ export function createRelayTransform(
|
|
|
88
97
|
|
|
89
98
|
return withSniff(['graphql'], (source, file) => {
|
|
90
99
|
if (!source.includes('graphql`') && !/graphql\s*`/.test(source)) return source
|
|
91
|
-
const
|
|
100
|
+
const resolved = path.resolve(file)
|
|
101
|
+
// A build materializes pages under its out dir; its links lead back to the source file.
|
|
102
|
+
const absolute = isUnder(cwd, resolved) ? realFile(resolved) : resolved
|
|
92
103
|
// Next scopes the transform to `src`. Files outside the build cwd entirely
|
|
93
104
|
// (materialized copies) are not covered by that check, so only skip a file
|
|
94
105
|
// that lives under the cwd but outside the configured source root.
|
|
95
|
-
|
|
106
|
+
const inSrc = isUnder(srcDir, resolved) || isUnder(realSrcDir, absolute)
|
|
107
|
+
if (isUnder(cwd, absolute) && !inSrc) return source
|
|
96
108
|
|
|
97
109
|
const bindings = new Map<string, string>()
|
|
98
110
|
const replaced = source.replace(relayTagPattern(), (match, body: string) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { nextCompatEnabled } from '../compat/aliases'
|
|
4
|
+
import { productionRelease } from '../runtime/production'
|
|
4
5
|
import type { ResolvedConfig } from '../config'
|
|
5
6
|
import type { ResponseFinalizer, ResponseFinalizerContext } from '../extensions'
|
|
6
7
|
import { getNextConfig } from './next/config-loader'
|
|
@@ -31,7 +32,7 @@ export function cacheControlFinalizers(config: ResolvedConfig): ResponseFinalize
|
|
|
31
32
|
rules ??= loadCompatHeaders(config.root)
|
|
32
33
|
applyConfigHeaders(ctx, await rules, config.basePath)
|
|
33
34
|
applyPoweredByHeader(ctx)
|
|
34
|
-
pagesRevalidateRules ??= loadPagesRevalidateRules(config
|
|
35
|
+
pagesRevalidateRules ??= loadPagesRevalidateRules(config)
|
|
35
36
|
applyDefaultIsrHeader(ctx, pagesRevalidateRules)
|
|
36
37
|
}
|
|
37
38
|
return [finalizer]
|
|
@@ -139,20 +140,27 @@ function isBrowserCacheable(value: string): boolean {
|
|
|
139
140
|
return !/\bno-store\b|\bno-cache\b/i.test(value)
|
|
140
141
|
}
|
|
141
142
|
|
|
142
|
-
function loadPagesRevalidateRules(
|
|
143
|
+
function loadPagesRevalidateRules(config: ResolvedConfig): RevalidateRule[] {
|
|
144
|
+
const facts =
|
|
145
|
+
productionRelease(config)?.compat?.pagesRevalidate ?? pagesRevalidateFacts(config.root)
|
|
146
|
+
return facts.flatMap(([relative, revalidateSeconds]) => {
|
|
147
|
+
const regex = pagesRouteRegex(relative)
|
|
148
|
+
return regex ? [{ regex, revalidateSeconds }] : []
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Pages with a `getStaticProps` revalidate window: `[pages-relative file, seconds]`. */
|
|
153
|
+
export function pagesRevalidateFacts(root: string): [string, number][] {
|
|
143
154
|
const pagesDir = path.join(root, 'pages')
|
|
144
155
|
if (!existsSync(pagesDir)) return []
|
|
145
|
-
const
|
|
156
|
+
const facts: [string, number][] = []
|
|
146
157
|
for (const file of walkFiles(pagesDir)) {
|
|
147
158
|
const source = readFileSync(file, 'utf8')
|
|
148
159
|
if (!/\bgetStaticProps\b/.test(source)) continue
|
|
149
160
|
const match = /\brevalidate\s*:\s*(\d+)/.exec(source)
|
|
150
|
-
if (
|
|
151
|
-
const regex = pagesRouteRegex(path.relative(pagesDir, file))
|
|
152
|
-
if (!regex) continue
|
|
153
|
-
rules.push({ regex, revalidateSeconds: Number(match[1]) })
|
|
161
|
+
if (match?.[1]) facts.push([path.relative(pagesDir, file), Number(match[1])])
|
|
154
162
|
}
|
|
155
|
-
return
|
|
163
|
+
return facts
|
|
156
164
|
}
|
|
157
165
|
|
|
158
166
|
function walkFiles(dir: string): string[] {
|
|
@@ -4,10 +4,10 @@ import path from 'node:path'
|
|
|
4
4
|
import type { Plugin } from 'esbuild'
|
|
5
5
|
import type { ResolvedConfig } from '../../config'
|
|
6
6
|
import { resolveImport } from '../../resolve/imports'
|
|
7
|
-
import { hoistCssImports } from '../../css/build'
|
|
8
7
|
import { maybeLightningcssTransform } from './lightningcss'
|
|
9
8
|
import { escapeRegex } from '../../utils/code'
|
|
10
9
|
import { cssModuleScopePath } from '../../utils/fs'
|
|
10
|
+
import { productionRelease } from '../../runtime/production'
|
|
11
11
|
|
|
12
12
|
interface ComposeRef {
|
|
13
13
|
names: string[]
|
|
@@ -23,31 +23,44 @@ interface CssModuleInfo {
|
|
|
23
23
|
const pagesCompatIgnoredSourceEntries = new Set(['.next', '.pnext', 'app', 'node_modules', 'pages'])
|
|
24
24
|
|
|
25
25
|
export function materializeNextCssSources(config: ResolvedConfig) {
|
|
26
|
+
// A production release already compiled everything these links would let resolve.
|
|
27
|
+
if (productionRelease(config)) return
|
|
26
28
|
const generatedRoot = path.dirname(config.appPath)
|
|
27
29
|
if (path.basename(path.dirname(generatedRoot)) !== 'pnext-pages-compat') return
|
|
28
30
|
|
|
31
|
+
const outTop = path.relative(config.root, config.outRootPath).split(path.sep)[0]
|
|
32
|
+
// Inside the app (a build's output) links stay relative, naming no build-machine path.
|
|
33
|
+
const inApp = !path.relative(config.root, generatedRoot).startsWith('..')
|
|
29
34
|
for (const entry of readdirSync(config.root)) {
|
|
30
|
-
if (pagesCompatIgnoredSourceEntries.has(entry)) continue
|
|
35
|
+
if (pagesCompatIgnoredSourceEntries.has(entry) || entry === outTop) continue
|
|
31
36
|
const source = path.join(config.root, entry)
|
|
32
37
|
const target = path.join(generatedRoot, entry)
|
|
33
38
|
if (existsSync(target)) continue
|
|
34
39
|
try {
|
|
35
|
-
symlinkSync(
|
|
40
|
+
symlinkSync(
|
|
41
|
+
inApp ? path.relative(generatedRoot, source) : source,
|
|
42
|
+
target,
|
|
43
|
+
lstatSync(source).isDirectory() ? 'dir' : 'file',
|
|
44
|
+
)
|
|
36
45
|
} catch {
|
|
37
46
|
// A concurrent materialization may have linked the same source already.
|
|
38
47
|
}
|
|
39
48
|
}
|
|
40
49
|
}
|
|
41
50
|
|
|
51
|
+
let cssBuild: Promise<typeof import('../../css/build')> | undefined
|
|
52
|
+
|
|
42
53
|
export function nextCssModuleChunkPlugin(config: ResolvedConfig): Plugin {
|
|
43
54
|
return {
|
|
44
55
|
name: 'pnext-compat-css-modules',
|
|
45
56
|
setup(build) {
|
|
46
|
-
build.onLoad({ filter: /\.css$/ }, ({ path: file }) => {
|
|
57
|
+
build.onLoad({ filter: /\.css$/ }, async ({ path: file }) => {
|
|
47
58
|
const source = nextCssSource(file, config.root)
|
|
48
59
|
// This onLoad claims every `.css`, so core's directive-order plugin
|
|
49
60
|
// (registered after it) never sees a compat app's stylesheet — hoist here.
|
|
50
|
-
const raw =
|
|
61
|
+
const raw = (await (cssBuild ??= import('../../css/build'))).hoistCssImports(
|
|
62
|
+
readFileSync(source, 'utf8'),
|
|
63
|
+
)
|
|
51
64
|
const contents = file.endsWith('.module.css')
|
|
52
65
|
? transformCssModule(raw, source, config.root)
|
|
53
66
|
: rewriteTransparentBodyChildren(raw)
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { getWorkUnit } from '../../request/context'
|
|
12
12
|
import { getRequestRuntime } from '../../routing/request-environment'
|
|
13
|
-
import { selectRouteForRequest } from '../../routing/
|
|
13
|
+
import { selectRouteForRequest } from '../../routing/match'
|
|
14
14
|
import path from 'node:path'
|
|
15
15
|
import type { RouteManifestEntry } from '../../types'
|
|
16
16
|
import type { RequestErrorContext, RequestErrorInfo } from '../../extensions'
|
|
@@ -12,7 +12,15 @@
|
|
|
12
12
|
// separate module state) and calling its register() with NEXT_RUNTIME='edge' set for the duration.
|
|
13
13
|
// Apps without edge entities never get the pass.
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
existsSync,
|
|
17
|
+
mkdirSync,
|
|
18
|
+
readFileSync,
|
|
19
|
+
readdirSync,
|
|
20
|
+
rmSync,
|
|
21
|
+
statSync,
|
|
22
|
+
writeFileSync,
|
|
23
|
+
} from 'node:fs'
|
|
16
24
|
import path from 'node:path'
|
|
17
25
|
import { pathToFileURL } from 'node:url'
|
|
18
26
|
import { createRequire } from 'node:module'
|
|
@@ -21,6 +29,7 @@ import { build } from '../../utils/esbuild'
|
|
|
21
29
|
import type { ResolvedConfig } from '../../config'
|
|
22
30
|
import { resolveExternalLoadTarget } from '../../resolve/imports'
|
|
23
31
|
import { compatAliases, reactServerLayerAliases } from '../aliases'
|
|
32
|
+
import { productionRelease } from '../../runtime/production'
|
|
24
33
|
|
|
25
34
|
const INSTRUMENTATION_BASENAMES = [
|
|
26
35
|
'instrumentation.ts',
|
|
@@ -136,38 +145,89 @@ async function importInstrumentation(
|
|
|
136
145
|
config: ResolvedConfig,
|
|
137
146
|
suffix = '',
|
|
138
147
|
): Promise<InstrumentationModule> {
|
|
139
|
-
const root = config.root
|
|
140
148
|
// Under config.outPath, so a dev server's scratch bundle lives in its own
|
|
141
149
|
// subtree and a concurrent build never removes it mid-import.
|
|
142
150
|
const outDir = path.join(config.outPath, 'instrumentation')
|
|
143
151
|
mkdirSync(outDir, { recursive: true })
|
|
144
152
|
const outfile = path.join(outDir, `instrumentation.${Date.now()}${suffix}.mjs`)
|
|
145
|
-
const tsconfig = path.join(root, 'tsconfig.json')
|
|
146
153
|
try {
|
|
147
|
-
await
|
|
148
|
-
entryPoints: [file],
|
|
149
|
-
outfile,
|
|
150
|
-
bundle: true,
|
|
151
|
-
platform: 'node',
|
|
152
|
-
format: 'esm',
|
|
153
|
-
target: 'esnext',
|
|
154
|
-
packages: 'external',
|
|
155
|
-
plugins: [instrumentationPlugin(root, config)],
|
|
156
|
-
...(existsSync(tsconfig) ? { tsconfig } : {}),
|
|
157
|
-
define: {
|
|
158
|
-
__dirname: JSON.stringify(path.dirname(file)),
|
|
159
|
-
__filename: JSON.stringify(file),
|
|
160
|
-
'import.meta.url': JSON.stringify(pathToFileURL(file).href),
|
|
161
|
-
},
|
|
162
|
-
logLevel: 'silent',
|
|
163
|
-
sourcemap: false,
|
|
164
|
-
})
|
|
154
|
+
await bundleInstrumentation(file, config, outfile)
|
|
165
155
|
return (await import(pathToFileURL(outfile).href)) as InstrumentationModule
|
|
166
156
|
} finally {
|
|
167
157
|
rmSync(outfile, { force: true })
|
|
168
158
|
}
|
|
169
159
|
}
|
|
170
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Bundle instrumentation for a production release: the node instance, plus a separate edge instance
|
|
163
|
+
* file when the app has edge entities. Out-relative paths, or undefined when the app has none.
|
|
164
|
+
*/
|
|
165
|
+
export async function emitReleaseInstrumentation(config: ResolvedConfig, outDir: string) {
|
|
166
|
+
const file = findInstrumentation(config)
|
|
167
|
+
if (!file) return undefined
|
|
168
|
+
const node = await releaseInstrumentation(file, config, outDir, 'instrumentation')
|
|
169
|
+
if (!appHasEdgeEntities(config)) return { file: path.relative(config.outPath, node) }
|
|
170
|
+
const edge = await releaseInstrumentation(file, config, outDir, 'instrumentation.edge')
|
|
171
|
+
return { file: path.relative(config.outPath, node), edge: path.relative(config.outPath, edge) }
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** One release instance: located relative to itself, named by its content (a new generation never reuses a module). */
|
|
175
|
+
async function releaseInstrumentation(
|
|
176
|
+
file: string,
|
|
177
|
+
config: ResolvedConfig,
|
|
178
|
+
outDir: string,
|
|
179
|
+
name: string,
|
|
180
|
+
) {
|
|
181
|
+
const temporary = path.join(outDir, `${name}.${process.pid}.tmp.mjs`)
|
|
182
|
+
await bundleInstrumentation(file, config, temporary, outDir)
|
|
183
|
+
const { relocateReleaseBundle } = await import('../../runtime/modules')
|
|
184
|
+
const contents = relocateReleaseBundle(config, temporary, readFileSync(temporary, 'utf8'))
|
|
185
|
+
rmSync(temporary, { force: true })
|
|
186
|
+
const outfile = path.join(outDir, `${name}.${Bun.hash(contents).toString(36)}.mjs`)
|
|
187
|
+
writeFileSync(outfile, contents)
|
|
188
|
+
return outfile
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function bundleInstrumentation(
|
|
192
|
+
file: string,
|
|
193
|
+
config: ResolvedConfig,
|
|
194
|
+
outfile: string,
|
|
195
|
+
releaseDir?: string,
|
|
196
|
+
) {
|
|
197
|
+
const root = config.root
|
|
198
|
+
const tsconfig = path.join(root, 'tsconfig.json')
|
|
199
|
+
// A release instance finds its source relative to itself, never at the build machine's path.
|
|
200
|
+
const sourceUrl = releaseDir
|
|
201
|
+
? `new URL(${JSON.stringify(path.relative(releaseDir, file).split(path.sep).join('/'))}, import.meta.url).href`
|
|
202
|
+
: JSON.stringify(pathToFileURL(file).href)
|
|
203
|
+
await build({
|
|
204
|
+
entryPoints: [file],
|
|
205
|
+
outfile,
|
|
206
|
+
bundle: true,
|
|
207
|
+
platform: 'node',
|
|
208
|
+
format: 'esm',
|
|
209
|
+
target: 'esnext',
|
|
210
|
+
packages: 'external',
|
|
211
|
+
plugins: [instrumentationPlugin(root, config)],
|
|
212
|
+
...(existsSync(tsconfig) ? { tsconfig } : {}),
|
|
213
|
+
banner: {
|
|
214
|
+
js:
|
|
215
|
+
'import { fileURLToPath as __pnextFileURLToPath } from "node:url";\n' +
|
|
216
|
+
'import { dirname as __pnextDirname } from "node:path";\n' +
|
|
217
|
+
`const __pnextSourceUrl = ${sourceUrl};\n` +
|
|
218
|
+
'const __pnextSourceFile = __pnextFileURLToPath(__pnextSourceUrl);\n' +
|
|
219
|
+
'const __pnextSourceDir = __pnextDirname(__pnextSourceFile);',
|
|
220
|
+
},
|
|
221
|
+
define: {
|
|
222
|
+
__dirname: '__pnextSourceDir',
|
|
223
|
+
__filename: '__pnextSourceFile',
|
|
224
|
+
'import.meta.url': '__pnextSourceUrl',
|
|
225
|
+
},
|
|
226
|
+
logLevel: 'silent',
|
|
227
|
+
sourcemap: false,
|
|
228
|
+
})
|
|
229
|
+
}
|
|
230
|
+
|
|
171
231
|
/**
|
|
172
232
|
* Load instrumentation and run register() once. Idempotent: repeated calls
|
|
173
233
|
* (build + start both run init hooks) reuse the first load. Returns immediately;
|
|
@@ -175,6 +235,11 @@ async function importInstrumentation(
|
|
|
175
235
|
*/
|
|
176
236
|
export function loadInstrumentation(config: ResolvedConfig): void {
|
|
177
237
|
if (readyGate) return
|
|
238
|
+
const released = productionRelease(config)
|
|
239
|
+
if (released) {
|
|
240
|
+
readyGate = registerReleased(released.instrumentation)
|
|
241
|
+
return
|
|
242
|
+
}
|
|
178
243
|
const file = findInstrumentation(config)
|
|
179
244
|
if (!file) {
|
|
180
245
|
readyGate = Promise.resolve()
|
|
@@ -197,21 +262,49 @@ export function loadInstrumentation(config: ResolvedConfig): void {
|
|
|
197
262
|
})()
|
|
198
263
|
}
|
|
199
264
|
|
|
265
|
+
/** A release's prebuilt instrumentation: register() on the node instance, then the edge instance. */
|
|
266
|
+
async function registerReleased(instrumentation: { file?: string; edge?: string } | undefined) {
|
|
267
|
+
if (!instrumentation?.file) return
|
|
268
|
+
try {
|
|
269
|
+
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
270
|
+
if (!process.env.NEXT_RUNTIME) process.env.NEXT_RUNTIME = 'nodejs'
|
|
271
|
+
loaded = (await import(pathToFileURL(instrumentation.file).href)) as InstrumentationModule
|
|
272
|
+
await loaded.register?.()
|
|
273
|
+
if (instrumentation.edge) {
|
|
274
|
+
await withEdgeRuntime(async () => {
|
|
275
|
+
const edgeInstance = (await import(
|
|
276
|
+
pathToFileURL(instrumentation.edge!).href
|
|
277
|
+
)) as InstrumentationModule
|
|
278
|
+
await edgeInstance.register?.()
|
|
279
|
+
}, 'instrumentation register() (edge pass) failed:')
|
|
280
|
+
}
|
|
281
|
+
} catch (error) {
|
|
282
|
+
console.error('instrumentation register() failed:', error)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
200
286
|
/**
|
|
201
287
|
* The edge boot pass: a fresh instrumentation instance registered with NEXT_RUNTIME='edge' for the
|
|
202
288
|
* duration of the call. A double provider registration is harmless - @opentelemetry/api rejects a second
|
|
203
289
|
* global registration and keeps the first.
|
|
204
290
|
*/
|
|
205
291
|
async function runEdgeRegisterPass(file: string, config: ResolvedConfig): Promise<void> {
|
|
292
|
+
await withEdgeRuntime(async () => {
|
|
293
|
+
const edgeInstance = await importInstrumentation(file, config, '.edge')
|
|
294
|
+
await edgeInstance.register?.()
|
|
295
|
+
}, 'instrumentation register() (edge pass) failed:')
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** Run `task` with NEXT_RUNTIME='edge', restoring the previous value. */
|
|
299
|
+
async function withEdgeRuntime(task: () => Promise<void>, failure: string): Promise<void> {
|
|
206
300
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
207
301
|
const previous = process.env.NEXT_RUNTIME
|
|
208
302
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
209
303
|
process.env.NEXT_RUNTIME = 'edge'
|
|
210
304
|
try {
|
|
211
|
-
|
|
212
|
-
await edgeInstance.register?.()
|
|
305
|
+
await task()
|
|
213
306
|
} catch (error) {
|
|
214
|
-
console.error(
|
|
307
|
+
console.error(failure, error)
|
|
215
308
|
} finally {
|
|
216
309
|
if (previous === undefined) {
|
|
217
310
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
@@ -18,9 +18,8 @@ import { currentRequest, getWorkUnit } from '../../request/context'
|
|
|
18
18
|
// readonly property." `require()` returns the real, mutable CJS exports
|
|
19
19
|
// object that node/http/https resolve `.get` calls through at runtime, so
|
|
20
20
|
// patch that instead of the namespace binding.
|
|
21
|
+
// Required on install, not at import: loading node:http/https costs every build ~10 ms.
|
|
21
22
|
const requireNode = createRequire(import.meta.url)
|
|
22
|
-
const httpModule = requireNode('node:http') as typeof http
|
|
23
|
-
const httpsModule = requireNode('node:https') as typeof https
|
|
24
23
|
|
|
25
24
|
interface TestProxyInfo {
|
|
26
25
|
proxyPort: number
|
|
@@ -284,6 +283,8 @@ export function installTestProxyFetch(): void {
|
|
|
284
283
|
;(testFetch as typeof fetch).preconnect = originalFetch.preconnect?.bind(originalFetch)
|
|
285
284
|
globalThis.fetch = testFetch as typeof fetch
|
|
286
285
|
|
|
286
|
+
const httpModule = requireNode('node:http') as typeof http
|
|
287
|
+
const httpsModule = requireNode('node:https') as typeof https
|
|
287
288
|
const originalHttpGet = httpModule.get
|
|
288
289
|
const originalHttpsGet = httpsModule.get
|
|
289
290
|
httpModule.get = patchableGet(originalHttpGet, originalFetch)
|