update tsconfig correctly when compilerOptions is not set yet (#30355)

A tsconfig like:

```
{
  "extends": "..."
}
```

currently fails the build if the config that is extended from has not the expected configuration (and we want to update it)

Fixes: https://github.com/vercel/next.js/issues/30360
This commit is contained in:
Tobias Koppers 2021-10-27 06:11:07 +02:00 committed by GitHub
parent 718003c8a7
commit 431178bf53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 0 deletions

View file

@ -117,6 +117,9 @@ export async function writeConfigurationDefaults(
const check = desiredCompilerOptions[optionKey]
if ('suggested' in check) {
if (!(optionKey in tsOptions)) {
if (!userTsConfig.compilerOptions) {
userTsConfig.compilerOptions = {}
}
userTsConfig.compilerOptions[optionKey] = check.suggested
suggestedActions.push(
chalk.cyan(optionKey) + ' was set to ' + chalk.bold(check.suggested)
@ -131,6 +134,9 @@ export async function writeConfigurationDefaults(
? check.parsedValue === ev
: check.value === ev)
) {
if (!userTsConfig.compilerOptions) {
userTsConfig.compilerOptions = {}
}
userTsConfig.compilerOptions[optionKey] = check.value
requiredActions.push(
chalk.cyan(optionKey) +

View file

@ -315,4 +315,61 @@ describe('tsconfig.json verifier', () => {
`"{ \\"extends\\": \\"./tsconfig.base.json\\" }"`
)
})
it('creates compilerOptions when you extend another config', async () => {
expect(await exists(tsConfig)).toBe(false)
expect(await exists(tsConfigBase)).toBe(false)
await writeFile(
tsConfigBase,
`
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}
`
)
await new Promise((resolve) => setTimeout(resolve, 500))
await writeFile(tsConfig, `{ "extends": "./tsconfig.base.json" }`)
await new Promise((resolve) => setTimeout(resolve, 500))
const { code } = await nextBuild(appDir)
expect(code).toBe(0)
expect(await readFile(tsConfig, 'utf8')).toMatchInlineSnapshot(`
"{
\\"extends\\": \\"./tsconfig.base.json\\",
\\"compilerOptions\\": {
\\"incremental\\": true
}
}
"
`)
})
})