Improve initial setup with new App Router TypeScript project (#64826)
This commit is contained in:
parent
270a9db056
commit
3438b39fcf
35 changed files with 360 additions and 142 deletions
6
.github/workflows/build_reusable.yml
vendored
6
.github/workflows/build_reusable.yml
vendored
|
@ -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' }}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -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(
|
||||
|
|
|
@ -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"]
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
@ -15,5 +15,7 @@
|
|||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"target": "ES2017",
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 })
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -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 })
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ export {
|
|||
createNextApp,
|
||||
projectFilesShouldExist,
|
||||
projectFilesShouldNotExist,
|
||||
projectShouldHaveNoGitChanges,
|
||||
shouldBeTemplateProject,
|
||||
shouldBeJavascriptProject,
|
||||
shouldBeTypescriptProject,
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue