Skip to content

Commit 8a8a00d

Browse files
authored
Revert "Move next-env.d.ts to dist dir" (#87311)
Reverts #86752 This has consequences when `.next` is in `exclude`. Reverting for now.
1 parent 3284587 commit 8a8a00d

File tree

25 files changed

+387
-251
lines changed

25 files changed

+387
-251
lines changed

packages/next/src/build/index.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ import {
224224
createRouteTypesManifest,
225225
writeRouteTypesManifest,
226226
writeValidatorFile,
227-
writeDynamicTypesFile,
228227
} from '../server/lib/router-utils/route-types-utils'
229228
import { Lockfile } from './lockfile'
230229
import {
@@ -1485,12 +1484,6 @@ export default async function build(
14851484
config
14861485
)
14871486
await writeValidatorFile(routeTypesManifest, validatorFilePath)
1488-
await writeDynamicTypesFile({
1489-
distDir,
1490-
imageImportsEnabled: !config.images.disableStaticImages,
1491-
hasPagesDir: !!pagesDir,
1492-
hasAppDir: !!appDir,
1493-
})
14941487
})
14951488

14961489
// Turbopack already handles conflicting app and page routes.

packages/next/src/build/type-check.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function verifyTypeScriptSetup(
2222
distDir: string,
2323
typeCheckPreflight: boolean,
2424
tsconfigPath: string | undefined,
25+
disableStaticImages: boolean,
2526
cacheDir: string | undefined,
2627
enableWorkerThreads: boolean | undefined,
2728
hasAppDir: boolean,
@@ -51,6 +52,7 @@ function verifyTypeScriptSetup(
5152
distDir,
5253
typeCheckPreflight,
5354
tsconfigPath,
55+
disableStaticImages,
5456
cacheDir,
5557
hasAppDir,
5658
hasPagesDir,
@@ -117,6 +119,7 @@ export async function startTypeChecking({
117119
config.distDir,
118120
!ignoreTypeScriptErrors,
119121
config.typescript.tsconfigPath,
122+
config.images.disableStaticImages,
120123
cacheDir,
121124
config.experimental.workerThreads,
122125
!!appDir,

packages/next/src/cli/next-test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ async function runPlaywright(
142142
distDir: nextConfig.distDir,
143143
typeCheckPreflight: false,
144144
tsconfigPath: nextConfig.typescript.tsconfigPath,
145+
disableStaticImages: nextConfig.images.disableStaticImages,
145146
hasAppDir: !!appDir,
146147
hasPagesDir: !!pagesDir,
147148
isolatedDevBuild: nextConfig.experimental.isolatedDevBuild,

packages/next/src/cli/next-typegen.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import {
2929
createRouteTypesManifest,
3030
writeRouteTypesManifest,
3131
writeValidatorFile,
32-
writeDynamicTypesFile,
3332
} from '../server/lib/router-utils/route-types-utils'
3433
import { writeCacheLifeTypes } from '../server/lib/router-utils/cache-life-type-utils'
3534
import { createValidFileMatcher } from '../server/lib/find-page-file'
@@ -60,6 +59,7 @@ const nextTypegen = async (
6059
distDir: nextConfig.distDir,
6160
typeCheckPreflight: false,
6261
tsconfigPath: nextConfig.typescript.tsconfigPath,
62+
disableStaticImages: nextConfig.images.disableStaticImages,
6363
hasAppDir: !!appDir,
6464
hasPagesDir: !!pagesDir,
6565
isolatedDevBuild: nextConfig.experimental.isolatedDevBuild,
@@ -171,13 +171,6 @@ const nextTypegen = async (
171171

172172
await writeValidatorFile(routeTypesManifest, validatorFilePath)
173173

174-
await writeDynamicTypesFile({
175-
distDir,
176-
imageImportsEnabled: !nextConfig.images.disableStaticImages,
177-
hasPagesDir: !!pagesDir,
178-
hasAppDir: !!appDir,
179-
})
180-
181174
// Generate cache-life types if cacheLife config exists
182175
const cacheLifeFilePath = join(distDir, 'types', 'cache-life.d.ts')
183176
writeCacheLifeTypes(nextConfig.cacheLife, cacheLifeFilePath)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import os from 'os'
2+
import path from 'path'
3+
import { promises as fs } from 'fs'
4+
5+
export async function writeAppTypeDeclarations({
6+
baseDir,
7+
distDir,
8+
imageImportsEnabled,
9+
hasPagesDir,
10+
hasAppDir,
11+
}: {
12+
baseDir: string
13+
distDir: string
14+
imageImportsEnabled: boolean
15+
hasPagesDir: boolean
16+
hasAppDir: boolean
17+
}): Promise<void> {
18+
// Reference `next` types
19+
const appTypeDeclarations = path.join(baseDir, 'next-env.d.ts')
20+
21+
// Defaults EOL to system default
22+
let eol = os.EOL
23+
let currentContent: string | undefined
24+
25+
try {
26+
currentContent = await fs.readFile(appTypeDeclarations, 'utf8')
27+
// If file already exists then preserve its line ending
28+
const lf = currentContent.indexOf('\n', /* skip first so we can lf - 1 */ 1)
29+
30+
if (lf !== -1) {
31+
if (currentContent[lf - 1] === '\r') {
32+
eol = '\r\n'
33+
} else {
34+
eol = '\n'
35+
}
36+
}
37+
} catch {}
38+
39+
/**
40+
* "Triple-slash directives" used to create typings files for Next.js projects
41+
* using Typescript .
42+
*
43+
* @see https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html
44+
*/
45+
const directives: string[] = [
46+
// Include the core Next.js typings.
47+
'/// <reference types="next" />',
48+
]
49+
50+
if (imageImportsEnabled) {
51+
directives.push('/// <reference types="next/image-types/global" />')
52+
}
53+
54+
if (hasAppDir && hasPagesDir) {
55+
directives.push(
56+
'/// <reference types="next/navigation-types/compat/navigation" />'
57+
)
58+
}
59+
60+
const routeTypesPath = path.posix.join(
61+
distDir.replaceAll(path.win32.sep, path.posix.sep),
62+
'types/routes.d.ts'
63+
)
64+
65+
// Use ESM import instead of triple-slash reference for better ESLint compatibility
66+
directives.push(`import "./${routeTypesPath}";`)
67+
68+
// Push the notice in.
69+
directives.push(
70+
'',
71+
'// NOTE: This file should not be edited',
72+
`// see https://nextjs.org/docs/${hasAppDir ? 'app' : 'pages'}/api-reference/config/typescript for more information.`
73+
)
74+
75+
const content = directives.join(eol) + eol
76+
77+
// Avoids an un-necessary write on read-only fs
78+
if (currentContent === content) {
79+
return
80+
}
81+
await fs.writeFile(appTypeDeclarations, content)
82+
}

packages/next/src/lib/typescript/writeConfigurationDefaults.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ describe('writeConfigurationDefaults()', () => {
8484
"node_modules",
8585
],
8686
"include": [
87+
"next-env.d.ts",
8788
".next/types/**/*.ts",
8889
".next/dev/types/**/*.ts",
8990
"**/*.mts",
@@ -106,7 +107,7 @@ describe('writeConfigurationDefaults()', () => {
106107
- strict was set to false
107108
- noEmit was set to true
108109
- incremental was set to true
109-
- include was set to ['.next/types/**/*.ts', '.next/dev/types/**/*.ts', '**/*.mts', '**/*.ts', '**/*.tsx']
110+
- include was set to ['next-env.d.ts', '.next/types/**/*.ts', '.next/dev/types/**/*.ts', '**/*.mts', '**/*.ts', '**/*.tsx']
110111
- plugins was updated to add { name: 'next' }
111112
- exclude was set to ['node_modules']
112113

packages/next/src/lib/typescript/writeConfigurationDefaults.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,16 +282,19 @@ export async function writeConfigurationDefaults(
282282
)
283283

284284
if (!('include' in userTsConfig)) {
285-
// Always include .next/types for dynamic types (image imports, route types, etc.)
286-
userTsConfig.include = [...nextAppTypes, '**/*.mts', '**/*.ts', '**/*.tsx']
285+
userTsConfig.include = hasAppDir
286+
? ['next-env.d.ts', ...nextAppTypes, '**/*.mts', '**/*.ts', '**/*.tsx']
287+
: ['next-env.d.ts', '**/*.mts', '**/*.ts', '**/*.tsx']
287288
suggestedActions.push(
288289
cyan('include') +
289290
' was set to ' +
290291
bold(
291-
`[${nextAppTypes.map((type) => `'${type}'`).join(', ')}, '**/*.mts', '**/*.ts', '**/*.tsx']`
292+
hasAppDir
293+
? `['next-env.d.ts', ${nextAppTypes.map((type) => `'${type}'`).join(', ')}, '**/*.mts', '**/*.ts', '**/*.tsx']`
294+
: `['next-env.d.ts', '**/*.mts', '**/*.ts', '**/*.tsx']`
292295
)
293296
)
294-
} else {
297+
} else if (hasAppDir) {
295298
const missingFromResolved = []
296299
for (const type of nextAppTypes) {
297300
if (!userTsConfig.include.includes(type)) {

packages/next/src/lib/verify-typescript-setup.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as log from '../build/output/log'
99

1010
import { getTypeScriptIntent } from './typescript/getTypeScriptIntent'
1111
import type { TypeCheckResult } from './typescript/runTypeCheck'
12+
import { writeAppTypeDeclarations } from './typescript/writeAppTypeDeclarations'
1213
import { writeConfigurationDefaults } from './typescript/writeConfigurationDefaults'
1314
import { installDependencies } from './install-dependencies'
1415
import { isCI } from '../server/ci-info'
@@ -38,6 +39,7 @@ export async function verifyTypeScriptSetup({
3839
cacheDir,
3940
tsconfigPath,
4041
typeCheckPreflight,
42+
disableStaticImages,
4143
hasAppDir,
4244
hasPagesDir,
4345
isolatedDevBuild,
@@ -50,6 +52,7 @@ export async function verifyTypeScriptSetup({
5052
cacheDir?: string
5153
tsconfigPath: string | undefined
5254
typeCheckPreflight: boolean
55+
disableStaticImages: boolean
5356
hasAppDir: boolean
5457
hasPagesDir: boolean
5558
isolatedDevBuild: boolean | undefined
@@ -135,6 +138,16 @@ export async function verifyTypeScriptSetup({
135138
hasPagesDir,
136139
isolatedDevBuild
137140
)
141+
// Write out the necessary `next-env.d.ts` file to correctly register
142+
// Next.js' types:
143+
await writeAppTypeDeclarations({
144+
baseDir: dir,
145+
distDir,
146+
imageImportsEnabled: !disableStaticImages,
147+
hasPagesDir,
148+
hasAppDir,
149+
})
150+
138151
let result
139152
if (typeCheckPreflight) {
140153
const { runTypeCheck } =

packages/next/src/server/lib/router-utils/route-types-utils.ts

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
generateRouteTypesFile,
1111
generateLinkTypesFile,
1212
generateValidatorFile,
13-
generateDynamicTypesFile,
1413
} from './typegen'
1514
import { tryToParsePath } from '../../../lib/try-to-parse-path'
1615
import {
@@ -383,35 +382,3 @@ export async function writeValidatorFile(
383382

384383
await fs.promises.writeFile(filePath, generateValidatorFile(manifest))
385384
}
386-
387-
/**
388-
* Writes the dynamic types file (.next/types/next-env.d.ts) that contains
389-
* config-dependent type references (image imports, navigation compat, etc.)
390-
*/
391-
export async function writeDynamicTypesFile({
392-
distDir,
393-
imageImportsEnabled,
394-
hasPagesDir,
395-
hasAppDir,
396-
}: {
397-
distDir: string
398-
imageImportsEnabled: boolean
399-
hasPagesDir: boolean
400-
hasAppDir: boolean
401-
}) {
402-
const typesDir = path.join(distDir, 'types')
403-
const filePath = path.join(typesDir, 'next-env.d.ts')
404-
405-
// Directory should already be created by writeRouteTypesManifest, but ensure it exists
406-
if (!fs.existsSync(typesDir)) {
407-
await fs.promises.mkdir(typesDir, { recursive: true })
408-
}
409-
410-
const content = generateDynamicTypesFile({
411-
imageImportsEnabled,
412-
hasPagesDir,
413-
hasAppDir,
414-
})
415-
416-
await fs.promises.writeFile(filePath, content)
417-
}

packages/next/src/server/lib/router-utils/setup-dev-bundler.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ import {
8585
createRouteTypesManifest,
8686
writeRouteTypesManifest,
8787
writeValidatorFile,
88-
writeDynamicTypesFile,
8988
} from './route-types-utils'
9089
import { writeCacheLifeTypes } from './cache-life-type-utils'
9190
import { isParallelRouteSegment } from '../../../shared/lib/segment'
@@ -146,6 +145,7 @@ async function verifyTypeScript(opts: SetupOpts) {
146145
distDir: opts.nextConfig.distDir,
147146
typeCheckPreflight: false,
148147
tsconfigPath: opts.nextConfig.typescript.tsconfigPath,
148+
disableStaticImages: opts.nextConfig.images.disableStaticImages,
149149
hasAppDir: !!opts.appDir,
150150
hasPagesDir: !!opts.pagesDir,
151151
isolatedDevBuild: opts.nextConfig.experimental.isolatedDevBuild,
@@ -265,12 +265,6 @@ async function startWatcher(
265265
path.join(distTypesDir, 'routes.d.ts'),
266266
opts.nextConfig
267267
)
268-
await writeDynamicTypesFile({
269-
distDir,
270-
imageImportsEnabled: !opts.nextConfig.images.disableStaticImages,
271-
hasPagesDir: !!pagesDir,
272-
hasAppDir: !!appDir,
273-
})
274268

275269
const routesManifestPath = path.join(distDir, ROUTES_MANIFEST)
276270
const routesManifest: DevRoutesManifest = {

0 commit comments

Comments
 (0)