next 16.2.11 → 16.2.12

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.
Files changed (155) hide show
  1. package/dist/.build-commit +1 -1
  2. package/dist/bin/next +2 -2
  3. package/dist/build/index.js +3 -3
  4. package/dist/build/load-jsconfig.js +40 -20
  5. package/dist/build/load-jsconfig.js.map +1 -1
  6. package/dist/build/next-config-ts/transpile-config.js +3 -114
  7. package/dist/build/next-config-ts/transpile-config.js.map +1 -1
  8. package/dist/build/swc/index.js +1 -1
  9. package/dist/build/turbopack-analyze/index.js +1 -1
  10. package/dist/build/turbopack-build/impl.js +1 -1
  11. package/dist/build/type-check.js +20 -13
  12. package/dist/build/type-check.js.map +1 -1
  13. package/dist/build/webpack-config.js +3 -3
  14. package/dist/bundle-analyzer/404.html +2 -2
  15. package/dist/bundle-analyzer/__next.__PAGE__.txt +1 -1
  16. package/dist/bundle-analyzer/__next._full.txt +1 -1
  17. package/dist/bundle-analyzer/__next._head.txt +1 -1
  18. package/dist/bundle-analyzer/__next._index.txt +1 -1
  19. package/dist/bundle-analyzer/__next._tree.txt +1 -1
  20. package/dist/bundle-analyzer/_not-found/__next._full.txt +1 -1
  21. package/dist/bundle-analyzer/_not-found/__next._head.txt +1 -1
  22. package/dist/bundle-analyzer/_not-found/__next._index.txt +1 -1
  23. package/dist/bundle-analyzer/_not-found/__next._not-found.__PAGE__.txt +1 -1
  24. package/dist/bundle-analyzer/_not-found/__next._not-found.txt +1 -1
  25. package/dist/bundle-analyzer/_not-found/__next._tree.txt +1 -1
  26. package/dist/bundle-analyzer/_not-found.html +2 -2
  27. package/dist/bundle-analyzer/_not-found.txt +1 -1
  28. package/dist/bundle-analyzer/index.html +2 -2
  29. package/dist/bundle-analyzer/index.txt +1 -1
  30. package/dist/cli/next-test.js +2 -1
  31. package/dist/cli/next-test.js.map +1 -1
  32. package/dist/cli/next-typegen.js +2 -1
  33. package/dist/cli/next-typegen.js.map +1 -1
  34. package/dist/client/app-bootstrap.js +1 -1
  35. package/dist/client/index.js +1 -1
  36. package/dist/compiled/next-server/pages-api-turbo.runtime.dev.js +1 -1
  37. package/dist/compiled/next-server/pages-api-turbo.runtime.dev.js.map +1 -1
  38. package/dist/compiled/next-server/pages-turbo.runtime.dev.js +1 -1
  39. package/dist/compiled/next-server/pages-turbo.runtime.dev.js.map +1 -1
  40. package/dist/compiled/next-server/server.runtime.prod.js +1 -1
  41. package/dist/compiled/next-server/server.runtime.prod.js.map +1 -1
  42. package/dist/docs/01-app/01-getting-started/01-installation.md +33 -0
  43. package/dist/docs/01-app/01-getting-started/02-project-structure.md +1 -1
  44. package/dist/docs/01-app/01-getting-started/06-fetching-data.md +1 -1
  45. package/dist/docs/01-app/01-getting-started/09-revalidating.md +1 -1
  46. package/dist/docs/01-app/02-guides/authentication.md +18 -10
  47. package/dist/docs/01-app/02-guides/backend-for-frontend.md +1 -1
  48. package/dist/docs/01-app/02-guides/debugging.md +2 -2
  49. package/dist/docs/01-app/02-guides/migrating/app-router-migration.md +18 -14
  50. package/dist/docs/01-app/02-guides/single-page-applications.md +1 -1
  51. package/dist/docs/01-app/02-guides/static-exports.md +2 -0
  52. package/dist/docs/01-app/03-api-reference/02-components/form.md +1 -1
  53. package/dist/docs/01-app/03-api-reference/03-file-conventions/error.md +2 -0
  54. package/dist/docs/01-app/03-api-reference/03-file-conventions/not-found.md +3 -1
  55. package/dist/docs/01-app/03-api-reference/04-functions/redirect.md +1 -0
  56. package/dist/docs/01-app/03-api-reference/04-functions/refresh.md +4 -1
  57. package/dist/docs/01-app/03-api-reference/04-functions/revalidatePath.md +3 -0
  58. package/dist/docs/01-app/03-api-reference/04-functions/revalidateTag.md +3 -0
  59. package/dist/docs/01-app/03-api-reference/04-functions/unstable_cache.md +5 -5
  60. package/dist/docs/01-app/03-api-reference/04-functions/use-search-params.md +1 -1
  61. package/dist/docs/01-app/03-api-reference/05-config/01-next-config-js/headers.md +11 -11
  62. package/dist/docs/01-app/03-api-reference/05-config/01-next-config-js/redirects.md +10 -10
  63. package/dist/docs/01-app/03-api-reference/05-config/01-next-config-js/rewrites.md +16 -16
  64. package/dist/docs/01-app/03-api-reference/05-config/01-next-config-js/serverActions.md +4 -1
  65. package/dist/docs/01-app/03-api-reference/05-config/01-next-config-js/useTypeScriptCli.md +62 -0
  66. package/dist/docs/01-app/03-api-reference/05-config/02-typescript.md +55 -1
  67. package/dist/docs/01-app/03-api-reference/07-adapters/05-routing-with-next-routing.md +0 -3
  68. package/dist/docs/02-pages/02-guides/forms.md +6 -6
  69. package/dist/docs/02-pages/03-building-your-application/01-routing/08-custom-error.md +2 -0
  70. package/dist/docs/02-pages/04-api-reference/04-config/01-next-config-js/useTypeScriptCli.md +8 -0
  71. package/dist/esm/build/index.js +3 -3
  72. package/dist/esm/build/load-jsconfig.js +40 -20
  73. package/dist/esm/build/load-jsconfig.js.map +1 -1
  74. package/dist/esm/build/next-config-ts/transpile-config.js +3 -73
  75. package/dist/esm/build/next-config-ts/transpile-config.js.map +1 -1
  76. package/dist/esm/build/swc/index.js +1 -1
  77. package/dist/esm/build/turbopack-analyze/index.js +1 -1
  78. package/dist/esm/build/turbopack-build/impl.js +1 -1
  79. package/dist/esm/build/type-check.js +20 -13
  80. package/dist/esm/build/type-check.js.map +1 -1
  81. package/dist/esm/build/webpack-config.js +3 -3
  82. package/dist/esm/client/app-bootstrap.js +1 -1
  83. package/dist/esm/client/index.js +1 -1
  84. package/dist/esm/lib/has-necessary-dependencies.js.map +1 -1
  85. package/dist/esm/lib/install-dependencies.js +1 -1
  86. package/dist/esm/lib/install-dependencies.js.map +1 -1
  87. package/dist/esm/lib/patch-incorrect-lockfile.js +3 -3
  88. package/dist/esm/lib/typescript/loadTsConfig.js +129 -0
  89. package/dist/esm/lib/typescript/loadTsConfig.js.map +1 -0
  90. package/dist/esm/lib/typescript/missingDependencyError.js +1 -1
  91. package/dist/esm/lib/typescript/missingDependencyError.js.map +1 -1
  92. package/dist/esm/lib/typescript/runTypeCheck.js.map +1 -1
  93. package/dist/esm/lib/typescript/runTypeCheckCli.js +38 -0
  94. package/dist/esm/lib/typescript/runTypeCheckCli.js.map +1 -0
  95. package/dist/esm/lib/typescript/runTypeScriptCli.js +217 -0
  96. package/dist/esm/lib/typescript/runTypeScriptCli.js.map +1 -0
  97. package/dist/esm/lib/verify-typescript-setup.js +87 -52
  98. package/dist/esm/lib/verify-typescript-setup.js.map +1 -1
  99. package/dist/esm/server/config-schema.js +1 -0
  100. package/dist/esm/server/config-schema.js.map +1 -1
  101. package/dist/esm/server/config-shared.js +1 -0
  102. package/dist/esm/server/config-shared.js.map +1 -1
  103. package/dist/esm/server/config.js +1 -1
  104. package/dist/esm/server/dev/hot-reloader-turbopack.js +2 -2
  105. package/dist/esm/server/dev/hot-reloader-webpack.js +1 -1
  106. package/dist/esm/server/lib/app-info-log.js +1 -1
  107. package/dist/esm/server/lib/router-utils/setup-dev-bundler.js +2 -1
  108. package/dist/esm/server/lib/router-utils/setup-dev-bundler.js.map +1 -1
  109. package/dist/esm/server/lib/start-server.js +1 -1
  110. package/dist/esm/shared/lib/errors/canary-only-config-error.js +1 -1
  111. package/dist/lib/has-necessary-dependencies.d.ts +2 -0
  112. package/dist/lib/has-necessary-dependencies.js.map +1 -1
  113. package/dist/lib/install-dependencies.js +1 -1
  114. package/dist/lib/install-dependencies.js.map +1 -1
  115. package/dist/lib/patch-incorrect-lockfile.js +3 -3
  116. package/dist/lib/typescript/loadTsConfig.d.ts +13 -0
  117. package/dist/lib/typescript/loadTsConfig.js +181 -0
  118. package/dist/lib/typescript/loadTsConfig.js.map +1 -0
  119. package/dist/lib/typescript/missingDependencyError.js +1 -1
  120. package/dist/lib/typescript/missingDependencyError.js.map +1 -1
  121. package/dist/lib/typescript/runTypeCheck.d.ts +2 -2
  122. package/dist/lib/typescript/runTypeCheck.js.map +1 -1
  123. package/dist/lib/typescript/runTypeCheckCli.d.ts +12 -0
  124. package/dist/lib/typescript/runTypeCheckCli.js +53 -0
  125. package/dist/lib/typescript/runTypeCheckCli.js.map +1 -0
  126. package/dist/lib/typescript/runTypeScriptCli.d.ts +38 -0
  127. package/dist/lib/typescript/runTypeScriptCli.js +256 -0
  128. package/dist/lib/typescript/runTypeScriptCli.js.map +1 -0
  129. package/dist/lib/verify-typescript-setup.d.ts +16 -1
  130. package/dist/lib/verify-typescript-setup.js +97 -56
  131. package/dist/lib/verify-typescript-setup.js.map +1 -1
  132. package/dist/server/config-schema.d.ts +1 -0
  133. package/dist/server/config-schema.js +1 -0
  134. package/dist/server/config-schema.js.map +1 -1
  135. package/dist/server/config-shared.d.ts +6 -0
  136. package/dist/server/config-shared.js +1 -0
  137. package/dist/server/config-shared.js.map +1 -1
  138. package/dist/server/config.js +1 -1
  139. package/dist/server/dev/hot-reloader-turbopack.js +2 -2
  140. package/dist/server/dev/hot-reloader-webpack.js +1 -1
  141. package/dist/server/lib/app-info-log.js +1 -1
  142. package/dist/server/lib/router-utils/setup-dev-bundler.js +2 -1
  143. package/dist/server/lib/router-utils/setup-dev-bundler.js.map +1 -1
  144. package/dist/server/lib/start-server.js +1 -1
  145. package/dist/shared/lib/errors/canary-only-config-error.js +1 -1
  146. package/dist/telemetry/anonymous-meta.js +1 -1
  147. package/dist/telemetry/events/build.d.ts +1 -0
  148. package/dist/telemetry/events/build.js.map +1 -1
  149. package/dist/telemetry/events/session-stopped.js +2 -2
  150. package/dist/telemetry/events/swc-load-failure.js +1 -1
  151. package/dist/telemetry/events/version.js +2 -2
  152. package/package.json +10 -10
  153. /package/dist/bundle-analyzer/_next/static/{yuLxudwpXbv0jKSL-s0ZM → xR78HbVQBty3GRl-Ydf7i}/_buildManifest.js +0 -0
  154. /package/dist/bundle-analyzer/_next/static/{yuLxudwpXbv0jKSL-s0ZM → xR78HbVQBty3GRl-Ydf7i}/_clientMiddlewareManifest.json +0 -0
  155. /package/dist/bundle-analyzer/_next/static/{yuLxudwpXbv0jKSL-s0ZM → xR78HbVQBty3GRl-Ydf7i}/_ssgManifest.js +0 -0
