Skip to content

Commit 4cf8b05

Browse files
authored
Fix tsconfig resolution quirks (#683)
1 parent c8ec522 commit 4cf8b05

File tree

7 files changed

+51
-4
lines changed

7 files changed

+51
-4
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ yarn.lock
44
test/fixtures/project/node_modules/.cache
55
!test/fixtures/typescript/extends-module/node_modules
66
test/fixtures/typescript/extends-module/node_modules/.cache
7+
!test/fixtures/typescript/extends-tsconfig-bases/node_modules
8+
test/fixtures/typescript/extends-tsconfig-bases/node_modules/.cache
79
.nyc_output
810
coverage

lib/options-manager.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
CACHE_DIR_NAME,
2929
} from './constants.js';
3030

31-
const {__dirname, readJson, require} = createEsmUtils(import.meta);
31+
const {__dirname, require} = createEsmUtils(import.meta);
3232
const {normalizePackageName} = Legacy.naming;
3333
const resolveModule = Legacy.ModuleResolver.resolve;
3434

@@ -162,7 +162,7 @@ const handleTSConfig = async options => {
162162

163163
if (tsConfigProjectPath) {
164164
options.tsConfigPath = path.resolve(options.cwd, tsConfigProjectPath);
165-
options.tsConfig = await readJson(options.tsConfigPath);
165+
options.tsConfig = JSON5.parse(await fs.readFile(options.tsConfigPath));
166166
} else {
167167
const tsConfigExplorer = cosmiconfig([], {
168168
searchPlaces: ['tsconfig.json'],
@@ -644,9 +644,22 @@ async function recursiveBuildTsConfig(tsConfig, tsConfigPath) {
644644
}
645645

646646
// If any of the following are missing, then we need to look up the base config as it could apply
647-
// Use node resolution
648647
const require = createRequire(tsConfigPath);
649-
const basePath = require.resolve(tsConfig.extends);
648+
649+
let basePath;
650+
try {
651+
basePath = require.resolve(tsConfig.extends);
652+
} catch (error) {
653+
// Tsconfig resolution is odd, It allows behavior that is not exactly like node resolution
654+
// therefore we attempt to smooth this out here with this hack
655+
try {
656+
basePath = require.resolve(path.join(tsConfig.extends, 'tsconfig.json'));
657+
} catch {
658+
// Throw the orginal resolution error to let the user know their extends block is invalid
659+
throw error;
660+
}
661+
}
662+
650663
const baseTsConfig = JSON5.parse(await fs.readFile(basePath));
651664

652665
delete tsConfig.extends;

test/fixtures/typescript/extends-tsconfig-bases/node_modules/@tsconfig/node16/package.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/fixtures/typescript/extends-tsconfig-bases/node_modules/@tsconfig/node16/tsconfig.json

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"xo": {}
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "@tsconfig/node16"
3+
}

test/options-manager.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,15 @@ test('mergeWithFileConfig: tsconfig can properly extend configs in node_modules'
680680
t.is(options.tsConfigPath, expectedConfigPath);
681681
});
682682

683+
test('mergeWithFileConfig: tsconfig can properly extend tsconfig base node_modules', async t => {
684+
const cwd = path.resolve('fixtures', 'typescript', 'extends-tsconfig-bases');
685+
const expectedConfigPath = path.join(cwd, 'tsconfig.json');
686+
const filePath = path.resolve(cwd, 'does-not-matter.ts');
687+
await t.notThrowsAsync(manager.mergeWithFileConfig({cwd, filePath}));
688+
const {options} = await manager.mergeWithFileConfig({cwd, filePath});
689+
t.is(options.tsConfigPath, expectedConfigPath);
690+
});
691+
683692
test('applyOverrides', t => {
684693
t.deepEqual(
685694
manager.applyOverrides(

0 commit comments

Comments
 (0)