Skip to content

Commit

Permalink
feat: support tsconfig extends (#328)
Browse files Browse the repository at this point in the history
* (feat) Support tsconfig extends

Fixes #300

* lint

Co-authored-by: Simon Holthausen <simon.holthausen@accso.de>
  • Loading branch information
dummdidumm and Simon Holthausen committed Mar 26, 2021
1 parent 795c02b commit d0b4766
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 31 deletions.
83 changes: 53 additions & 30 deletions src/transformers/typescript.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { dirname } from 'path';
import { dirname, isAbsolute, join } from 'path';

import ts from 'typescript';

Expand Down Expand Up @@ -53,6 +53,53 @@ const importTransformer: ts.TransformerFactory<ts.SourceFile> = (context) => {
return (node) => ts.visitNode(node, visit);
};

export function loadTsconfig(
compilerOptionsJSON: any,
filename: string,
tsOptions: Options.Typescript,
) {
if (typeof tsOptions.tsconfigFile === 'boolean') {
return { errors: [], options: compilerOptionsJSON };
}

let basePath = process.cwd();

const fileDirectory = (tsOptions.tsconfigDirectory ||
dirname(filename)) as string;

let tsconfigFile =
tsOptions.tsconfigFile ||
ts.findConfigFile(fileDirectory, ts.sys.fileExists);

tsconfigFile = isAbsolute(tsconfigFile)
? tsconfigFile
: join(basePath, tsconfigFile);

basePath = dirname(tsconfigFile);

const { error, config } = ts.readConfigFile(tsconfigFile, ts.sys.readFile);

if (error) {
throw new Error(formatDiagnostics(error, basePath));
}

// Do this so TS will not search for initial files which might take a while
config.include = [];

let { errors, options } = ts.parseJsonConfigFileContent(
config,
ts.sys,
basePath,
compilerOptionsJSON,
tsconfigFile,
);

// Filter out "no files found error"
errors = errors.filter((d) => d.code !== 18003);

return { errors, options };
}

const transformer: Transformer<Options.Typescript> = ({
content,
filename,
Expand All @@ -64,38 +111,14 @@ const transformer: Transformer<Options.Typescript> = ({
target: 'es6',
};

let basePath = process.cwd();

if (options.tsconfigFile !== false || options.tsconfigDirectory) {
const fileDirectory = (options.tsconfigDirectory ||
dirname(filename)) as string;

const tsconfigFile =
options.tsconfigFile ||
ts.findConfigFile(fileDirectory, ts.sys.fileExists);

if (typeof tsconfigFile === 'string') {
basePath = dirname(tsconfigFile);

const { error, config } = ts.readConfigFile(
tsconfigFile,
ts.sys.readFile,
);

if (error) {
throw new Error(formatDiagnostics(error, basePath));
}

Object.assign(compilerOptionsJSON, config.compilerOptions);
}
}
const basePath = process.cwd();

Object.assign(compilerOptionsJSON, options.compilerOptions);

const {
errors,
options: convertedCompilerOptions,
} = ts.convertCompilerOptionsFromJson(compilerOptionsJSON, basePath);
const { errors, options: convertedCompilerOptions } =
options.tsconfigFile !== false || options.tsconfigDirectory
? loadTsconfig(compilerOptionsJSON, filename, options)
: ts.convertCompilerOptionsFromJson(compilerOptionsJSON, basePath);

if (errors.length) {
throw new Error(formatDiagnostics(errors, basePath));
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/tsconfig.extends1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "./tsconfig.extends2.json",
"compilerOptions": {
"esModuleInterop": true,
}
}
6 changes: 6 additions & 0 deletions test/fixtures/tsconfig.extends2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"skipLibCheck": false,
}
}
20 changes: 19 additions & 1 deletion test/transformers/typescript.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import { resolve } from 'path';
import type { Diagnostic } from 'typescript';

import sveltePreprocess from '../../src';
import { loadTsconfig } from '../../src/transformers/typescript';
import type { Processed } from '../../src/types';
import { preprocess, getFixtureContent, spyConsole } from '../utils';
import {
preprocess,
getFixtureContent,
spyConsole,
getTestAppFilename,
} from '../utils';

spyConsole({ silent: true });

Expand Down Expand Up @@ -103,5 +109,17 @@ describe('transformer - typescript', () => {

return expect(code).toContain(getFixtureContent('script.js'));
});

it('supports extends field', () => {
const { options } = loadTsconfig({}, getTestAppFilename(), {
tsconfigFile: './test/fixtures/tsconfig.extends1.json',
});

expect(options).toMatchObject({
module: 5,
skipLibCheck: false,
esModuleInterop: true,
});
});
});
});

0 comments on commit d0b4766

Please sign in to comment.