@@ -23,7 +23,7 @@ To use rewrites you can use the `rewrites` key in `next.config.js`:
23
23
 
24
24
  ```js filename="next.config.js"
25
25
  module.exports = {
26
- async rewrites() {
26
+ rewrites() {
27
27
  return [
28
28
  {
29
29
  source: '/about',
@@ -36,7 +36,7 @@ module.exports = {
36
36
 
37
37
  Rewrites are applied to client-side routing. In the example above, navigating to `<Link href="/about">` will serve content from `/` while keeping the URL as `/about`.
38
38
 
39
- `rewrites` is an async function that expects to return either an array or an object of arrays (see below) holding objects with `source` and `destination` properties:
39
+ `rewrites` can be defined as a synchronous or async function. It should return, or resolve to, either an array or an object of arrays (see below) holding objects with `source` and `destination` properties:
40
40
 
41
41
  - `source`: `String` - is the incoming request path pattern.
42
42
  - `destination`: `String` is the path you want to route to.
@@ -49,7 +49,7 @@ When the `rewrites` function returns an array, rewrites are applied after checki
49
49
 
50
50
  ```js filename="next.config.js"
51
51
  module.exports = {
52
- async rewrites() {
52
+ rewrites() {
53
53
  return {
54
54
  beforeFiles: [
55
55
  // These rewrites are checked after headers/redirects
@@ -117,7 +117,7 @@ When using parameters in a rewrite the parameters will be passed in the query by
117
117
 
118
118
  ```js filename="next.config.js"
119
119
  module.exports = {
120
- async rewrites() {
120
+ rewrites() {
121
121
  return [
122
122
  {
123
123
  source: '/old-about/:path*',
@@ -132,7 +132,7 @@ If a parameter is used in the destination none of the parameters will be automat
132
132
 
133
133
  ```js filename="next.config.js"
134
134
  module.exports = {
135
- async rewrites() {
135
+ rewrites() {
136
136
  return [
137
137
  {
138
138
  source: '/docs/:path*',
@@ -147,7 +147,7 @@ You can still pass the parameters manually in the query if one is already used i
147
147
 
148
148
  ```js filename="next.config.js"
149
149
  module.exports = {
150
- async rewrites() {
150
+ rewrites() {
151
151
  return [
152
152
  {
153
153
  source: '/:first/:second',
@@ -169,7 +169,7 @@ Path matches are allowed, for example `/blog/:slug` will match `/blog/first-post
169
169
 
170
170
  ```js filename="next.config.js"
171
171
  module.exports = {
172
- async rewrites() {
172
+ rewrites() {
173
173
  return [
174
174
  {
175
175
  source: '/blog/:slug',
@@ -192,7 +192,7 @@ To match a wildcard path you can use `*` after a parameter, for example `/blog/:
192
192
 
193
193
  ```js filename="next.config.js"
194
194
  module.exports = {
195
- async rewrites() {
195
+ rewrites() {
196
196
  return [
197
197
  {
198
198
  source: '/blog/:slug*',
@@ -209,7 +209,7 @@ To match a regex path you can wrap the regex in parenthesis after a parameter, f
209
209
 
210
210
  ```js filename="next.config.js"
211
211
  module.exports = {
212
- async rewrites() {
212
+ rewrites() {
213
213
  return [
214
214
  {
215
215
  source: '/old-blog/:post(\\d{1,})',
@@ -224,7 +224,7 @@ The following characters `(`, `)`, `{`, `}`, `[`, `]`, `|`, `\`, `^`, `.`, `:`,
224
224
 
225
225
  ```js filename="next.config.js"
226
226
  module.exports = {
227
- async rewrites() {
227
+ rewrites() {
228
228
  return [
229
229
  {
230
230
  // this will match `/english(default)/something` being requested
@@ -248,7 +248,7 @@ To only match a rewrite when header, cookie, or query values also match the `has
248
248
 
249
249
  ```js filename="next.config.js"
250
250
  module.exports = {
251
- async rewrites() {
251
+ rewrites() {
252
252
  return [
253
253
  // if the header `x-rewrite-me` is present,
254
254
  // this rewrite will be applied
@@ -338,7 +338,7 @@ Rewrites allow you to rewrite to an external URL. This is especially useful for
338
338
 
339
339
  ```js filename="next.config.js"
340
340
  module.exports = {
341
- async rewrites() {
341
+ rewrites() {
342
342
  return [
343
343
  {
344
344
  source: '/blog',
@@ -358,7 +358,7 @@ If you're using `trailingSlash: true`, you also need to insert a trailing slash
358
358
  ```js filename="next.config.js"
359
359
  module.exports = {
360
360
  trailingSlash: true,
361
- async rewrites() {
361
+ rewrites() {
362
362
  return [
363
363
  {
364
364
  source: '/blog/',
@@ -381,7 +381,7 @@ This way you don't have to change the rewrites configuration when migrating more
381
381
 
382
382
  ```js filename="next.config.js"
383
383
  module.exports = {
384
- async rewrites() {
384
+ rewrites() {
385
385
  return {
386
386
  fallback: [
387
387
  {
@@ -402,7 +402,7 @@ When leveraging [`basePath` support](/docs/app/api-reference/config/next-config-
402
402
  module.exports = {
403
403
  basePath: '/docs',
404
404
 
405
- async rewrites() {
405
+ rewrites() {
406
406
  return [
407
407
  {
408
408
  source: '/with-basePath', // automatically becomes /docs/with-basePath
@@ -433,7 +433,7 @@ module.exports = {
433
433
  defaultLocale: 'en',
434
434
  },
435
435
 
436
- async rewrites() {
436
+ rewrites() {
437
437
  return [
438
438
  {
439
439
  source: '/with-locale', // automatically handles all locales
@@ -1,9 +1,12 @@
1
1
  ---
2
2
  title: serverActions
3
3
  description: Configure Server Actions behavior in your Next.js application.
4
+ related:
5
+ links:
6
+ - app/guides/server-actions
4
7
  ---
5
8
 
6
- Options for configuring Server Actions behavior in your Next.js application.
9
+ Options for configuring Server Actions behavior in your Next.js application. For how Server Actions work, including the security boundary these options tune, see the [Server Actions guide](/docs/app/guides/server-actions).
7
10
 
8
11
  ## `allowedOrigins`
9
12
 
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: useTypeScriptCli
3
+ description: Run the project-local TypeScript CLI for type checking during production builds.
4
+ version: experimental
5
+ ---
6
+
7
+ The `experimental.useTypeScriptCli` option makes `next build` run the project-local `tsc` command instead of loading the TypeScript JavaScript compiler API. You can use this option with TypeScript 6, and it enables [TypeScript 7](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/) support while its JavaScript API is unavailable.
8
+
9
+ Install TypeScript 7 in your project:
10
+
11
+ ```bash package="pnpm"
12
+ pnpm add -D typescript@^7
13
+ ```
14
+
15
+ ```bash package="npm"
16
+ npm install -D typescript@^7
17
+ ```
18
+
19
+ ```bash package="yarn"
20
+ yarn add -D typescript@^7
21
+ ```
22
+
23
+ ```bash package="bun"
24
+ bun add -D typescript@^7
25
+ ```
26
+
27
+ Then, explicitly enable the CLI checker:
28
+
29
+ ```ts filename="next.config.ts" switcher
30
+ import type { NextConfig } from 'next'
31
+
32
+ const nextConfig: NextConfig = {
33
+ experimental: {
34
+ useTypeScriptCli: true,
35
+ },
36
+ }
37
+
38
+ export default nextConfig
39
+ ```
40
+
41
+ ```js filename="next.config.js" switcher
42
+ /** @type {import('next').NextConfig} */
43
+ const nextConfig = {
44
+ experimental: {
45
+ useTypeScriptCli: true,
46
+ },
47
+ }
48
+
49
+ module.exports = nextConfig
50
+ ```
51
+
52
+ Next.js does not select the CLI checker automatically. If TypeScript 7 is installed without this option, `next build` exits with instructions to enable it or install a TypeScript version supported by the default checker.
53
+
54
+ ## Behavior
55
+
56
+ - Next.js continues to generate `next-env.d.ts` and route types and to apply its recommended `tsconfig` settings before running the checker.
57
+ - TypeScript diagnostics are printed directly from `tsc`. Next.js-specific code frames and error rewriting are not applied.
58
+ - The complete project selected by the configured `tsconfig` file is checked, including test files and `.next/dev/types` when included. The [`--debug-build-paths`](/docs/app/api-reference/cli/next#next-build-options) option does not limit this set and produces a warning when combined with the CLI checker.
59
+ - [`typescript.tsconfigPath`](/docs/app/api-reference/config/typescript#custom-tsconfig-path) selects the project passed to `tsc`.
60
+ - [`typescript.ignoreBuildErrors`](/docs/app/api-reference/config/typescript#disabling-typescript-errors-in-production) skips the type-checking step, including the CLI checker.
61
+
62
+ Learn more about [using TypeScript 7 with Next.js](/docs/app/api-reference/config/typescript#using-typescript-7).
@@ -11,6 +11,60 @@ To add TypeScript to an existing project, rename a file to `.ts` / `.tsx`. Run `
11
11
 
12
12
  > **Good to know**: If you already have a `jsconfig.json` file, copy the `paths` compiler option from the old `jsconfig.json` into the new `tsconfig.json` file, and delete the old `jsconfig.json` file.
13
13
 
14
+ ## Using TypeScript 7
15
+
16
+ [TypeScript 7](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/) does not currently provide the JavaScript compiler API that Next.js uses for type checking by default. To use TypeScript 7 during `next build`, install it in your project:
17
+
18
+ ```bash package="pnpm"
19
+ pnpm add -D typescript@^7
20
+ ```
21
+
22
+ ```bash package="npm"
23
+ npm install -D typescript@^7
24
+ ```
25
+
26
+ ```bash package="yarn"
27
+ yarn add -D typescript@^7
28
+ ```
29
+
30
+ ```bash package="bun"
31
+ bun add -D typescript@^7
32
+ ```
33
+
34
+ Then, opt in to running the project-local `tsc` CLI instead of the JavaScript API with [`experimental.useTypeScriptCli`](/docs/app/api-reference/config/next-config-js/useTypeScriptCli):
35
+
36
+ ```ts filename="next.config.ts" switcher
37
+ import type { NextConfig } from 'next'
38
+
39
+ const nextConfig: NextConfig = {
40
+ experimental: {
41
+ useTypeScriptCli: true,
42
+ },
43
+ }
44
+
45
+ export default nextConfig
46
+ ```
47
+
48
+ ```js filename="next.config.js" switcher
49
+ /** @type {import('next').NextConfig} */
50
+ const nextConfig = {
51
+ experimental: {
52
+ useTypeScriptCli: true,
53
+ },
54
+ }
55
+
56
+ module.exports = nextConfig
57
+ ```
58
+
59
+ Next.js does not enable this option automatically. If you install TypeScript 7 without enabling `experimental.useTypeScriptCli`, `next build` exits with instructions to enable the option or install a TypeScript version supported by the default checker.
60
+
61
+ > **Good to know**:
62
+ >
63
+ > - CLI type checking prints the native `tsc` diagnostics. It does not apply Next.js-specific code frames or rewrite errors for routes, pages, layouts, or route handlers.
64
+ > - The CLI checks the complete project selected by your `tsconfig` file. This includes test files and `.next/dev/types` when they are included by that configuration. [`next build --debug-build-paths`](/docs/app/api-reference/cli/next#next-build-options) does not narrow the files that are type checked and produces a warning when used with this option.
65
+ > - [`typescript.tsconfigPath`](#custom-tsconfig-path) continues to select the configuration passed to `tsc`. [`typescript.ignoreBuildErrors`](#disabling-typescript-errors-in-production) skips the type-checking step, including the CLI checker.
66
+ > - `experimental.useTypeScriptCli` is experimental and its behavior may change.
67
+
14
68
  <AppOnly>
15
69
 
16
70
  ## IDE Plugin
@@ -31,7 +85,7 @@ You can enable the plugin in VS Code by:
31
85
  height="637"
32
86
  />
33
87
 
34
- Now, when editing files, the custom plugin will be enabled. When running `next build`, the custom type checker will be used.
88
+ Now, when editing files, the custom plugin will be enabled. By default, the custom type checker is used when running `next build`. When [`experimental.useTypeScriptCli`](#using-typescript-7) is enabled, the project-local `tsc` CLI is used instead.
35
89
 
36
90
  The TypeScript plugin can help with:
37
91
 
@@ -5,9 +5,6 @@ description: Use `@next/routing` to apply Next.js route matching behavior in ada
5
5
 
6
6
  You can use [`@next/routing`](https://www.npmjs.com/package/@next/routing) to reproduce Next.js route matching behavior with data from `onBuildComplete`.
7
7
 
8
- > [!NOTE]
9
- > `@next/routing` is experimental and will stabilize with the adapters API.
10
-
11
8
  ```typescript
12
9
  import { resolveRoutes } from '@next/routing'
13
10
 
@@ -36,10 +36,10 @@ export default function handler(req, res) {
36
36
  Then, call the API Route from the client with an event handler:
37
37
 
38
38
  ```tsx filename="pages/index.tsx" switcher
39
- import { FormEvent } from 'react'
39
+ import { SubmitEvent } from 'react'
40
40
 
41
41
  export default function Page() {
42
- async function onSubmit(event: FormEvent<HTMLFormElement>) {
42
+ async function onSubmit(event: SubmitEvent<HTMLFormElement>) {
43
43
  event.preventDefault()
44
44
 
45
45
  const formData = new FormData(event.currentTarget)
@@ -133,13 +133,13 @@ export default async function handler(req, res) {
133
133
  You can use React state to show an error message when a form submission fails:
134
134
 
135
135
  ```tsx filename="pages/index.tsx" switcher
136
- import React, { useState, FormEvent } from 'react'
136
+ import React, { useState, SubmitEvent } from 'react'
137
137
 
138
138
  export default function Page() {
139
139
  const [isLoading, setIsLoading] = useState<boolean>(false)
140
140
  const [error, setError] = useState<string | null>(null)
141
141
 
142
- async function onSubmit(event: FormEvent<HTMLFormElement>) {
142
+ async function onSubmit(event: SubmitEvent<HTMLFormElement>) {
143
143
  event.preventDefault()
144
144
  setIsLoading(true)
145
145
  setError(null) // Clear previous errors when a new request starts
@@ -235,12 +235,12 @@ export default function Page() {
235
235
  You can use React state to show a loading state when a form is submitting on the server:
236
236
 
237
237
  ```tsx filename="pages/index.tsx" switcher
238
- import React, { useState, FormEvent } from 'react'
238
+ import React, { useState, SubmitEvent } from 'react'
239
239
 
240
240
  export default function Page() {
241
241
  const [isLoading, setIsLoading] = useState<boolean>(false)
242
242
 
243
- async function onSubmit(event: FormEvent<HTMLFormElement>) {
243
+ async function onSubmit(event: SubmitEvent<HTMLFormElement>) {
244
244
  event.preventDefault()
245
245
  setIsLoading(true) // Set loading to true when the request starts
246
246
 
@@ -9,6 +9,8 @@ A 404 page may be accessed very often. Server-rendering an error page for every
9
9
 
10
10
  To avoid the above pitfalls, Next.js provides a static 404 page by default without having to add any additional files.
11
11
 
12
+ > **Good to know**: The default 404 and 500 pages follow the operating system's color scheme via `prefers-color-scheme` and do not read an app-level theme. Because `pages/404.js` and `pages/500.js` render inside your custom `App`, providing your own files lets your global styles and theme apply.
13
+
12
14
  ### Customizing The 404 Page
13
15
 
14
16
  To create a custom 404 page you can create a `pages/404.js` file. This file is statically generated at build time.
@@ -0,0 +1,8 @@
1
+ ---
2
+ title: useTypeScriptCli
3
+ description: Run the project-local TypeScript CLI for type checking during production builds.
4
+ source: app/api-reference/config/next-config-js/useTypeScriptCli
5
+ version: experimental
6
+ ---
7
+
8
+ {/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
@@ -333,7 +333,7 @@ export default async function build(dir, experimentalAnalyze = false, reactProdu
333
333
  try {
334
334
  const nextBuildSpan = trace('next-build', undefined, {
335
335
  buildMode: experimentalBuildMode,
336
- version: "16.2.11",
336
+ version: "16.2.12",
337
337
  ...enabledFeatures
338
338
  });
339
339
  NextBuildContext.nextBuildSpan = nextBuildSpan;
@@ -769,7 +769,7 @@ export default async function build(dir, experimentalAnalyze = false, reactProdu
769
769
  // Files outside of the distDir can be "type": "module"
770
770
  await writeFileUtf8(path.join(distDir, 'package.json'), '{"type": "commonjs"}');
771
771
  // These are written to distDir, so they need to come after creating and cleaning distDr.
772
- await recordFrameworkVersion("16.2.11");
772
+ await recordFrameworkVersion("16.2.12");
773
773
  await updateBuildDiagnostics({
774
774
  buildStage: 'start'
775
775
  });
@@ -2497,7 +2497,7 @@ export default async function build(dir, experimentalAnalyze = false, reactProdu
2497
2497
  configOutDir: path.join(dir, configOutDir),
2498
2498
  staticPages,
2499
2499
  serverPropsPages,
2500
- nextVersion: "16.2.11",
2500
+ nextVersion: "16.2.12",
2501
2501
  tracingRoot: outputFileTracingRoot,
2502
2502
  hasNodeMiddleware,
2503
2503
  hasInstrumentationHook,
@@ -4,8 +4,9 @@ import * as Log from './output/log';
4
4
  import { getTypeScriptConfiguration } from '../lib/typescript/getTypeScriptConfiguration';
5
5
  import { readFileSync } from 'fs';
6
6
  import isError from '../lib/is-error';
7
- import { hasNecessaryDependencies } from '../lib/has-necessary-dependencies';
8
7
  import { codeFrameColumns } from '../shared/lib/errors/code-frame';
8
+ import { getTypeScriptApiMissingError, getTypeScriptConfigurationCli, getTypeScriptPackageInfo, hasNativeTypeScriptPreview } from '../lib/typescript/runTypeScriptCli';
9
+ import { loadTsConfigOptions } from '../lib/typescript/loadTsConfig';
9
10
  let TSCONFIG_WARNED = false;
10
11
  export function parseJsonFile(filePath) {
11
12
  const JSON5 = require('next/dist/compiled/json5');
@@ -36,19 +37,14 @@ export function parseJsonFile(filePath) {
36
37
  }
37
38
  export default async function loadJsConfig(dir, config) {
38
39
  var _jsConfig_compilerOptions;
39
- let typeScriptPath;
40
- try {
41
- const deps = hasNecessaryDependencies(dir, [
42
- {
43
- pkg: 'typescript',
44
- file: 'typescript/lib/typescript.js',
45
- exportsRestrict: true
46
- }
47
- ]);
48
- typeScriptPath = deps.resolved.get('typescript');
49
- } catch {}
40
+ const useTypeScriptCli = Boolean(config.experimental.useTypeScriptCli);
41
+ const typeScriptPackage = getTypeScriptPackageInfo(dir);
42
+ const typeScriptPath = useTypeScriptCli ? typeScriptPackage == null ? void 0 : typeScriptPackage.tscPath : typeScriptPackage == null ? void 0 : typeScriptPackage.apiPath;
50
43
  const tsConfigFileName = config.typescript.tsconfigPath || 'tsconfig.json';
51
44
  const tsConfigPath = path.join(dir, tsConfigFileName);
45
+ if (!useTypeScriptCli && typeScriptPackage && !typeScriptPackage.apiPath && !hasNativeTypeScriptPreview(dir) && fs.existsSync(tsConfigPath)) {
46
+ throw getTypeScriptApiMissingError(typeScriptPackage.version);
47
+ }
52
48
  const useTypeScript = Boolean(typeScriptPath && fs.existsSync(tsConfigPath));
53
49
  let implicitBaseurl;
54
50
  let jsConfig;
@@ -58,11 +54,26 @@ export default async function loadJsConfig(dir, config) {
58
54
  TSCONFIG_WARNED = true;
59
55
  Log.info(`Using tsconfig file: ${tsConfigFileName}`);
60
56
  }
61
- const ts = await Promise.resolve(require(typeScriptPath));
62
- const tsConfig = await getTypeScriptConfiguration(ts, tsConfigPath, true);
63
- jsConfig = {
64
- compilerOptions: tsConfig.options
65
- };
57
+ if (useTypeScriptCli) {
58
+ const tsConfig = await getTypeScriptConfigurationCli({
59
+ baseDir: dir,
60
+ tsConfigPath,
61
+ tscPath: typeScriptPath
62
+ });
63
+ const configOrigins = loadTsConfigOptions(tsConfigPath);
64
+ jsConfig = {
65
+ compilerOptions: {
66
+ ...tsConfig.compilerOptions,
67
+ pathsBasePath: configOrigins.pathsBasePath
68
+ }
69
+ };
70
+ } else {
71
+ const ts = await Promise.resolve(require(typeScriptPath));
72
+ const tsConfig = await getTypeScriptConfiguration(ts, tsConfigPath, true);
73
+ jsConfig = {
74
+ compilerOptions: tsConfig.options
75
+ };
76
+ }
66
77
  implicitBaseurl = path.dirname(tsConfigPath);
67
78
  }
68
79
  const jsConfigPath = path.join(dir, 'jsconfig.json');
@@ -73,13 +84,22 @@ export default async function loadJsConfig(dir, config) {
73
84
  let resolvedBaseUrl;
74
85
  if (jsConfig == null ? void 0 : (_jsConfig_compilerOptions = jsConfig.compilerOptions) == null ? void 0 : _jsConfig_compilerOptions.baseUrl) {
75
86
  resolvedBaseUrl = {
76
- baseUrl: path.resolve(dir, jsConfig.compilerOptions.baseUrl),
87
+ baseUrl: path.resolve(implicitBaseurl ?? dir, jsConfig.compilerOptions.baseUrl),
77
88
  isImplicit: false
78
89
  };
79
90
  } else {
80
- if (implicitBaseurl) {
91
+ var _jsConfig_compilerOptions1;
92
+ // TypeScript 5.0+: `pathsBasePath` is the directory of the tsconfig that
93
+ // defines `paths`. For paths inherited from an extended base tsconfig (e.g.
94
+ // a workspace-root tsconfig.base.json for nx monorepo), this is the base
95
+ // config's directory — not the app tsconfig dir. Using it ensures JsConfigPathsPlugin
96
+ // joins path-mapping values against the correct base so `baseUrl` is not required
97
+ // for path aliases to work in webpack.
98
+ const pathsBasePath = jsConfig == null ? void 0 : (_jsConfig_compilerOptions1 = jsConfig.compilerOptions) == null ? void 0 : _jsConfig_compilerOptions1.pathsBasePath;
99
+ const effectiveBaseUrl = pathsBasePath ?? implicitBaseurl;
100
+ if (effectiveBaseUrl) {
81
101
  resolvedBaseUrl = {
82
- baseUrl: implicitBaseurl,
102
+ baseUrl: effectiveBaseUrl,
83
103
  isImplicit: true
84
104
  };
85
105
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/build/load-jsconfig.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs'\nimport type { NextConfigComplete } from '../server/config-shared'\nimport * as Log from './output/log'\nimport { getTypeScriptConfiguration } from '../lib/typescript/getTypeScriptConfiguration'\nimport { readFileSync } from 'fs'\nimport isError from '../lib/is-error'\nimport { hasNecessaryDependencies } from '../lib/has-necessary-dependencies'\nimport { codeFrameColumns } from '../shared/lib/errors/code-frame'\n\nlet TSCONFIG_WARNED = false\n\nexport function parseJsonFile(filePath: string) {\n const JSON5 =\n require('next/dist/compiled/json5') as typeof import('next/dist/compiled/json5')\n const contents = readFileSync(filePath, 'utf8')\n\n // Special case an empty file\n if (contents.trim() === '') {\n return {}\n }\n\n try {\n return JSON5.parse(contents)\n } catch (err) {\n if (!isError(err)) throw err\n const codeFrame = codeFrameColumns(\n String(contents),\n {\n start: {\n line: (err as Error & { lineNumber?: number }).lineNumber || 1,\n column:\n (err as Error & { columnNumber?: number }).columnNumber ||\n undefined,\n },\n },\n { message: err.message, color: true }\n )\n throw new Error(\n `Failed to parse \"${filePath}\":\\n${codeFrame ?? err.message}`\n )\n }\n}\n\nexport type ResolvedBaseUrl =\n | { baseUrl: string; isImplicit: boolean }\n | undefined\n\nexport type JsConfig = { compilerOptions: Record<string, any> } | undefined\n\nexport default async function loadJsConfig(\n dir: string,\n config: NextConfigComplete\n): Promise<{\n useTypeScript: boolean\n jsConfig: JsConfig\n jsConfigPath?: string\n resolvedBaseUrl: ResolvedBaseUrl\n}> {\n let typeScriptPath: string | undefined\n try {\n const deps = hasNecessaryDependencies(dir, [\n {\n pkg: 'typescript',\n file: 'typescript/lib/typescript.js',\n exportsRestrict: true,\n },\n ])\n typeScriptPath = deps.resolved.get('typescript')\n } catch {}\n const tsConfigFileName = config.typescript.tsconfigPath || 'tsconfig.json'\n const tsConfigPath = path.join(dir, tsConfigFileName)\n const useTypeScript = Boolean(typeScriptPath && fs.existsSync(tsConfigPath))\n\n let implicitBaseurl\n let jsConfig: { compilerOptions: Record<string, any> } | undefined\n // jsconfig is a subset of tsconfig\n if (useTypeScript) {\n if (tsConfigFileName !== 'tsconfig.json' && TSCONFIG_WARNED === false) {\n TSCONFIG_WARNED = true\n Log.info(`Using tsconfig file: ${tsConfigFileName}`)\n }\n\n const ts = (await Promise.resolve(\n require(typeScriptPath!)\n )) as typeof import('typescript')\n const tsConfig = await getTypeScriptConfiguration(ts, tsConfigPath, true)\n jsConfig = { compilerOptions: tsConfig.options }\n implicitBaseurl = path.dirname(tsConfigPath)\n }\n\n const jsConfigPath = path.join(dir, 'jsconfig.json')\n if (!useTypeScript && fs.existsSync(jsConfigPath)) {\n jsConfig = parseJsonFile(jsConfigPath)\n implicitBaseurl = path.dirname(jsConfigPath)\n }\n\n let resolvedBaseUrl: ResolvedBaseUrl\n if (jsConfig?.compilerOptions?.baseUrl) {\n resolvedBaseUrl = {\n baseUrl: path.resolve(dir, jsConfig.compilerOptions.baseUrl),\n isImplicit: false,\n }\n } else {\n if (implicitBaseurl) {\n resolvedBaseUrl = {\n baseUrl: implicitBaseurl,\n isImplicit: true,\n }\n }\n }\n\n return {\n useTypeScript,\n jsConfig,\n resolvedBaseUrl,\n jsConfigPath: useTypeScript\n ? tsConfigPath\n : fs.existsSync(jsConfigPath)\n ? jsConfigPath\n : undefined,\n }\n}\n"],"names":["path","fs","Log","getTypeScriptConfiguration","readFileSync","isError","hasNecessaryDependencies","codeFrameColumns","TSCONFIG_WARNED","parseJsonFile","filePath","JSON5","require","contents","trim","parse","err","codeFrame","String","start","line","lineNumber","column","columnNumber","undefined","message","color","Error","loadJsConfig","dir","config","jsConfig","typeScriptPath","deps","pkg","file","exportsRestrict","resolved","get","tsConfigFileName","typescript","tsconfigPath","tsConfigPath","join","useTypeScript","Boolean","existsSync","implicitBaseurl","info","ts","Promise","resolve","tsConfig","compilerOptions","options","dirname","jsConfigPath","resolvedBaseUrl","baseUrl","isImplicit"],"mappings":"AAAA,OAAOA,UAAU,OAAM;AACvB,OAAOC,QAAQ,KAAI;AAEnB,YAAYC,SAAS,eAAc;AACnC,SAASC,0BAA0B,QAAQ,+CAA8C;AACzF,SAASC,YAAY,QAAQ,KAAI;AACjC,OAAOC,aAAa,kBAAiB;AACrC,SAASC,wBAAwB,QAAQ,oCAAmC;AAC5E,SAASC,gBAAgB,QAAQ,kCAAiC;AAElE,IAAIC,kBAAkB;AAEtB,OAAO,SAASC,cAAcC,QAAgB;IAC5C,MAAMC,QACJC,QAAQ;IACV,MAAMC,WAAWT,aAAaM,UAAU;IAExC,6BAA6B;IAC7B,IAAIG,SAASC,IAAI,OAAO,IAAI;QAC1B,OAAO,CAAC;IACV;IAEA,IAAI;QACF,OAAOH,MAAMI,KAAK,CAACF;IACrB,EAAE,OAAOG,KAAK;QACZ,IAAI,CAACX,QAAQW,MAAM,MAAMA;QACzB,MAAMC,YAAYV,iBAChBW,OAAOL,WACP;YACEM,OAAO;gBACLC,MAAM,AAACJ,IAAwCK,UAAU,IAAI;gBAC7DC,QACE,AAACN,IAA0CO,YAAY,IACvDC;YACJ;QACF,GACA;YAAEC,SAAST,IAAIS,OAAO;YAAEC,OAAO;QAAK;QAEtC,MAAM,qBAEL,CAFK,IAAIC,MACR,CAAC,iBAAiB,EAAEjB,SAAS,IAAI,EAAEO,aAAaD,IAAIS,OAAO,EAAE,GADzD,qBAAA;mBAAA;wBAAA;0BAAA;QAEN;IACF;AACF;AAQA,eAAe,eAAeG,aAC5BC,GAAW,EACXC,MAA0B;QA8CtBC;IAvCJ,IAAIC;IACJ,IAAI;QACF,MAAMC,OAAO3B,yBAAyBuB,KAAK;YACzC;gBACEK,KAAK;gBACLC,MAAM;gBACNC,iBAAiB;YACnB;SACD;QACDJ,iBAAiBC,KAAKI,QAAQ,CAACC,GAAG,CAAC;IACrC,EAAE,OAAM,CAAC;IACT,MAAMC,mBAAmBT,OAAOU,UAAU,CAACC,YAAY,IAAI;IAC3D,MAAMC,eAAe1C,KAAK2C,IAAI,CAACd,KAAKU;IACpC,MAAMK,gBAAgBC,QAAQb,kBAAkB/B,GAAG6C,UAAU,CAACJ;IAE9D,IAAIK;IACJ,IAAIhB;IACJ,mCAAmC;IACnC,IAAIa,eAAe;QACjB,IAAIL,qBAAqB,mBAAmB/B,oBAAoB,OAAO;YACrEA,kBAAkB;YAClBN,IAAI8C,IAAI,CAAC,CAAC,qBAAqB,EAAET,kBAAkB;QACrD;QAEA,MAAMU,KAAM,MAAMC,QAAQC,OAAO,CAC/BvC,QAAQoB;QAEV,MAAMoB,WAAW,MAAMjD,2BAA2B8C,IAAIP,cAAc;QACpEX,WAAW;YAAEsB,iBAAiBD,SAASE,OAAO;QAAC;QAC/CP,kBAAkB/C,KAAKuD,OAAO,CAACb;IACjC;IAEA,MAAMc,eAAexD,KAAK2C,IAAI,CAACd,KAAK;IACpC,IAAI,CAACe,iBAAiB3C,GAAG6C,UAAU,CAACU,eAAe;QACjDzB,WAAWtB,cAAc+C;QACzBT,kBAAkB/C,KAAKuD,OAAO,CAACC;IACjC;IAEA,IAAIC;IACJ,IAAI1B,6BAAAA,4BAAAA,SAAUsB,eAAe,qBAAzBtB,0BAA2B2B,OAAO,EAAE;QACtCD,kBAAkB;YAChBC,SAAS1D,KAAKmD,OAAO,CAACtB,KAAKE,SAASsB,eAAe,CAACK,OAAO;YAC3DC,YAAY;QACd;IACF,OAAO;QACL,IAAIZ,iBAAiB;YACnBU,kBAAkB;gBAChBC,SAASX;gBACTY,YAAY;YACd;QACF;IACF;IAEA,OAAO;QACLf;QACAb;QACA0B;QACAD,cAAcZ,gBACVF,eACAzC,GAAG6C,UAAU,CAACU,gBACZA,eACAhC;IACR;AACF","ignoreList":[0]}
1
+ {"version":3,"sources":["../../../src/build/load-jsconfig.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs'\nimport type { NextConfigComplete } from '../server/config-shared'\nimport * as Log from './output/log'\nimport { getTypeScriptConfiguration } from '../lib/typescript/getTypeScriptConfiguration'\nimport { readFileSync } from 'fs'\nimport isError from '../lib/is-error'\nimport { codeFrameColumns } from '../shared/lib/errors/code-frame'\nimport {\n getTypeScriptApiMissingError,\n getTypeScriptConfigurationCli,\n getTypeScriptPackageInfo,\n hasNativeTypeScriptPreview,\n} from '../lib/typescript/runTypeScriptCli'\nimport { loadTsConfigOptions } from '../lib/typescript/loadTsConfig'\n\nlet TSCONFIG_WARNED = false\n\nexport function parseJsonFile(filePath: string) {\n const JSON5 =\n require('next/dist/compiled/json5') as typeof import('next/dist/compiled/json5')\n const contents = readFileSync(filePath, 'utf8')\n\n // Special case an empty file\n if (contents.trim() === '') {\n return {}\n }\n\n try {\n return JSON5.parse(contents)\n } catch (err) {\n if (!isError(err)) throw err\n const codeFrame = codeFrameColumns(\n String(contents),\n {\n start: {\n line: (err as Error & { lineNumber?: number }).lineNumber || 1,\n column:\n (err as Error & { columnNumber?: number }).columnNumber ||\n undefined,\n },\n },\n { message: err.message, color: true }\n )\n throw new Error(\n `Failed to parse \"${filePath}\":\\n${codeFrame ?? err.message}`\n )\n }\n}\n\nexport type ResolvedBaseUrl =\n | { baseUrl: string; isImplicit: boolean }\n | undefined\n\nexport type JsConfig = { compilerOptions: Record<string, any> } | undefined\n\nexport default async function loadJsConfig(\n dir: string,\n config: NextConfigComplete\n): Promise<{\n useTypeScript: boolean\n jsConfig: JsConfig\n jsConfigPath?: string\n resolvedBaseUrl: ResolvedBaseUrl\n}> {\n const useTypeScriptCli = Boolean(config.experimental.useTypeScriptCli)\n const typeScriptPackage = getTypeScriptPackageInfo(dir)\n const typeScriptPath = useTypeScriptCli\n ? typeScriptPackage?.tscPath\n : typeScriptPackage?.apiPath\n const tsConfigFileName = config.typescript.tsconfigPath || 'tsconfig.json'\n const tsConfigPath = path.join(dir, tsConfigFileName)\n\n if (\n !useTypeScriptCli &&\n typeScriptPackage &&\n !typeScriptPackage.apiPath &&\n !hasNativeTypeScriptPreview(dir) &&\n fs.existsSync(tsConfigPath)\n ) {\n throw getTypeScriptApiMissingError(typeScriptPackage.version)\n }\n\n const useTypeScript = Boolean(typeScriptPath && fs.existsSync(tsConfigPath))\n\n let implicitBaseurl\n let jsConfig: { compilerOptions: Record<string, any> } | undefined\n // jsconfig is a subset of tsconfig\n if (useTypeScript) {\n if (tsConfigFileName !== 'tsconfig.json' && TSCONFIG_WARNED === false) {\n TSCONFIG_WARNED = true\n Log.info(`Using tsconfig file: ${tsConfigFileName}`)\n }\n\n if (useTypeScriptCli) {\n const tsConfig = await getTypeScriptConfigurationCli({\n baseDir: dir,\n tsConfigPath,\n tscPath: typeScriptPath!,\n })\n const configOrigins = loadTsConfigOptions(tsConfigPath)\n jsConfig = {\n compilerOptions: {\n ...tsConfig.compilerOptions,\n pathsBasePath: configOrigins.pathsBasePath,\n },\n }\n } else {\n const ts = (await Promise.resolve(\n require(typeScriptPath!)\n )) as typeof import('typescript')\n const tsConfig = await getTypeScriptConfiguration(ts, tsConfigPath, true)\n jsConfig = { compilerOptions: tsConfig.options }\n }\n implicitBaseurl = path.dirname(tsConfigPath)\n }\n\n const jsConfigPath = path.join(dir, 'jsconfig.json')\n if (!useTypeScript && fs.existsSync(jsConfigPath)) {\n jsConfig = parseJsonFile(jsConfigPath)\n implicitBaseurl = path.dirname(jsConfigPath)\n }\n\n let resolvedBaseUrl: ResolvedBaseUrl\n if (jsConfig?.compilerOptions?.baseUrl) {\n resolvedBaseUrl = {\n baseUrl: path.resolve(\n implicitBaseurl ?? dir,\n jsConfig.compilerOptions.baseUrl\n ),\n isImplicit: false,\n }\n } else {\n // TypeScript 5.0+: `pathsBasePath` is the directory of the tsconfig that\n // defines `paths`. For paths inherited from an extended base tsconfig (e.g.\n // a workspace-root tsconfig.base.json for nx monorepo), this is the base\n // config's directory — not the app tsconfig dir. Using it ensures JsConfigPathsPlugin\n // joins path-mapping values against the correct base so `baseUrl` is not required\n // for path aliases to work in webpack.\n const pathsBasePath: string | undefined =\n jsConfig?.compilerOptions?.pathsBasePath\n const effectiveBaseUrl = pathsBasePath ?? implicitBaseurl\n if (effectiveBaseUrl) {\n resolvedBaseUrl = {\n baseUrl: effectiveBaseUrl,\n isImplicit: true,\n }\n }\n }\n\n return {\n useTypeScript,\n jsConfig,\n resolvedBaseUrl,\n jsConfigPath: useTypeScript\n ? tsConfigPath\n : fs.existsSync(jsConfigPath)\n ? jsConfigPath\n : undefined,\n }\n}\n"],"names":["path","fs","Log","getTypeScriptConfiguration","readFileSync","isError","codeFrameColumns","getTypeScriptApiMissingError","getTypeScriptConfigurationCli","getTypeScriptPackageInfo","hasNativeTypeScriptPreview","loadTsConfigOptions","TSCONFIG_WARNED","parseJsonFile","filePath","JSON5","require","contents","trim","parse","err","codeFrame","String","start","line","lineNumber","column","columnNumber","undefined","message","color","Error","loadJsConfig","dir","config","jsConfig","useTypeScriptCli","Boolean","experimental","typeScriptPackage","typeScriptPath","tscPath","apiPath","tsConfigFileName","typescript","tsconfigPath","tsConfigPath","join","existsSync","version","useTypeScript","implicitBaseurl","info","tsConfig","baseDir","configOrigins","compilerOptions","pathsBasePath","ts","Promise","resolve","options","dirname","jsConfigPath","resolvedBaseUrl","baseUrl","isImplicit","effectiveBaseUrl"],"mappings":"AAAA,OAAOA,UAAU,OAAM;AACvB,OAAOC,QAAQ,KAAI;AAEnB,YAAYC,SAAS,eAAc;AACnC,SAASC,0BAA0B,QAAQ,+CAA8C;AACzF,SAASC,YAAY,QAAQ,KAAI;AACjC,OAAOC,aAAa,kBAAiB;AACrC,SAASC,gBAAgB,QAAQ,kCAAiC;AAClE,SACEC,4BAA4B,EAC5BC,6BAA6B,EAC7BC,wBAAwB,EACxBC,0BAA0B,QACrB,qCAAoC;AAC3C,SAASC,mBAAmB,QAAQ,iCAAgC;AAEpE,IAAIC,kBAAkB;AAEtB,OAAO,SAASC,cAAcC,QAAgB;IAC5C,MAAMC,QACJC,QAAQ;IACV,MAAMC,WAAWb,aAAaU,UAAU;IAExC,6BAA6B;IAC7B,IAAIG,SAASC,IAAI,OAAO,IAAI;QAC1B,OAAO,CAAC;IACV;IAEA,IAAI;QACF,OAAOH,MAAMI,KAAK,CAACF;IACrB,EAAE,OAAOG,KAAK;QACZ,IAAI,CAACf,QAAQe,MAAM,MAAMA;QACzB,MAAMC,YAAYf,iBAChBgB,OAAOL,WACP;YACEM,OAAO;gBACLC,MAAM,AAACJ,IAAwCK,UAAU,IAAI;gBAC7DC,QACE,AAACN,IAA0CO,YAAY,IACvDC;YACJ;QACF,GACA;YAAEC,SAAST,IAAIS,OAAO;YAAEC,OAAO;QAAK;QAEtC,MAAM,qBAEL,CAFK,IAAIC,MACR,CAAC,iBAAiB,EAAEjB,SAAS,IAAI,EAAEO,aAAaD,IAAIS,OAAO,EAAE,GADzD,qBAAA;mBAAA;wBAAA;0BAAA;QAEN;IACF;AACF;AAQA,eAAe,eAAeG,aAC5BC,GAAW,EACXC,MAA0B;QAkEtBC;IA3DJ,MAAMC,mBAAmBC,QAAQH,OAAOI,YAAY,CAACF,gBAAgB;IACrE,MAAMG,oBAAoB9B,yBAAyBwB;IACnD,MAAMO,iBAAiBJ,mBACnBG,qCAAAA,kBAAmBE,OAAO,GAC1BF,qCAAAA,kBAAmBG,OAAO;IAC9B,MAAMC,mBAAmBT,OAAOU,UAAU,CAACC,YAAY,IAAI;IAC3D,MAAMC,eAAe9C,KAAK+C,IAAI,CAACd,KAAKU;IAEpC,IACE,CAACP,oBACDG,qBACA,CAACA,kBAAkBG,OAAO,IAC1B,CAAChC,2BAA2BuB,QAC5BhC,GAAG+C,UAAU,CAACF,eACd;QACA,MAAMvC,6BAA6BgC,kBAAkBU,OAAO;IAC9D;IAEA,MAAMC,gBAAgBb,QAAQG,kBAAkBvC,GAAG+C,UAAU,CAACF;IAE9D,IAAIK;IACJ,IAAIhB;IACJ,mCAAmC;IACnC,IAAIe,eAAe;QACjB,IAAIP,qBAAqB,mBAAmB/B,oBAAoB,OAAO;YACrEA,kBAAkB;YAClBV,IAAIkD,IAAI,CAAC,CAAC,qBAAqB,EAAET,kBAAkB;QACrD;QAEA,IAAIP,kBAAkB;YACpB,MAAMiB,WAAW,MAAM7C,8BAA8B;gBACnD8C,SAASrB;gBACTa;gBACAL,SAASD;YACX;YACA,MAAMe,gBAAgB5C,oBAAoBmC;YAC1CX,WAAW;gBACTqB,iBAAiB;oBACf,GAAGH,SAASG,eAAe;oBAC3BC,eAAeF,cAAcE,aAAa;gBAC5C;YACF;QACF,OAAO;YACL,MAAMC,KAAM,MAAMC,QAAQC,OAAO,CAC/B5C,QAAQwB;YAEV,MAAMa,WAAW,MAAMlD,2BAA2BuD,IAAIZ,cAAc;YACpEX,WAAW;gBAAEqB,iBAAiBH,SAASQ,OAAO;YAAC;QACjD;QACAV,kBAAkBnD,KAAK8D,OAAO,CAAChB;IACjC;IAEA,MAAMiB,eAAe/D,KAAK+C,IAAI,CAACd,KAAK;IACpC,IAAI,CAACiB,iBAAiBjD,GAAG+C,UAAU,CAACe,eAAe;QACjD5B,WAAWtB,cAAckD;QACzBZ,kBAAkBnD,KAAK8D,OAAO,CAACC;IACjC;IAEA,IAAIC;IACJ,IAAI7B,6BAAAA,4BAAAA,SAAUqB,eAAe,qBAAzBrB,0BAA2B8B,OAAO,EAAE;QACtCD,kBAAkB;YAChBC,SAASjE,KAAK4D,OAAO,CACnBT,mBAAmBlB,KACnBE,SAASqB,eAAe,CAACS,OAAO;YAElCC,YAAY;QACd;IACF,OAAO;YAQH/B;QAPF,yEAAyE;QACzE,4EAA4E;QAC5E,yEAAyE;QACzE,sFAAsF;QACtF,kFAAkF;QAClF,uCAAuC;QACvC,MAAMsB,gBACJtB,6BAAAA,6BAAAA,SAAUqB,eAAe,qBAAzBrB,2BAA2BsB,aAAa;QAC1C,MAAMU,mBAAmBV,iBAAiBN;QAC1C,IAAIgB,kBAAkB;YACpBH,kBAAkB;gBAChBC,SAASE;gBACTD,YAAY;YACd;QACF;IACF;IAEA,OAAO;QACLhB;QACAf;QACA6B;QACAD,cAAcb,gBACVJ,eACA7C,GAAG+C,UAAU,CAACe,gBACZA,eACAnC;IACR;AACF","ignoreList":[0]}
@@ -1,10 +1,10 @@
1
1
  import path from 'node:path';
2
2
  import { readFileSync, existsSync } from 'node:fs';
3
3
  import { pathToFileURL } from 'node:url';
4
- import * as CommentJson from 'next/dist/compiled/comment-json';
5
4
  import { deregisterHook, registerHook, requireFromString } from './require-hook';
6
5
  import { warn, warnOnce } from '../output/log';
7
6
  import { getNodeOptionsArgs } from '../../server/lib/utils';
7
+ import { loadTsConfigOptions } from '../../lib/typescript/loadTsConfig';
8
8
  function resolveSWCOptions(cwd, compilerOptions) {
9
9
  var _process_versions, _process;
10
10
  return {
@@ -18,7 +18,7 @@ function resolveSWCOptions(cwd, compilerOptions) {
18
18
  ...compilerOptions.baseUrl ? {
19
19
  baseUrl: path.resolve(cwd, compilerOptions.baseUrl)
20
20
  } : compilerOptions.paths ? {
21
- baseUrl: cwd
21
+ baseUrl: compilerOptions.pathsBasePath ?? cwd
22
22
  } : {}
23
23
  },
24
24
  module: {
@@ -33,76 +33,6 @@ function resolveSWCOptions(cwd, compilerOptions) {
33
33
  }
34
34
  };
35
35
  }
36
- function resolveExtends(extendsPath, currentConfigDir) {
37
- // Relative paths are resolved relative to the current config's directory
38
- if (extendsPath.startsWith('./') || extendsPath.startsWith('../') || path.isAbsolute(extendsPath)) {
39
- const resolved = path.resolve(currentConfigDir, extendsPath);
40
- // TypeScript allows omitting .json extension
41
- if (existsSync(resolved)) {
42
- return resolved;
43
- }
44
- if (!resolved.endsWith('.json') && existsSync(resolved + '.json')) {
45
- return resolved + '.json';
46
- }
47
- return resolved;
48
- }
49
- // Package paths - use require.resolve to find the package
50
- try {
51
- // Try resolving as a direct path within the package
52
- return require.resolve(extendsPath, {
53
- paths: [
54
- currentConfigDir
55
- ]
56
- });
57
- } catch {
58
- // If that fails, try appending tsconfig.json for package names like "@tsconfig/node18"
59
- try {
60
- return require.resolve(extendsPath + '/tsconfig.json', {
61
- paths: [
62
- currentConfigDir
63
- ]
64
- });
65
- } catch {
66
- // Return the original path and let it fail later with a clear error
67
- return path.resolve(currentConfigDir, extendsPath);
68
- }
69
- }
70
- }
71
- function loadTsConfigFile(configPath, visited) {
72
- const resolvedPath = path.resolve(configPath);
73
- if (visited.has(resolvedPath)) {
74
- return {};
75
- }
76
- visited.add(resolvedPath);
77
- if (!existsSync(resolvedPath)) {
78
- return {};
79
- }
80
- const configContent = readFileSync(resolvedPath, 'utf8');
81
- const config = CommentJson.parse(configContent);
82
- const configDir = path.dirname(resolvedPath);
83
- let mergedOptions = {};
84
- // Note that config options from `extends` should get overwritten, not merged
85
- if (config.extends) {
86
- const extendsList = Array.isArray(config.extends) ? config.extends : [
87
- config.extends
88
- ];
89
- for (const extendsPath of extendsList){
90
- const parentConfigPath = resolveExtends(extendsPath, configDir);
91
- const parentOptions = loadTsConfigFile(parentConfigPath, visited);
92
- mergedOptions = {
93
- ...mergedOptions,
94
- ...parentOptions
95
- };
96
- }
97
- }
98
- const currentOptions = config.compilerOptions ?? {};
99
- mergedOptions = {
100
- ...mergedOptions,
101
- paths: currentOptions.paths ?? mergedOptions.paths,
102
- baseUrl: currentOptions.baseUrl ?? mergedOptions.baseUrl
103
- };
104
- return mergedOptions;
105
- }
106
36
  async function loadTsConfig(dir) {
107
37
  // NOTE: This doesn't fully cover the edge case for setting
108
38
  // "typescript.tsconfigPath" in next config which is currently
@@ -113,7 +43,7 @@ async function loadTsConfig(dir) {
113
43
  if (!existsSync(resolvedTsConfigPath)) {
114
44
  return {};
115
45
  }
116
- return loadTsConfigFile(resolvedTsConfigPath, new Set());
46
+ return loadTsConfigOptions(resolvedTsConfigPath);
117
47
  }
118
48
  export async function transpileConfig({ nextConfigPath, dir }) {
119
49
  try {