mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
dx: avoid next-env.d.ts change in dev (#88103)
This commit is contained in:
@@ -20,6 +20,7 @@ import { hrtimeDurationToString } from './duration-to-string'
|
||||
function verifyTypeScriptSetup(
|
||||
dir: string,
|
||||
distDir: string,
|
||||
distDirRoot: string | undefined,
|
||||
typeCheckPreflight: boolean,
|
||||
tsconfigPath: string | undefined,
|
||||
disableStaticImages: boolean,
|
||||
@@ -50,6 +51,7 @@ function verifyTypeScriptSetup(
|
||||
.verifyTypeScriptSetup({
|
||||
dir,
|
||||
distDir,
|
||||
distDirRoot,
|
||||
typeCheckPreflight,
|
||||
tsconfigPath,
|
||||
disableStaticImages,
|
||||
@@ -117,6 +119,7 @@ export async function startTypeChecking({
|
||||
verifyTypeScriptSetup(
|
||||
dir,
|
||||
config.distDir,
|
||||
config.distDirRoot,
|
||||
!ignoreTypeScriptErrors,
|
||||
config.typescript.tsconfigPath,
|
||||
config.images.disableStaticImages,
|
||||
|
||||
@@ -140,6 +140,7 @@ async function runPlaywright(
|
||||
const { version: typeScriptVersion } = await verifyTypeScriptSetup({
|
||||
dir: baseDir,
|
||||
distDir: nextConfig.distDir,
|
||||
distDirRoot: nextConfig.distDirRoot,
|
||||
typeCheckPreflight: false,
|
||||
tsconfigPath: nextConfig.typescript.tsconfigPath,
|
||||
disableStaticImages: nextConfig.images.disableStaticImages,
|
||||
|
||||
@@ -57,6 +57,7 @@ const nextTypegen = async (
|
||||
await verifyTypeScriptSetup({
|
||||
dir: baseDir,
|
||||
distDir: nextConfig.distDir,
|
||||
distDirRoot: nextConfig.distDirRoot,
|
||||
typeCheckPreflight: false,
|
||||
tsconfigPath: nextConfig.typescript.tsconfigPath,
|
||||
disableStaticImages: nextConfig.images.disableStaticImages,
|
||||
|
||||
@@ -5,12 +5,15 @@ import { promises as fs } from 'fs'
|
||||
export async function writeAppTypeDeclarations({
|
||||
baseDir,
|
||||
distDir,
|
||||
distDirRoot,
|
||||
imageImportsEnabled,
|
||||
hasPagesDir,
|
||||
hasAppDir,
|
||||
}: {
|
||||
baseDir: string
|
||||
distDir: string
|
||||
/** The original distDir before any modifications (e.g., for isolatedDevBuild). Used for stable type imports. */
|
||||
distDirRoot?: string
|
||||
imageImportsEnabled: boolean
|
||||
hasPagesDir: boolean
|
||||
hasAppDir: boolean
|
||||
@@ -57,10 +60,12 @@ export async function writeAppTypeDeclarations({
|
||||
)
|
||||
}
|
||||
|
||||
const routeTypesPath = path.posix.join(
|
||||
distDir.replaceAll(path.win32.sep, path.posix.sep),
|
||||
'types/routes.d.ts'
|
||||
// Use distDirRoot for stable path that doesn't change between dev/build modes
|
||||
const stableDistDir = (distDirRoot ?? distDir).replaceAll(
|
||||
path.win32.sep,
|
||||
path.posix.sep
|
||||
)
|
||||
const routeTypesPath = path.posix.join(stableDistDir, 'types/routes.d.ts')
|
||||
|
||||
// Use ESM import instead of triple-slash reference for better ESLint compatibility
|
||||
directives.push(`import "./${routeTypesPath}";`)
|
||||
|
||||
@@ -36,6 +36,7 @@ const requiredPackages = [
|
||||
export async function verifyTypeScriptSetup({
|
||||
dir,
|
||||
distDir,
|
||||
distDirRoot,
|
||||
cacheDir,
|
||||
tsconfigPath,
|
||||
typeCheckPreflight,
|
||||
@@ -49,6 +50,8 @@ export async function verifyTypeScriptSetup({
|
||||
}: {
|
||||
dir: string
|
||||
distDir: string
|
||||
/** The original distDir before any modifications (e.g., for isolatedDevBuild). */
|
||||
distDirRoot?: string
|
||||
cacheDir?: string
|
||||
tsconfigPath: string | undefined
|
||||
typeCheckPreflight: boolean
|
||||
@@ -143,6 +146,7 @@ export async function verifyTypeScriptSetup({
|
||||
await writeAppTypeDeclarations({
|
||||
baseDir: dir,
|
||||
distDir,
|
||||
distDirRoot,
|
||||
imageImportsEnabled: !disableStaticImages,
|
||||
hasPagesDir,
|
||||
hasAppDir,
|
||||
|
||||
@@ -395,3 +395,28 @@ export async function writeValidatorFile(
|
||||
: generateValidatorFile(manifest)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a proxy routes.d.ts file at the stable path that re-exports from
|
||||
* the actual dev types location. This allows next-env.d.ts to always reference
|
||||
* the same stable path regardless of dev/build mode.
|
||||
*
|
||||
* @param stableTypesDir - The stable types directory (e.g., .next/types)
|
||||
* @param devTypesRelativePath - Relative path from stable dir to dev types (e.g., ../dev/types/routes.d.ts)
|
||||
*/
|
||||
export async function writeRouteTypesProxy(
|
||||
stableTypesDir: string,
|
||||
devTypesRelativePath: string
|
||||
) {
|
||||
if (!fs.existsSync(stableTypesDir)) {
|
||||
await fs.promises.mkdir(stableTypesDir, { recursive: true })
|
||||
}
|
||||
|
||||
const proxyFilePath = path.join(stableTypesDir, 'routes.d.ts')
|
||||
const proxyContent = `// This file re-exports route types from the dev types location.
|
||||
// This provides a stable import path for next-env.d.ts across dev/build modes.
|
||||
export * from '${devTypesRelativePath}';
|
||||
`
|
||||
|
||||
await fs.promises.writeFile(proxyFilePath, proxyContent)
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ import {
|
||||
createRouteTypesManifest,
|
||||
writeRouteTypesManifest,
|
||||
writeValidatorFile,
|
||||
writeRouteTypesProxy,
|
||||
} from './route-types-utils'
|
||||
import { writeCacheLifeTypes } from './cache-life-type-utils'
|
||||
import { isParallelRouteSegment } from '../../../shared/lib/segment'
|
||||
@@ -143,6 +144,7 @@ async function verifyTypeScript(opts: SetupOpts) {
|
||||
const verifyResult = await verifyTypeScriptSetup({
|
||||
dir: opts.dir,
|
||||
distDir: opts.nextConfig.distDir,
|
||||
distDirRoot: opts.nextConfig.distDirRoot,
|
||||
typeCheckPreflight: false,
|
||||
tsconfigPath: opts.nextConfig.typescript.tsconfigPath,
|
||||
disableStaticImages: opts.nextConfig.images.disableStaticImages,
|
||||
@@ -266,6 +268,17 @@ async function startWatcher(
|
||||
opts.nextConfig
|
||||
)
|
||||
|
||||
// When isolatedDevBuild is enabled, write a proxy file at the stable path
|
||||
// that re-exports from the dev types location
|
||||
if (opts.nextConfig.experimental.isolatedDevBuild) {
|
||||
const stableTypesDir = path.join(
|
||||
opts.dir,
|
||||
opts.nextConfig.distDirRoot,
|
||||
'types'
|
||||
)
|
||||
await writeRouteTypesProxy(stableTypesDir, '../dev/types/routes.d.ts')
|
||||
}
|
||||
|
||||
const routesManifestPath = path.join(distDir, ROUTES_MANIFEST)
|
||||
const routesManifest: DevRoutesManifest = {
|
||||
version: 3,
|
||||
|
||||
@@ -23,4 +23,32 @@ describe('isolated-dev-build', () => {
|
||||
expect(await browser.elementByCss('p').text()).toBe('hello updated world')
|
||||
})
|
||||
})
|
||||
|
||||
it('should use stable path in next-env.d.ts that does not change between dev/build', async () => {
|
||||
const nextEnvContent = await next.readFile('next-env.d.ts')
|
||||
// Snapshot ensures next-env.d.ts content stays stable
|
||||
expect(nextEnvContent).toMatchInlineSnapshot(`
|
||||
"/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import "./.next/types/routes.d.ts";
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
"
|
||||
`)
|
||||
})
|
||||
|
||||
it('should create proxy routes.d.ts at stable path that re-exports from dev types', async () => {
|
||||
// The proxy file should re-export from the dev types location
|
||||
const proxyContent = await next.readFile('.next/types/routes.d.ts')
|
||||
expect(proxyContent).toMatchInlineSnapshot(`
|
||||
"// This file re-exports route types from the dev types location.
|
||||
// This provides a stable import path for next-env.d.ts across dev/build modes.
|
||||
export * from '../dev/types/routes.d.ts';
|
||||
"
|
||||
`)
|
||||
|
||||
// The actual dev types should exist
|
||||
expect(await next.hasFile('.next/dev/types/routes.d.ts')).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import './.next/dev/types/routes.d.ts'
|
||||
import './.next/types/routes.d.ts'
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import "./.next/dev/types/routes.d.ts";
|
||||
import "./.next/types/routes.d.ts";
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
|
||||
|
||||
Reference in New Issue
Block a user