Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(next): respect extends in tsconfig with exclude and include #16619

Merged
merged 8 commits into from Jan 24, 2021
18 changes: 9 additions & 9 deletions packages/next/lib/typescript/writeConfigurationDefaults.ts
Expand Up @@ -95,16 +95,16 @@ export async function writeConfigurationDefaults(
}

const desiredCompilerOptions = getDesiredCompilerOptions(ts)
const effectiveConfiguration = await getTypeScriptConfiguration(
ts,
tsConfigPath
)
const {
options: tsOptions,
raw: rawConfig,
} = await getTypeScriptConfiguration(ts, tsConfigPath)

const userTsConfigContent = await fs.readFile(tsConfigPath, {
encoding: 'utf8',
})
const userTsConfig = CommentJson.parse(userTsConfigContent)
if (userTsConfig.compilerOptions == null) {
if (userTsConfig.compilerOptions == null && !('extends' in rawConfig)) {
userTsConfig.compilerOptions = {}
isFirstTimeSetup = true
}
Expand All @@ -114,14 +114,14 @@ export async function writeConfigurationDefaults(
for (const optionKey of Object.keys(desiredCompilerOptions)) {
const check = desiredCompilerOptions[optionKey]
if ('suggested' in check) {
if (!(optionKey in effectiveConfiguration.options)) {
if (!(optionKey in tsOptions)) {
userTsConfig.compilerOptions[optionKey] = check.suggested
suggestedActions.push(
chalk.cyan(optionKey) + ' was set to ' + chalk.bold(check.suggested)
)
}
} else if ('value' in check) {
const ev = effectiveConfiguration.options[optionKey]
const ev = tsOptions[optionKey]
if (
!('parsedValues' in check
? check.parsedValues?.includes(ev)
Expand All @@ -143,7 +143,7 @@ export async function writeConfigurationDefaults(
}
}

if (userTsConfig.include == null) {
if (!('include' in rawConfig)) {
userTsConfig.include = ['next-env.d.ts', '**/*.ts', '**/*.tsx']
suggestedActions.push(
chalk.cyan('include') +
Expand All @@ -152,7 +152,7 @@ export async function writeConfigurationDefaults(
)
}

if (userTsConfig.exclude == null) {
if (!('exclude' in rawConfig)) {
userTsConfig.exclude = ['node_modules']
suggestedActions.push(
chalk.cyan('exclude') + ' was set to ' + chalk.bold(`['node_modules']`)
Expand Down
54 changes: 54 additions & 0 deletions test/integration/tsconfig-verifier/test/index.test.js
Expand Up @@ -10,13 +10,16 @@ jest.setTimeout(1000 * 60 * 5)
describe('tsconfig.json verifier', () => {
const appDir = path.join(__dirname, '../')
const tsConfig = path.join(appDir, 'tsconfig.json')
const tsConfigBase = path.join(appDir, 'tsconfig.base.json')

beforeEach(async () => {
await remove(tsConfig)
await remove(tsConfigBase)
})

afterEach(async () => {
await remove(tsConfig)
await remove(tsConfigBase)
})

it('Creates a default tsconfig.json when one is missing', async () => {
Expand Down Expand Up @@ -258,4 +261,55 @@ describe('tsconfig.json verifier', () => {
"
`)
})

it('allows you to extend another configuration file', 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\\" }"`
)
})
})