next.js
d165670e - feat: use Node.js native TS resolver for `next.config.ts` (#83240)

Commit
140 days ago
feat: use Node.js native TS resolver for `next.config.ts` (#83240) ### Why? Since `next.config.ts` was resolved via require-hook, it had a restriction with Native ESM syntax, like top-level await, dynamic import, and Node.js ESM APIs like `import.meta.url`. There were previous attempts to resolve this via the ESM loader, but those approaches (https://github.com/vercel/next.js/pull/68365, https://github.com/vercel/next.js/pull/83120) ended up adding ~39ms compared to the require-hook due to the loader registration time. However, Node.js natively supports TS since v22.7.0 under the experimental flag, and was enabled by default since v23.6.0. Therefore, this PR feature detects the Node.js version and uses its feature to resolve `next.config.ts` and allows native ESM syntax. As a comparison, the usage of ESM loader vs Native TS on a "Large App": - Duration: ~65% faster (186 ms → 66 ms) - RSS: ~41% lower (80 MB → 47 MB) - Heap: ~78% lower (18 MB → 4 MB) <details><summary>Benchmark Details</summary> <p> | Type | Transpile Duration (ms) | Resident Set Size (MB) | Heap Used (MB) | |---------|--------------------------|------------------------|----------------| | ESM | 186.04 | 79.94 | 17.68 | | Native | 66.09 | 47.32 | 3.81 | | **Δ (Abs)** | -119.95 | -32.62 | -13.87 | | **Δ (%)** | -64.5% | -40.8% | -78.4% | </p> </details> ### How? Used Node.js Native TS support (since v22.7.0). Feature detected with `process.features.typescript` (since v22.10.0), and fallback to the legacy resolution for the current session if it throws. This feature follows the restriction of the Native TS support. The notable restrictions are: - Requires extensions for file imports - Doesn't read tsconfig.json (no import alias) - Requires `with { type: 'json' }` when importing JSON For details, see [Node.js Type stripping](https://nodejs.org/api/typescript.html#type-stripping). See the changes below to get the idea of what is restricted or newly allowed. - Changes to fixtures due to restrictions: https://github.com/vercel/next.js/pull/83240/commits/de1bec89f1976aa6f0cba03aa38cae4c1977abec - Additions to fixtures due to ESM support: https://github.com/vercel/next.js/pull/83240/commits/622a2a828693422aa511793af56734f40569d9f5 Added `next-config-ts-native-ts` tests on CI to run on Node.js v22 and v24. ## Benchmark #### Hello World App - Duration: ~68% faster (102 ms → 32 ms) - RSS: ~65% lower (72 MB → 25 MB) - Heap: ~87% lower (31 MB → 4 MB) <details><summary>Benchmark Details</summary> <p> | Attempt | Transpile Duration (ms) | Resident Set Size (MB) | Heap Used (MB) | |-----------|--------------------------|------------------------|----------------| | CJS 1 | 104.03 | 69.16 | 30.32 | | CJS 2 | 100.35 | 59.95 | 30.14 | | CJS 3 | 100.77 | 75.83 | 32.18 | | CJS 4 | 103.43 | 77.33 | 30.13 | | CJS 5 | 100.82 | 76.30 | 30.22 | | Native 1 | 33.75 | 25.19 | 3.84 | | Native 2 | 28.71 | 21.72 | 3.85 | | Native 3 | 33.49 | 28.95 | 3.85 | | Native 4 | 32.78 | 24.97 | 3.85 | | Native 5 | 33.43 | 24.89 | 3.85 | | **CJS Avg** | 101.88 | 71.71 | 30.60 | | **Native Avg**| 32.43 | 25.14 | 3.85 | | **Δ (Abs)** | -69.45 | -46.57 | -26.75 | | **Δ (%)** | -68.2% | -64.9% | -87.4% | </p> </details> #### Large App > Benchmarked from a large repository that imports packages like `@next/bundle-analyzer`. - Duration: ~56% faster (152 ms → 66 ms) - RSS: ~30% lower (68 MB → 47 MB) - Heap: ~78% lower (17 MB → 4 MB) <details><summary>Benchmark Details</summary> <p> | Attempt | Transpile Duration (ms) | Resident Set Size (MB) | Heap Used (MB) | |-----------|--------------------------|------------------------|----------------| | CJS 1 | 154.35 | 67.73 | 17.16 | | CJS 2 | 148.02 | 61.33 | 17.32 | | CJS 3 | 152.44 | 66.06 | 17.14 | | CJS 4 | 149.89 | 74.33 | 17.17 | | CJS 5 | 156.27 | 68.20 | 17.25 | | Native 1 | 68.01 | 34.66 | 5.51 | | Native 2 | 66.41 | 53.83 | 5.48 | | Native 3 | 62.39 | 45.80 | 1.48 | | Native 4 | 65.20 | 52.02 | 1.35 | | Native 5 | 68.44 | 50.31 | 5.25 | | **CJS Avg** | 152.19 | 67.53 | 17.21 | | **Native Avg**| 66.09 | 47.32 | 3.81 | | **Δ (Abs)** | -86.10 | -20.21 | -13.39 | | **Δ (%)** | -56.6% | -29.9% | -77.8% | </p> </details> Fixes https://github.com/vercel/next.js/issues/67765 Fixes https://github.com/vercel/next.js/issues/71705 Closes [NDX-494](https://linear.app/vercel/issue/NDX-494) --------- Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> Co-authored-by: Sebastian "Sebbie" Silbermann <silbermann.sebastian@gmail.com>
Author
Parents
Loading