Skip to content

Commit 20c9fc4

Browse files
committed
fix: make generateTrace work with newer TypeScript versions
Closes: TypeStrong#722
1 parent 95c69ff commit 20c9fc4

File tree

3 files changed

+57
-44
lines changed

3 files changed

+57
-44
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ yarn add --dev @types/webpack
347347

348348
## Profiling types resolution
349349

350-
When using TypeScript 4.1.x in `build` mode you can profile long type checks by
350+
When using TypeScript 4.3.0 or newer in `build` mode you can profile long type checks by
351351
setting "generateTrace" compiler option. This is an instruction from [microsoft/TypeScript#40063](https://github.com/microsoft/TypeScript/pull/40063):
352352

353353
1. Set "generateTrace": "{folderName}" in your `tsconfig.json` (under `compilerOptions`)

src/typescript/worker/lib/tracing.ts

+27-16
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,48 @@ import { getConfigFilePathFromCompilerOptions } from './config';
44
import { typescript } from './typescript';
55
import { config } from './worker-config';
66

7-
// write this type as it's available only starting from TypeScript 4.1.0
7+
// these types are internal in TypeScript, so reproduce them here
8+
type Mode = 'project' | 'build' | 'server';
89
interface Tracing {
9-
startTracing(configFilePath: string, traceDirPath: string, isBuildMode: boolean): void;
10-
stopTracing(typeCatalog: unknown): void;
11-
dumpLegend(): void;
10+
startTracing:
11+
| undefined
12+
| ((tracingMode: Mode, traceDir: string, configFilePath?: string) => void);
13+
14+
tracing:
15+
| undefined
16+
| {
17+
stopTracing(): void;
18+
dumpLegend(): void;
19+
};
1220
}
1321

1422
// eslint-disable-next-line @typescript-eslint/no-explicit-any
15-
const tracing: Tracing | undefined = (typescript as any).tracing;
23+
const traceableTypescript: Tracing = typescript as any;
1624

1725
export function startTracingIfNeeded(compilerOptions: ts.CompilerOptions) {
18-
if (compilerOptions.generateTrace && tracing) {
19-
tracing.startTracing(
20-
getConfigFilePathFromCompilerOptions(compilerOptions),
21-
compilerOptions.generateTrace as string,
22-
config.build
26+
if (
27+
typeof compilerOptions.generateTrace === 'string' &&
28+
typeof traceableTypescript.startTracing === 'function'
29+
) {
30+
traceableTypescript.startTracing(
31+
config.build ? 'build' : 'project',
32+
compilerOptions.generateTrace,
33+
getConfigFilePathFromCompilerOptions(compilerOptions)
2334
);
2435
}
2536
}
2637

2738
export function stopTracingIfNeeded(program: ts.BuilderProgram) {
2839
const compilerOptions = program.getCompilerOptions();
2940

30-
if (compilerOptions.generateTrace && tracing) {
31-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
32-
tracing.stopTracing((program.getProgram() as any).getTypeCatalog());
41+
if (
42+
typeof compilerOptions.generateTrace === 'string' &&
43+
typeof traceableTypescript.tracing?.stopTracing === 'function'
44+
) {
45+
traceableTypescript.tracing.stopTracing();
3346
}
3447
}
3548

3649
export function dumpTracingLegendIfNeeded() {
37-
if (tracing) {
38-
tracing.dumpLegend();
39-
}
50+
traceableTypescript.tracing?.dumpLegend();
4051
}

test/e2e/type-script-tracing.spec.ts

+29-27
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,38 @@ import path from 'path';
33
import { extractWebpackErrors } from './driver/webpack-errors-extractor';
44

55
describe('TypeScript Tracing', () => {
6-
it.each([{ build: true, typescript: '~4.1.0' }])(
7-
'can generate trace files for %p',
8-
async ({ build, ...dependencies }) => {
9-
await sandbox.load(path.join(__dirname, 'fixtures/typescript-basic'));
10-
await sandbox.install('yarn', { ...dependencies });
6+
it.each([
7+
{ build: true, typescript: '~4.3.0' },
8+
{ build: true, typescript: '~4.4.0' },
9+
{ build: true, typescript: '~4.5.0' },
10+
{ build: true, typescript: '~4.6.0' },
11+
])('can generate trace files for %p', async ({ build, ...dependencies }) => {
12+
await sandbox.load(path.join(__dirname, 'fixtures/typescript-basic'));
13+
await sandbox.install('yarn', { ...dependencies });
1114

12-
// enable tracing
13-
await sandbox.patch(
14-
'tsconfig.json',
15-
'"outDir": "./dist"',
16-
'"outDir": "./dist",\n"generateTrace": "./traces"'
17-
);
15+
// enable tracing
16+
await sandbox.patch(
17+
'tsconfig.json',
18+
'"outDir": "./dist"',
19+
'"outDir": "./dist",\n"generateTrace": "./traces"'
20+
);
1821

19-
await sandbox.write(
20-
'fork-ts-checker.config.js',
21-
`module.exports = ${JSON.stringify({ typescript: { build } })};`
22-
);
22+
await sandbox.write(
23+
'fork-ts-checker.config.js',
24+
`module.exports = ${JSON.stringify({ typescript: { build } })};`
25+
);
2326

24-
const webpackResult = await sandbox.exec('yarn webpack --mode=development');
25-
const errors = extractWebpackErrors(webpackResult);
26-
expect(errors).toEqual([]);
27+
const webpackResult = await sandbox.exec('yarn webpack --mode=development');
28+
const errors = extractWebpackErrors(webpackResult);
29+
expect(errors).toEqual([]);
2730

28-
expect(await sandbox.exists('dist')).toEqual(true);
31+
expect(await sandbox.exists('dist')).toEqual(true);
2932

30-
expect(await sandbox.list('./traces')).toEqual(
31-
expect.arrayContaining([
32-
expect.objectContaining({ name: expect.stringMatching(/types.*\.json/) }),
33-
expect.objectContaining({ name: expect.stringMatching(/trace.*\.json/) }),
34-
])
35-
);
36-
}
37-
);
33+
expect(await sandbox.list('./traces')).toEqual(
34+
expect.arrayContaining([
35+
expect.objectContaining({ name: expect.stringMatching(/types.*\.json/) }),
36+
expect.objectContaining({ name: expect.stringMatching(/trace.*\.json/) }),
37+
])
38+
);
39+
});
3840
});

0 commit comments

Comments
 (0)