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() - }) - }) -})