diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml
index 71efa09474..81a2ffe05f 100644
--- a/.github/workflows/build_reusable.yml
+++ b/.github/workflows/build_reusable.yml
@@ -133,6 +133,12 @@ jobs:
# clean up any previous artifacts to avoid hitting disk space limits
- run: git clean -xdf && rm -rf /tmp/next-repo-*; rm -rf /tmp/next-install-* /tmp/yarn-* /tmp/ncc-cache target
+ # Configure a git user so that Create Next App can initialize git repos during integration tests.
+ - name: Set CI git user
+ run: |
+ git config --global user.name "vercel-ci-bot"
+ git config --global user.email "infra+ci@vercel.com"
+
- run: cargo clean
if: ${{ inputs.skipNativeBuild != 'yes' || inputs.needsNextest == 'yes' || inputs.needsRust == 'yes' }}
diff --git a/packages/create-next-app/templates/app-tw/ts/tsconfig.json b/packages/create-next-app/templates/app-tw/ts/tsconfig.json
index e7ff90fd27..d8b93235f2 100644
--- a/packages/create-next-app/templates/app-tw/ts/tsconfig.json
+++ b/packages/create-next-app/templates/app-tw/ts/tsconfig.json
@@ -1,5 +1,6 @@
{
"compilerOptions": {
+ "target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
diff --git a/packages/create-next-app/templates/app/ts/tsconfig.json b/packages/create-next-app/templates/app/ts/tsconfig.json
index e7ff90fd27..d8b93235f2 100644
--- a/packages/create-next-app/templates/app/ts/tsconfig.json
+++ b/packages/create-next-app/templates/app/ts/tsconfig.json
@@ -1,5 +1,6 @@
{
"compilerOptions": {
+ "target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
diff --git a/packages/create-next-app/templates/default-tw/ts/tsconfig.json b/packages/create-next-app/templates/default-tw/ts/tsconfig.json
index 649790e5da..957e71fe5b 100644
--- a/packages/create-next-app/templates/default-tw/ts/tsconfig.json
+++ b/packages/create-next-app/templates/default-tw/ts/tsconfig.json
@@ -1,5 +1,6 @@
{
"compilerOptions": {
+ "target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
diff --git a/packages/create-next-app/templates/default/ts/tsconfig.json b/packages/create-next-app/templates/default/ts/tsconfig.json
index 649790e5da..957e71fe5b 100644
--- a/packages/create-next-app/templates/default/ts/tsconfig.json
+++ b/packages/create-next-app/templates/default/ts/tsconfig.json
@@ -1,5 +1,6 @@
{
"compilerOptions": {
+ "target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
diff --git a/packages/next/src/lib/typescript/writeConfigurationDefaults.test.ts b/packages/next/src/lib/typescript/writeConfigurationDefaults.test.ts
new file mode 100644
index 0000000000..62981007dd
--- /dev/null
+++ b/packages/next/src/lib/typescript/writeConfigurationDefaults.test.ts
@@ -0,0 +1,257 @@
+import { mkdtemp, writeFile, readFile } from 'node:fs/promises'
+import { tmpdir } from 'node:os'
+import { join } from 'node:path'
+// eslint-disable-next-line import/no-extraneous-dependencies
+import ts from 'typescript'
+import { writeConfigurationDefaults } from './writeConfigurationDefaults'
+
+describe('writeConfigurationDefaults()', () => {
+ let consoleLogSpy: jest.SpyInstance
+ let distDir: string
+ let hasAppDir: boolean
+ let tmpDir: string
+ let tsConfigPath: string
+ let isFirstTimeSetup: boolean
+ let hasPagesDir: boolean
+
+ beforeEach(async () => {
+ consoleLogSpy = jest.spyOn(console, 'log').mockImplementation()
+ distDir = '.next'
+ tmpDir = await mkdtemp(join(tmpdir(), 'nextjs-test-'))
+ tsConfigPath = join(tmpDir, 'tsconfig.json')
+ isFirstTimeSetup = false
+ })
+
+ afterEach(() => {
+ consoleLogSpy.mockRestore()
+ })
+
+ describe('appDir', () => {
+ beforeEach(() => {
+ hasAppDir = true
+ hasPagesDir = false
+ })
+
+ it('applies suggested and mandatory defaults to existing tsconfig.json and logs them', async () => {
+ await writeFile(tsConfigPath, JSON.stringify({ compilerOptions: {} }), {
+ encoding: 'utf8',
+ })
+
+ await writeConfigurationDefaults(
+ ts,
+ tsConfigPath,
+ isFirstTimeSetup,
+ hasAppDir,
+ distDir,
+ hasPagesDir
+ )
+
+ const tsConfig = await readFile(tsConfigPath, { encoding: 'utf8' })
+
+ expect(JSON.parse(tsConfig)).toMatchInlineSnapshot(`
+ {
+ "compilerOptions": {
+ "allowJs": true,
+ "esModuleInterop": true,
+ "incremental": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext",
+ ],
+ "module": "esnext",
+ "moduleResolution": "node",
+ "noEmit": true,
+ "plugins": [
+ {
+ "name": "next",
+ },
+ ],
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "target": "ES2017",
+ },
+ "exclude": [
+ "node_modules",
+ ],
+ "include": [
+ "next-env.d.ts",
+ ".next/types/**/*.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ],
+ }
+ `)
+
+ expect(
+ consoleLogSpy.mock.calls
+ .flat()
+ .join('\n')
+ // eslint-disable-next-line no-control-regex
+ .replace(/\x1B\[\d+m/g, '') // remove color control characters
+ ).toMatchInlineSnapshot(`
+ "
+
+ We detected TypeScript in your project and reconfigured your tsconfig.json file for you. Strict-mode is set to false by default.
+
+ The following suggested values were added to your tsconfig.json. These values can be changed to fit your project's needs:
+
+
+ - target was set to ES2017 (For top-level \`await\`. Note: Next.js only polyfills for the esmodules target.)
+
+ - lib was set to dom,dom.iterable,esnext
+
+ - allowJs was set to true
+
+ - skipLibCheck was set to true
+
+ - strict was set to false
+
+ - noEmit was set to true
+
+ - incremental was set to true
+
+ - include was set to ['next-env.d.ts', '.next/types/**/*.ts', '**/*.ts', '**/*.tsx']
+
+ - plugins was updated to add { name: 'next' }
+
+ - exclude was set to ['node_modules']
+
+
+ The following mandatory changes were made to your tsconfig.json:
+
+
+ - module was set to esnext (for dynamic import() support)
+
+ - esModuleInterop was set to true (requirement for SWC / babel)
+
+ - moduleResolution was set to node (to match webpack resolution)
+
+ - resolveJsonModule was set to true (to match webpack resolution)
+
+ - isolatedModules was set to true (requirement for SWC / Babel)
+
+ - jsx was set to preserve (next.js implements its own optimized jsx transform)
+ "
+ `)
+ })
+
+ it('does not warn about disabled strict mode if strict mode was already enabled', async () => {
+ await writeFile(
+ tsConfigPath,
+ JSON.stringify({ compilerOptions: { strict: true } }),
+ { encoding: 'utf8' }
+ )
+
+ await writeConfigurationDefaults(
+ ts,
+ tsConfigPath,
+ isFirstTimeSetup,
+ hasAppDir,
+ distDir,
+ hasPagesDir
+ )
+
+ expect(
+ consoleLogSpy.mock.calls
+ .flat()
+ .join('\n')
+ // eslint-disable-next-line no-control-regex
+ .replace(/\x1B\[\d+m/g, '') // remove color control characters
+ ).not.toMatch('Strict-mode is set to false by default.')
+ })
+
+ describe('with tsconfig extends', () => {
+ let tsConfigBasePath: string
+ let nextAppTypes: string
+
+ beforeEach(() => {
+ tsConfigBasePath = join(tmpDir, 'tsconfig.base.json')
+ nextAppTypes = `${distDir}/types/**/*.ts`
+ })
+
+ it('should support empty includes when base provides it', async () => {
+ const include = ['**/*.ts', '**/*.tsx', nextAppTypes]
+ const content = { extends: './tsconfig.base.json' }
+ const baseContent = { include }
+
+ await writeFile(tsConfigPath, JSON.stringify(content, null, 2))
+ await writeFile(tsConfigBasePath, JSON.stringify(baseContent, null, 2))
+
+ await expect(
+ writeConfigurationDefaults(
+ ts,
+ tsConfigPath,
+ isFirstTimeSetup,
+ hasAppDir,
+ distDir,
+ hasPagesDir
+ )
+ ).resolves.not.toThrow()
+
+ const output = await readFile(tsConfigPath, 'utf-8')
+ const parsed = JSON.parse(output)
+
+ expect(parsed.include).toBeUndefined()
+ })
+
+ it('should replace includes when base is missing appTypes', async () => {
+ const include = ['**/*.ts', '**/*.tsx']
+ const content = { extends: './tsconfig.base.json' }
+ const baseContent = { include }
+
+ await writeFile(tsConfigPath, JSON.stringify(content, null, 2))
+ await writeFile(tsConfigBasePath, JSON.stringify(baseContent, null, 2))
+
+ await expect(
+ writeConfigurationDefaults(
+ ts,
+ tsConfigPath,
+ isFirstTimeSetup,
+ hasAppDir,
+ distDir,
+ hasPagesDir
+ )
+ ).resolves.not.toThrow()
+
+ const output = await readFile(tsConfigPath, 'utf8')
+ const parsed = JSON.parse(output)
+
+ expect(parsed.include.sort()).toMatchInlineSnapshot(`
+ [
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ]
+ `)
+ })
+
+ it('should not add strictNullChecks if base provides it', async () => {
+ const content = { extends: './tsconfig.base.json' }
+
+ const baseContent = {
+ compilerOptions: { strictNullChecks: true, strict: true },
+ }
+
+ await writeFile(tsConfigPath, JSON.stringify(content, null, 2))
+ await writeFile(tsConfigBasePath, JSON.stringify(baseContent, null, 2))
+
+ await writeConfigurationDefaults(
+ ts,
+ tsConfigPath,
+ isFirstTimeSetup,
+ hasAppDir,
+ distDir,
+ hasPagesDir
+ )
+ const output = await readFile(tsConfigPath, 'utf8')
+ const parsed = JSON.parse(output)
+
+ expect(parsed.compilerOptions.strictNullChecks).toBeUndefined()
+ })
+ })
+ })
+})
diff --git a/packages/next/src/lib/typescript/writeConfigurationDefaults.ts b/packages/next/src/lib/typescript/writeConfigurationDefaults.ts
index a1f61ba8c3..00f6f35176 100644
--- a/packages/next/src/lib/typescript/writeConfigurationDefaults.ts
+++ b/packages/next/src/lib/typescript/writeConfigurationDefaults.ts
@@ -176,9 +176,7 @@ export async function writeConfigurationDefaults(
cyan(optionKey) +
' was set to ' +
bold(check.suggested) +
- check.reason
- ? ` (${check.reason})`
- : ''
+ (check.reason ? ` (${check.reason})` : '')
)
}
} else if ('value' in check) {
@@ -337,8 +335,13 @@ export async function writeConfigurationDefaults(
Log.info(
`We detected TypeScript in your project and reconfigured your ${cyan(
'tsconfig.json'
- )} file for you. Strict-mode is set to ${cyan('false')} by default.`
+ )} file for you.${
+ userTsConfig.compilerOptions?.strict
+ ? ''
+ : ` Strict-mode is set to ${cyan('false')} by default.`
+ }`
)
+
if (suggestedActions.length) {
Log.info(
`The following suggested values were added to your ${cyan(
diff --git a/test/development/acceptance-app/fixtures/app-hmr-changes/tsconfig.json b/test/development/acceptance-app/fixtures/app-hmr-changes/tsconfig.json
index a7b71d74a2..819e8e45f3 100644
--- a/test/development/acceptance-app/fixtures/app-hmr-changes/tsconfig.json
+++ b/test/development/acceptance-app/fixtures/app-hmr-changes/tsconfig.json
@@ -14,8 +14,13 @@
"resolveJsonModule": true,
"isolatedModules": true,
"incremental": true,
- "baseUrl": "."
+ "baseUrl": ".",
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
},
"exclude": ["node_modules"],
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
+ "include": ["**/*.ts", "**/*.tsx", "next-env.d.ts", ".next/types/**/*.ts"]
}
diff --git a/test/development/app-dir/experimental-lightningcss/tsconfig.json b/test/development/app-dir/experimental-lightningcss/tsconfig.json
index b3222239ed..7fdcf2e2f4 100644
--- a/test/development/app-dir/experimental-lightningcss/tsconfig.json
+++ b/test/development/app-dir/experimental-lightningcss/tsconfig.json
@@ -16,7 +16,8 @@
{
"name": "next"
}
- ]
+ ],
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/development/basic/define-class-fields/fixture/tsconfig.json b/test/development/basic/define-class-fields/fixture/tsconfig.json
index 19678d45ed..0836be079c 100644
--- a/test/development/basic/define-class-fields/fixture/tsconfig.json
+++ b/test/development/basic/define-class-fields/fixture/tsconfig.json
@@ -15,5 +15,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true
- }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
}
diff --git a/test/e2e/app-dir/edge-runtime-node-compatibility/tsconfig.json b/test/e2e/app-dir/edge-runtime-node-compatibility/tsconfig.json
index 98a3adc505..ffdb23f66c 100644
--- a/test/e2e/app-dir/edge-runtime-node-compatibility/tsconfig.json
+++ b/test/e2e/app-dir/edge-runtime-node-compatibility/tsconfig.json
@@ -18,7 +18,8 @@
"name": "next"
}
],
- "strictNullChecks": true
+ "strictNullChecks": true,
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/interception-middleware-rewrite/tsconfig.json b/test/e2e/app-dir/interception-middleware-rewrite/tsconfig.json
index b27fb72470..2eef1368c6 100644
--- a/test/e2e/app-dir/interception-middleware-rewrite/tsconfig.json
+++ b/test/e2e/app-dir/interception-middleware-rewrite/tsconfig.json
@@ -17,7 +17,8 @@
{
"name": "next"
}
- ]
+ ],
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/metadata-suspense/tsconfig.json b/test/e2e/app-dir/metadata-suspense/tsconfig.json
index b27fb72470..2eef1368c6 100644
--- a/test/e2e/app-dir/metadata-suspense/tsconfig.json
+++ b/test/e2e/app-dir/metadata-suspense/tsconfig.json
@@ -17,7 +17,8 @@
{
"name": "next"
}
- ]
+ ],
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/modularizeimports/tsconfig.json b/test/e2e/app-dir/modularizeimports/tsconfig.json
index bd052d943b..ecbe79a14d 100644
--- a/test/e2e/app-dir/modularizeimports/tsconfig.json
+++ b/test/e2e/app-dir/modularizeimports/tsconfig.json
@@ -18,7 +18,8 @@
"name": "next"
}
],
- "strictNullChecks": true
+ "strictNullChecks": true,
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/parallel-routes-and-interception/tsconfig.json b/test/e2e/app-dir/parallel-routes-and-interception/tsconfig.json
index b27fb72470..2eef1368c6 100644
--- a/test/e2e/app-dir/parallel-routes-and-interception/tsconfig.json
+++ b/test/e2e/app-dir/parallel-routes-and-interception/tsconfig.json
@@ -17,7 +17,8 @@
{
"name": "next"
}
- ]
+ ],
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/parallel-routes-not-found/tsconfig.json b/test/e2e/app-dir/parallel-routes-not-found/tsconfig.json
index b27fb72470..2eef1368c6 100644
--- a/test/e2e/app-dir/parallel-routes-not-found/tsconfig.json
+++ b/test/e2e/app-dir/parallel-routes-not-found/tsconfig.json
@@ -17,7 +17,8 @@
{
"name": "next"
}
- ]
+ ],
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/root-layout-redirect/tsconfig.json b/test/e2e/app-dir/root-layout-redirect/tsconfig.json
index b27fb72470..2eef1368c6 100644
--- a/test/e2e/app-dir/root-layout-redirect/tsconfig.json
+++ b/test/e2e/app-dir/root-layout-redirect/tsconfig.json
@@ -17,7 +17,8 @@
{
"name": "next"
}
- ]
+ ],
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/router-stuck-dynamic-static-segment/tsconfig.json b/test/e2e/app-dir/router-stuck-dynamic-static-segment/tsconfig.json
index b27fb72470..2eef1368c6 100644
--- a/test/e2e/app-dir/router-stuck-dynamic-static-segment/tsconfig.json
+++ b/test/e2e/app-dir/router-stuck-dynamic-static-segment/tsconfig.json
@@ -17,7 +17,8 @@
{
"name": "next"
}
- ]
+ ],
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/searchparams-static-bailout/tsconfig.json b/test/e2e/app-dir/searchparams-static-bailout/tsconfig.json
index b27fb72470..2eef1368c6 100644
--- a/test/e2e/app-dir/searchparams-static-bailout/tsconfig.json
+++ b/test/e2e/app-dir/searchparams-static-bailout/tsconfig.json
@@ -17,7 +17,8 @@
{
"name": "next"
}
- ]
+ ],
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/underscore-ignore-app-paths/tsconfig.json b/test/e2e/app-dir/underscore-ignore-app-paths/tsconfig.json
index 98a3adc505..ffdb23f66c 100644
--- a/test/e2e/app-dir/underscore-ignore-app-paths/tsconfig.json
+++ b/test/e2e/app-dir/underscore-ignore-app-paths/tsconfig.json
@@ -18,7 +18,8 @@
"name": "next"
}
],
- "strictNullChecks": true
+ "strictNullChecks": true,
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/app-dir/use-params/tsconfig.json b/test/e2e/app-dir/use-params/tsconfig.json
index b27fb72470..1132f0024c 100644
--- a/test/e2e/app-dir/use-params/tsconfig.json
+++ b/test/e2e/app-dir/use-params/tsconfig.json
@@ -17,7 +17,9 @@
{
"name": "next"
}
- ]
+ ],
+ "target": "ES2017",
+ "strictNullChecks": true
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/e2e/instrumentation-hook-src/tsconfig.json b/test/e2e/instrumentation-hook-src/tsconfig.json
index 9d1a27aced..b11582b86f 100644
--- a/test/e2e/instrumentation-hook-src/tsconfig.json
+++ b/test/e2e/instrumentation-hook-src/tsconfig.json
@@ -18,7 +18,8 @@
"name": "next"
}
],
- "strictNullChecks": true
+ "strictNullChecks": true,
+ "target": "ES2017"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
diff --git a/test/integration/app-types/tsconfig.json b/test/integration/app-types/tsconfig.json
index 98a3adc505..ffdb23f66c 100644
--- a/test/integration/app-types/tsconfig.json
+++ b/test/integration/app-types/tsconfig.json
@@ -18,7 +18,8 @@
"name": "next"
}
],
- "strictNullChecks": true
+ "strictNullChecks": true,
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/integration/create-next-app/lib/utils.ts b/test/integration/create-next-app/lib/utils.ts
index 387defb4db..1a7e0243a1 100644
--- a/test/integration/create-next-app/lib/utils.ts
+++ b/test/integration/create-next-app/lib/utils.ts
@@ -4,9 +4,9 @@
* This file contains utilities for `create-next-app` testing.
*/
-import { ChildProcess, spawn, SpawnOptions } from 'child_process'
+import { ChildProcess, execSync, spawn, SpawnOptions } from 'child_process'
import { existsSync } from 'fs'
-import { resolve } from 'path'
+import { join, resolve } from 'path'
import glob from 'glob'
import Conf from 'next/dist/compiled/conf'
@@ -15,7 +15,12 @@ import {
mapSrcFiles,
projectSpecification,
} from './specification'
-import { CustomTemplateOptions, ProjectDeps, ProjectFiles } from './types'
+import {
+ CustomTemplateOptions,
+ DefaultTemplateOptions,
+ ProjectDeps,
+ ProjectFiles,
+} from './types'
const cli = require.resolve('create-next-app/dist/index.js')
@@ -71,6 +76,22 @@ export const spawnExitPromise = (childProcess: ChildProcess) => {
})
}
+export const projectShouldHaveNoGitChanges = ({
+ cwd,
+ projectName,
+}: DefaultTemplateOptions) => {
+ const projectDirname = join(cwd, projectName)
+
+ try {
+ execSync('git diff --quiet', { cwd: projectDirname })
+ } catch {
+ execSync('git status', { cwd: projectDirname, stdio: 'inherit' })
+ execSync('git --no-pager diff', { cwd: projectDirname, stdio: 'inherit' })
+
+ throw new Error('Found unexpected git changes.')
+ }
+}
+
export const projectFilesShouldExist = ({
cwd,
projectName,
diff --git a/test/integration/create-next-app/templates/app.test.ts b/test/integration/create-next-app/templates/app.test.ts
index bbf26cd4fe..6721bb9f74 100644
--- a/test/integration/create-next-app/templates/app.test.ts
+++ b/test/integration/create-next-app/templates/app.test.ts
@@ -1,5 +1,6 @@
import {
createNextApp,
+ projectShouldHaveNoGitChanges,
shouldBeTemplateProject,
spawnExitPromise,
tryNextDev,
@@ -70,10 +71,8 @@ describe('create-next-app --app (App Router)', () => {
const exitCode = await spawnExitPromise(cp)
expect(exitCode).toBe(0)
shouldBeTemplateProject({ cwd, projectName, template: 'app', mode: 'ts' })
- await tryNextDev({
- cwd,
- projectName,
- })
+ await tryNextDev({ cwd, projectName })
+ await projectShouldHaveNoGitChanges({ cwd, projectName })
})
})
diff --git a/test/integration/create-next-app/templates/pages.test.ts b/test/integration/create-next-app/templates/pages.test.ts
index 7888172f8b..77e630220c 100644
--- a/test/integration/create-next-app/templates/pages.test.ts
+++ b/test/integration/create-next-app/templates/pages.test.ts
@@ -1,5 +1,6 @@
import {
createNextApp,
+ projectShouldHaveNoGitChanges,
shouldBeTemplateProject,
spawnExitPromise,
tryNextDev,
@@ -78,11 +79,8 @@ describe('create-next-app --no-app (Pages Router)', () => {
template: 'default',
mode: 'ts',
})
- await tryNextDev({
- cwd,
- projectName,
- isApp: false,
- })
+ await tryNextDev({ cwd, projectName, isApp: false })
+ await projectShouldHaveNoGitChanges({ cwd, projectName })
})
})
diff --git a/test/integration/create-next-app/utils.ts b/test/integration/create-next-app/utils.ts
index 1d242ea7a2..2389cc8bf0 100644
--- a/test/integration/create-next-app/utils.ts
+++ b/test/integration/create-next-app/utils.ts
@@ -74,6 +74,7 @@ export {
createNextApp,
projectFilesShouldExist,
projectFilesShouldNotExist,
+ projectShouldHaveNoGitChanges,
shouldBeTemplateProject,
shouldBeJavascriptProject,
shouldBeTypescriptProject,
diff --git a/test/integration/custom-server-types/next-env.d.ts b/test/integration/custom-server-types/next-env.d.ts
index 7b7aa2c772..4f11a03dc6 100644
--- a/test/integration/custom-server-types/next-env.d.ts
+++ b/test/integration/custom-server-types/next-env.d.ts
@@ -1,2 +1,5 @@
///
-///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/test/integration/draft-mode/tsconfig.json b/test/integration/draft-mode/tsconfig.json
index 0866cd4886..5914a0d347 100644
--- a/test/integration/draft-mode/tsconfig.json
+++ b/test/integration/draft-mode/tsconfig.json
@@ -20,7 +20,8 @@
"amp-test-utils": ["test/lib/amp-test-utils"],
"next-webdriver": ["test/lib/next-webdriver"],
"e2e-utils": ["test/lib/e2e-utils"]
- }
+ },
+ "target": "ES2017"
},
"include": [
"test/integration/draft-mode/next-env.d.ts",
diff --git a/test/integration/eslint/with-typescript/tsconfig.json b/test/integration/eslint/with-typescript/tsconfig.json
index 30ab32c42d..7e6c83ab11 100644
--- a/test/integration/eslint/with-typescript/tsconfig.json
+++ b/test/integration/eslint/with-typescript/tsconfig.json
@@ -18,7 +18,8 @@
"name": "next"
}
],
- "strictNullChecks": true
+ "strictNullChecks": true,
+ "target": "ES2017"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".build/types/**/*.ts"],
"exclude": ["node_modules"]
diff --git a/test/integration/next-image-legacy/svgo-webpack/tsconfig.json b/test/integration/next-image-legacy/svgo-webpack/tsconfig.json
index 7d2ef029f4..8299219e0e 100644
--- a/test/integration/next-image-legacy/svgo-webpack/tsconfig.json
+++ b/test/integration/next-image-legacy/svgo-webpack/tsconfig.json
@@ -12,7 +12,8 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
- "jsx": "preserve"
+ "jsx": "preserve",
+ "incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/production/deployment-id-handling/app/tsconfig.json b/test/production/deployment-id-handling/app/tsconfig.json
index 98a3adc505..ffdb23f66c 100644
--- a/test/production/deployment-id-handling/app/tsconfig.json
+++ b/test/production/deployment-id-handling/app/tsconfig.json
@@ -18,7 +18,8 @@
"name": "next"
}
],
- "strictNullChecks": true
+ "strictNullChecks": true,
+ "target": "ES2017"
},
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/production/graceful-shutdown/src/tsconfig.json b/test/production/graceful-shutdown/src/tsconfig.json
index 1c4f693a99..d88efa188d 100644
--- a/test/production/graceful-shutdown/src/tsconfig.json
+++ b/test/production/graceful-shutdown/src/tsconfig.json
@@ -11,7 +11,8 @@
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
- "jsx": "preserve"
+ "jsx": "preserve",
+ "target": "ES2017"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/production/terser-class-static-blocks/tsconfig.json b/test/production/terser-class-static-blocks/tsconfig.json
index 1c4f693a99..d88efa188d 100644
--- a/test/production/terser-class-static-blocks/tsconfig.json
+++ b/test/production/terser-class-static-blocks/tsconfig.json
@@ -11,7 +11,8 @@
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
- "jsx": "preserve"
+ "jsx": "preserve",
+ "target": "ES2017"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
diff --git a/test/unit/write-configuration-defaults.test.ts b/test/unit/write-configuration-defaults.test.ts
deleted file mode 100644
index f1e946d2e2..0000000000
--- a/test/unit/write-configuration-defaults.test.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-/* eslint-env jest */
-import fs from 'fs-extra'
-import { join } from 'path'
-import { writeConfigurationDefaults } from 'next/dist/lib/typescript/writeConfigurationDefaults'
-import * as ts from 'typescript'
-
-const fixtureDir = join(__dirname, 'fixtures/config-ts')
-const tsconfigFile = join(fixtureDir, 'tsconfig.json')
-const tsconfigBaseFile = join(fixtureDir, 'tsconfig.base.json')
-const distDir = '.next'
-const nextAppTypes = `${distDir}/types/**/*.ts`
-
-describe('tsconfig.base.json', () => {
- beforeEach(async () => {
- await fs.ensureDir(fixtureDir)
- })
- afterEach(async () => {
- await fs.remove(tsconfigFile)
- await fs.remove(tsconfigBaseFile)
- })
-
- describe('appDir', () => {
- it('should support empty includes when base provides it', async () => {
- const include = ['**/*.ts', '**/*.tsx', nextAppTypes]
- const content = {
- extends: './tsconfig.base.json',
- }
- const baseContent = {
- include,
- }
-
- await fs.writeFile(tsconfigFile, JSON.stringify(content, null, 2))
- await fs.writeFile(tsconfigBaseFile, JSON.stringify(baseContent, null, 2))
-
- await expect(
- writeConfigurationDefaults(ts, tsconfigFile, false, true, distDir, true)
- ).resolves.not.toThrow()
-
- const output = await fs.readFile(tsconfigFile, 'utf8')
- const parsed = JSON.parse(output)
-
- expect(parsed.include).toBeUndefined()
- })
-
- it('should replace includes when base is missing appTypes', async () => {
- const include = ['**/*.ts', '**/*.tsx']
- const content = {
- extends: './tsconfig.base.json',
- }
- const baseContent = {
- include,
- }
-
- await fs.writeFile(tsconfigFile, JSON.stringify(content, null, 2))
- await fs.writeFile(tsconfigBaseFile, JSON.stringify(baseContent, null, 2))
-
- await expect(
- writeConfigurationDefaults(ts, tsconfigFile, false, true, distDir, true)
- ).resolves.not.toThrow()
-
- const output = await fs.readFile(tsconfigFile, 'utf8')
- const parsed = JSON.parse(output)
-
- expect(parsed.include.sort()).toMatchInlineSnapshot(`
- [
- "**/*.ts",
- "**/*.tsx",
- ".next/types/**/*.ts",
- ]
- `)
- })
-
- it('should not add strictNullChecks if base provides it', async () => {
- const content = {
- extends: './tsconfig.base.json',
- }
-
- const baseContent = {
- compilerOptions: {
- strictNullChecks: true,
- strict: true,
- },
- }
-
- await fs.writeFile(tsconfigFile, JSON.stringify(content, null, 2))
- await fs.writeFile(tsconfigBaseFile, JSON.stringify(baseContent, null, 2))
-
- await writeConfigurationDefaults(
- ts,
- tsconfigFile,
- false,
- true,
- distDir,
- true
- )
- const output = await fs.readFile(tsconfigFile, 'utf8')
- const parsed = JSON.parse(output)
-
- expect(parsed.compilerOptions.strictNullChecks).toBeUndefined()
- })
- })
-})