Skip to content

Commit e812f18

Browse files
authored
feat: overwrite other fields in tsconfig.json (#440)
As we have full control over the config file content, we can easily overwrite other fields like `include` or `exclude`. It can be useful, for example, if you don't want to type-check storybook files in your webpack compilation. Now you don't have to create a separate tsconfig.json file to accomplish that. BREAKING CHANGE: 🧨 `typescript.compilerOptions` option changed to the `typescript.configOverwrite.compilerOptions` option
1 parent 2b72fd0 commit e812f18

14 files changed

+178
-141
lines changed

README.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -153,18 +153,18 @@ Options passed to the plugin constructor will overwrite options from the cosmico
153153

154154
Options for the TypeScript checker (`typescript` option object).
155155

156-
| Name | Type | Default value | Description |
157-
| -------------------- | --------- | -------------------------------------------------------------------------------------- | ----------- |
158-
| `enabled` | `boolean` | `true` | If `true`, it enables TypeScript checker. |
159-
| `memoryLimit` | `number` | `2048` | Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number. |
160-
| `configFile` | `string` | `'tsconfig.json'` | Path to the `tsconfig.json` file (path relative to the `compiler.options.context` or absolute path) |
161-
| `context` | `string` | `dirname(configuration.configFile)` | The base path for finding files specified in the `tsconfig.json`. Same as the `context` option from the [ts-loader](https://github.com/TypeStrong/ts-loader#context). Useful if you want to keep your `tsconfig.json` in an external package. Keep in mind that **not** having a `tsconfig.json` in your project root can cause different behaviour between `fork-ts-checker-webpack-plugin` and `tsc`. When using editors like `VS Code` it is advised to add a `tsconfig.json` file to the root of the project and extend the config file referenced in option `configFile`. |
162-
| `build` | `boolean` | `false` | The equivalent of the `--build` flag for the `tsc` command. |
163-
| `mode` | `'readonly'` or `'write-tsbuildinfo'` or `'write-references'` | `'write-tsbuildinfo'` | If you use the `babel-loader`, it's recommended to use `write-references` mode to improve initial compilation time. If you use `ts-loader`, it's recommended to use `write-tsbuildinfo` mode to not overwrite filed emitted by the `ts-loader`. |
164-
| `compilerOptions` | `object` | `{ skipLibCheck: true, sourceMap: false, inlineSourceMap: false, incremental: true }` | These options will overwrite compiler options from the `tsconfig.json` file. |
165-
| `diagnosticsOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. |
166-
| `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). |
167-
| `profile` | `boolean` | `false` | Measures and prints timings related to the TypeScript performance. |
156+
| Name | Type | Default value | Description |
157+
| -------------------- | --------- | ---------------------------------------------------------------------------------------------------------- | ----------- |
158+
| `enabled` | `boolean` | `true` | If `true`, it enables TypeScript checker. |
159+
| `memoryLimit` | `number` | `2048` | Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number. |
160+
| `configFile` | `string` | `'tsconfig.json'` | Path to the `tsconfig.json` file (path relative to the `compiler.options.context` or absolute path) |
161+
| `configOverwrite` | `object` | `{ compilerOptions: { skipLibCheck: true, sourceMap: false, inlineSourceMap: false, incremental: true } }` | This configuration will overwrite configuration from the `tsconfig.json` file. Supported fields are: `extends`, `compilerOptions`, `include`, `exclude`, `files`, and `references`. |
162+
| `context` | `string` | `dirname(configuration.configFile)` | The base path for finding files specified in the `tsconfig.json`. Same as the `context` option from the [ts-loader](https://github.com/TypeStrong/ts-loader#context). Useful if you want to keep your `tsconfig.json` in an external package. Keep in mind that **not** having a `tsconfig.json` in your project root can cause different behaviour between `fork-ts-checker-webpack-plugin` and `tsc`. When using editors like `VS Code` it is advised to add a `tsconfig.json` file to the root of the project and extend the config file referenced in option `configFile`. |
163+
| `build` | `boolean` | `false` | The equivalent of the `--build` flag for the `tsc` command. |
164+
| `mode` | `'readonly'` or `'write-tsbuildinfo'` or `'write-references'` | `'write-tsbuildinfo'` | If you use the `babel-loader`, it's recommended to use `write-references` mode to improve initial compilation time. If you use `ts-loader`, it's recommended to use `write-tsbuildinfo` mode to not overwrite filed emitted by the `ts-loader`. |
165+
| `diagnosticsOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. |
166+
| `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). |
167+
| `profile` | `boolean` | `false` | Measures and prints timings related to the TypeScript performance. |
168168

169169
#### TypeScript extensions options
170170

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
interface TypeScriptConfigurationOverwrite {
2+
extends?: string;
3+
compilerOptions?: object;
4+
include?: string[];
5+
exclude?: string[];
6+
files?: string[];
7+
references?: { path: string; prepend?: boolean }[];
8+
}
9+
10+
export { TypeScriptConfigurationOverwrite };

src/typescript-reporter/TypeScriptReporterConfiguration.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ import {
88
createTypeScriptVueExtensionConfiguration,
99
TypeScriptVueExtensionConfiguration,
1010
} from './extension/vue/TypeScriptVueExtensionConfiguration';
11+
import { TypeScriptConfigurationOverwrite } from './TypeScriptConfigurationOverwrite';
1112

1213
interface TypeScriptReporterConfiguration {
1314
enabled: boolean;
1415
memoryLimit: number;
1516
configFile: string;
17+
configOverwrite: TypeScriptConfigurationOverwrite;
1618
build: boolean;
1719
context: string;
1820
mode: 'readonly' | 'write-tsbuildinfo' | 'write-references';
19-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
20-
compilerOptions: any;
2121
diagnosticOptions: TypeScriptDiagnosticsOptions;
2222
extensions: {
2323
vue: TypeScriptVueExtensionConfiguration;
@@ -62,11 +62,14 @@ function createTypeScriptReporterConfiguration(
6262
profile: false,
6363
...optionsAsObject,
6464
configFile: configFile,
65-
context: optionsAsObject.context || path.dirname(configFile),
66-
compilerOptions: {
67-
...defaultCompilerOptions,
68-
...(optionsAsObject.compilerOptions || {}),
65+
configOverwrite: {
66+
...(optionsAsObject.configOverwrite || {}),
67+
compilerOptions: {
68+
...defaultCompilerOptions,
69+
...((optionsAsObject.configOverwrite || {}).compilerOptions || {}),
70+
},
6971
},
72+
context: optionsAsObject.context || path.dirname(configFile),
7073
extensions: {
7174
vue: createTypeScriptVueExtensionConfiguration(
7275
optionsAsObject.extensions ? optionsAsObject.extensions.vue : undefined

src/typescript-reporter/TypeScriptReporterOptions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import { TypeScriptDiagnosticsOptions } from './TypeScriptDiagnosticsOptions';
22
import { TypeScriptVueExtensionOptions } from './extension/vue/TypeScriptVueExtensionOptions';
3+
import { TypeScriptConfigurationOverwrite } from './TypeScriptConfigurationOverwrite';
34

45
type TypeScriptReporterOptions =
56
| boolean
67
| {
78
enabled?: boolean;
89
memoryLimit?: number;
910
configFile?: string;
11+
configOverwrite?: TypeScriptConfigurationOverwrite;
1012
context?: string;
1113
build?: boolean;
1214
mode?: 'readonly' | 'write-tsbuildinfo' | 'write-references';
13-
compilerOptions?: object;
1415
diagnosticOptions?: Partial<TypeScriptDiagnosticsOptions>;
1516
extensions?: {
1617
vue?: TypeScriptVueExtensionOptions;

src/typescript-reporter/reporter/TypeScriptConfigurationParser.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
11
import * as ts from 'typescript';
2+
import { TypeScriptConfigurationOverwrite } from '../TypeScriptConfigurationOverwrite';
23

34
function parseTypeScriptConfiguration(
45
configFileName: string,
56
configFileContext: string,
6-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7-
customCompilerOptions: any,
7+
configOverwriteJSON: TypeScriptConfigurationOverwrite,
88
parseConfigFileHost: ts.ParseConfigFileHost
99
): ts.ParsedCommandLine {
10-
// convert jsonCompilerOptions to ts.CompilerOptions
11-
const customCompilerOptionsConvertResults = ts.convertCompilerOptionsFromJson(
12-
customCompilerOptions,
13-
configFileContext
14-
);
10+
const parsedConfigFileJSON = ts.readConfigFile(configFileName, parseConfigFileHost.readFile);
11+
12+
const overwrittenConfigFileJSON = {
13+
...(parsedConfigFileJSON.config || {}),
14+
...configOverwriteJSON,
15+
compilerOptions: {
16+
...((parsedConfigFileJSON.config || {}).compilerOptions || {}),
17+
...(configOverwriteJSON.compilerOptions || {}),
18+
},
19+
};
1520

16-
const parsedConfigFile = ts.parseJsonSourceFileConfigFileContent(
17-
ts.readJsonConfigFile(configFileName, parseConfigFileHost.readFile),
21+
const parsedConfigFile = ts.parseJsonConfigFileContent(
22+
overwrittenConfigFileJSON,
1823
parseConfigFileHost,
19-
configFileContext,
20-
customCompilerOptionsConvertResults.options || {}
24+
configFileContext
2125
);
22-
if (customCompilerOptionsConvertResults.errors) {
23-
parsedConfigFile.errors.push(...customCompilerOptionsConvertResults.errors);
24-
}
2526

2627
return {
2728
...parsedConfigFile,
2829
options: {
2930
...parsedConfigFile.options,
3031
configFilePath: configFileName,
3132
},
33+
errors: parsedConfigFileJSON.error ? [parsedConfigFileJSON.error] : parsedConfigFile.errors,
3234
};
3335
}
3436

src/typescript-reporter/reporter/TypeScriptReporter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration
119119
parsedConfiguration = parseTypeScriptConfiguration(
120120
configuration.configFile,
121121
configuration.context,
122-
configuration.compilerOptions,
122+
configuration.configOverwrite,
123123
{
124124
...system,
125125
onUnRecoverableConfigFileDiagnostic: (diagnostic) => {

test/e2e/TypeScriptCompilerOptions.spec.ts

Lines changed: 0 additions & 63 deletions
This file was deleted.

test/e2e/TypeScriptConfigurationChange.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ describe('TypeScript Configuration Change', () => {
6060
expect(errors.length).toBeGreaterThan(0);
6161

6262
// revert the change
63-
await sandbox.patch('tsconfig.json', '"lib": ["ES6"]', '"lib": ["DOM", "ES6"],');
63+
await sandbox.patch('tsconfig.json', '"lib": ["ES6"],', '"lib": ["DOM", "ES6"]');
6464

6565
await driver.waitForNoErrors();
6666
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, Sandbox } from './sandbox/Sandbox';
2+
import { readFixture } from './sandbox/Fixture';
3+
import { join } from 'path';
4+
import {
5+
createWebpackDevServerDriver,
6+
WEBPACK_CLI_VERSION,
7+
WEBPACK_DEV_SERVER_VERSION,
8+
WebpackDevServerDriver,
9+
} from './sandbox/WebpackDevServerDriver';
10+
11+
describe('TypeScript Compiler Options parsing', () => {
12+
let sandbox: Sandbox;
13+
14+
beforeAll(async () => {
15+
sandbox = await createSandbox();
16+
});
17+
18+
beforeEach(async () => {
19+
await sandbox.reset();
20+
});
21+
22+
afterAll(async () => {
23+
await sandbox.cleanup();
24+
});
25+
26+
it.each([
27+
{ typescript: '2.7.1' },
28+
{ typescript: '~3.0.0' },
29+
{ typescript: '~3.6.0' },
30+
{ typescript: '^3.8.0' },
31+
])('reports errors because of the misconfiguration', async ({ typescript }) => {
32+
await sandbox.load([
33+
await readFixture(join(__dirname, 'fixtures/environment/typescript-basic.fixture'), {
34+
FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify(
35+
FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION
36+
),
37+
TS_LOADER_VERSION: JSON.stringify('^5.0.0'),
38+
TYPESCRIPT_VERSION: JSON.stringify(typescript),
39+
WEBPACK_VERSION: JSON.stringify('^4.0.0'),
40+
WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION),
41+
WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION),
42+
ASYNC: JSON.stringify(false),
43+
}),
44+
await readFixture(join(__dirname, 'fixtures/implementation/typescript-basic.fixture')),
45+
]);
46+
47+
let driver: WebpackDevServerDriver;
48+
let errors: string[];
49+
50+
await sandbox.write(
51+
'fork-ts-checker.config.js',
52+
'module.exports = { typescript: { configOverwrite: { compilerOptions: { target: "ES3", lib: ["ES3"] } } } };'
53+
);
54+
55+
driver = createWebpackDevServerDriver(sandbox.spawn('npm run webpack-dev-server'), false);
56+
errors = await driver.waitForErrors();
57+
expect(errors.length).toBeGreaterThan(0);
58+
await sandbox.kill(driver.process);
59+
60+
await sandbox.write(
61+
'fork-ts-checker.config.js',
62+
'module.exports = { typescript: { configOverwrite: { include: [] } } };'
63+
);
64+
65+
driver = createWebpackDevServerDriver(sandbox.spawn('npm run webpack-dev-server'), false);
66+
errors = await driver.waitForErrors();
67+
expect(errors.length).toBeGreaterThan(0);
68+
await sandbox.kill(driver.process);
69+
});
70+
});

test/e2e/sandbox/GenericProcessDriver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { createQueuedListener, Listener, QueuedListener } from './Listener';
33
import stripAnsi from 'strip-ansi';
44

55
interface GenericProcessDriver {
6+
process: ChildProcess;
67
waitForStdoutIncludes: (string: string, timeout?: number) => Promise<void>;
78
waitForStderrIncludes: (string: string, timeout?: number) => Promise<void>;
8-
close: () => Promise<boolean>;
99
}
1010

1111
interface StringListener extends Listener {
@@ -66,6 +66,7 @@ function createGenericProcessDriver(
6666
}
6767

6868
return {
69+
process,
6970
waitForStdoutIncludes: (string, timeout = defaultTimeout) =>
7071
new Promise<void>((resolve, reject) => {
7172
const timeoutId = setTimeout(() => {
@@ -106,7 +107,6 @@ function createGenericProcessDriver(
106107
string,
107108
});
108109
}),
109-
close: async () => process.kill(),
110110
};
111111
}
112112

0 commit comments

Comments
 (0)