Skip to content

Commit 1f12810

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

File tree

3 files changed

+55
-44
lines changed

3 files changed

+55
-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

+25-16
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,46 @@ 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(tracingMode: Mode, traceDir: string, configFilePath?: string): void;
11+
12+
tracing:
13+
| undefined
14+
| {
15+
stopTracing(): void;
16+
dumpLegend(): void;
17+
};
1218
}
1319

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

1723
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
24+
if (
25+
typeof compilerOptions.generateTrace === 'string' &&
26+
typeof traceableTypescript.startTracing === 'function'
27+
) {
28+
traceableTypescript.startTracing(
29+
config.build ? 'build' : 'project',
30+
compilerOptions.generateTrace,
31+
getConfigFilePathFromCompilerOptions(compilerOptions)
2332
);
2433
}
2534
}
2635

2736
export function stopTracingIfNeeded(program: ts.BuilderProgram) {
2837
const compilerOptions = program.getCompilerOptions();
2938

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

3647
export function dumpTracingLegendIfNeeded() {
37-
if (tracing) {
38-
tracing.dumpLegend();
39-
}
48+
traceableTypescript.tracing?.dumpLegend();
4049
}

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)