Skip to content

Commit 9639c2b

Browse files
authored
feat: add typescriptPath option (#478)
1 parent 52c5110 commit 9639c2b

15 files changed

+63
-32
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ Options for the TypeScript checker (`typescript` option object).
168168
| `diagnosticOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. |
169169
| `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). |
170170
| `profile` | `boolean` | `false` | Measures and prints timings related to the TypeScript performance. |
171+
| `typescriptPath` | `string` | `require.resolve('typescript')` | If supplied this is a custom path where TypeScript can be found. |
171172

172173
#### TypeScript extensions options
173174

src/ForkTsCheckerWebpackPluginOptions.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@
175175
"profile": {
176176
"type": "boolean",
177177
"description": "Measures and prints timings related to the TypeScript performance."
178+
},
179+
"typescriptPath": {
180+
"type": "string",
181+
"description": "If supplied this is a custom path where TypeScript can be found."
178182
}
179183
}
180184
}

src/typescript-reporter/TypeScriptReporterConfiguration.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ interface TypeScriptReporterConfiguration {
2323
vue: TypeScriptVueExtensionConfiguration;
2424
};
2525
profile: boolean;
26+
typescriptPath: string;
2627
}
2728

2829
function createTypeScriptReporterConfiguration(
@@ -42,12 +43,14 @@ function createTypeScriptReporterConfiguration(
4243
const optionsAsObject: Exclude<TypeScriptReporterOptions, boolean> =
4344
typeof options === 'object' ? options : {};
4445

46+
const typescriptPath = optionsAsObject.typescriptPath || require.resolve('typescript');
47+
4548
const defaultCompilerOptions: Record<string, unknown> = {
4649
skipLibCheck: true,
4750
sourceMap: false,
4851
inlineSourceMap: false,
4952
};
50-
if (semver.gte(ts.version, '2.9.0')) {
53+
if (semver.gte(require(typescriptPath).version, '2.9.0')) {
5154
defaultCompilerOptions.declarationMap = false;
5255
}
5356

@@ -79,6 +82,7 @@ function createTypeScriptReporterConfiguration(
7982
global: false,
8083
...(optionsAsObject.diagnosticOptions || {}),
8184
},
85+
typescriptPath: typescriptPath,
8286
};
8387
}
8488

src/typescript-reporter/TypeScriptReporterOptions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type TypeScriptReporterOptions =
1717
vue?: TypeScriptVueExtensionOptions;
1818
};
1919
profile?: boolean;
20+
typescriptPath?: string;
2021
};
2122

2223
export { TypeScriptReporterOptions };

src/typescript-reporter/TypeScriptSupport.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ function assertTypeScriptSupport(configuration: TypeScriptReporterConfiguration)
88
let typescriptVersion: string | undefined;
99

1010
try {
11-
typescriptVersion = require('typescript').version;
11+
typescriptVersion = require(configuration.typescriptPath).version;
1212
} catch (error) {}
1313

1414
if (!typescriptVersion) {

src/typescript-reporter/issue/TypeScriptIssueFactory.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as ts from 'typescript';
22
import * as os from 'os';
33
import { deduplicateAndSortIssues, Issue, IssueLocation } from '../../issue';
44

5-
function createIssueFromTsDiagnostic(diagnostic: ts.Diagnostic): Issue {
5+
function createIssueFromTsDiagnostic(typescript: typeof ts, diagnostic: ts.Diagnostic): Issue {
66
let file: string | undefined;
77
let location: IssueLocation | undefined;
88

@@ -37,15 +37,18 @@ function createIssueFromTsDiagnostic(diagnostic: ts.Diagnostic): Issue {
3737
code: 'TS' + String(diagnostic.code),
3838
// we don't handle Suggestion and Message diagnostics
3939
severity: diagnostic.category === 0 ? 'warning' : 'error',
40-
message: ts.flattenDiagnosticMessageText(diagnostic.messageText, os.EOL),
40+
message: typescript.flattenDiagnosticMessageText(diagnostic.messageText, os.EOL),
4141
file,
4242
location,
4343
};
4444
}
4545

46-
function createIssuesFromTsDiagnostics(diagnostics: ts.Diagnostic[]): Issue[] {
46+
function createIssuesFromTsDiagnostics(
47+
typescript: typeof ts,
48+
diagnostics: ts.Diagnostic[]
49+
): Issue[] {
4750
return deduplicateAndSortIssues(
48-
diagnostics.map((diagnostic) => createIssueFromTsDiagnostic(diagnostic))
51+
diagnostics.map((diagnostic) => createIssueFromTsDiagnostic(typescript, diagnostic))
4952
);
5053
}
5154

src/typescript-reporter/profile/TypeScriptPerformance.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@ interface TypeScriptPerformance {
88
measure(name: string, startMark?: string, endMark?: string): void;
99
}
1010

11-
function getTypeScriptPerformance(): TypeScriptPerformance | undefined {
11+
function getTypeScriptPerformance(typescript: typeof ts): TypeScriptPerformance | undefined {
1212
// eslint-disable-next-line @typescript-eslint/no-explicit-any
13-
return (ts as any).performance;
13+
return (typescript as any).performance;
1414
}
1515

16-
function connectTypeScriptPerformance(performance: Performance): Performance {
17-
const typeScriptPerformance = getTypeScriptPerformance();
16+
function connectTypeScriptPerformance(
17+
typescript: typeof ts,
18+
performance: Performance
19+
): Performance {
20+
const typeScriptPerformance = getTypeScriptPerformance(typescript);
1821

1922
if (typeScriptPerformance) {
2023
const { mark, measure } = typeScriptPerformance;

src/typescript-reporter/reporter/ControlledTypeScriptSystem.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ interface ControlledTypeScriptSystem extends ts.System {
4040
type FileSystemMode = 'readonly' | 'write-tsbuildinfo' | 'write-references';
4141

4242
function createControlledTypeScriptSystem(
43+
typescript: typeof ts,
4344
mode: FileSystemMode = 'readonly'
4445
): ControlledTypeScriptSystem {
4546
// watchers
@@ -50,7 +51,7 @@ function createControlledTypeScriptSystem(
5051
const deletedFiles = new Map<string, boolean>();
5152
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5253
const timeoutCallbacks = new Set<any>();
53-
const caseSensitive = ts.sys.useCaseSensitiveFileNames;
54+
const caseSensitive = typescript.sys.useCaseSensitiveFileNames;
5455
const realFileSystem = createRealFileSystem(caseSensitive);
5556
const passiveFileSystem = createPassiveFileSystem(caseSensitive, realFileSystem);
5657

@@ -149,7 +150,7 @@ function createControlledTypeScriptSystem(
149150
}
150151

151152
const controlledSystem: ControlledTypeScriptSystem = {
152-
...ts.sys,
153+
...typescript.sys,
153154
useCaseSensitiveFileNames: caseSensitive,
154155
fileExists(path: string): boolean {
155156
const stats = passiveFileSystem.readStats(path);
@@ -200,7 +201,7 @@ function createControlledTypeScriptSystem(
200201
getWriteFileSystem(path).updateTimes(path, date, date);
201202

202203
invokeDirectoryWatchers(path);
203-
invokeFileWatchers(path, ts.FileWatcherEventKind.Changed);
204+
invokeFileWatchers(path, typescript.FileWatcherEventKind.Changed);
204205
},
205206
watchFile(path: string, callback: ts.FileWatcherCallback): ts.FileWatcher {
206207
return createWatcher(fileWatcherCallbacksMap, path, callback);
@@ -240,7 +241,7 @@ function createControlledTypeScriptSystem(
240241
invokeFileCreated(path: string) {
241242
const normalizedPath = realFileSystem.normalizePath(path);
242243

243-
invokeFileWatchers(path, ts.FileWatcherEventKind.Created);
244+
invokeFileWatchers(path, typescript.FileWatcherEventKind.Created);
244245
invokeDirectoryWatchers(normalizedPath);
245246

246247
deletedFiles.set(normalizedPath, false);
@@ -249,19 +250,19 @@ function createControlledTypeScriptSystem(
249250
const normalizedPath = realFileSystem.normalizePath(path);
250251

251252
if (deletedFiles.get(normalizedPath) || !fileWatcherCallbacksMap.has(normalizedPath)) {
252-
invokeFileWatchers(path, ts.FileWatcherEventKind.Created);
253+
invokeFileWatchers(path, typescript.FileWatcherEventKind.Created);
253254
invokeDirectoryWatchers(normalizedPath);
254255

255256
deletedFiles.set(normalizedPath, false);
256257
} else {
257-
invokeFileWatchers(path, ts.FileWatcherEventKind.Changed);
258+
invokeFileWatchers(path, typescript.FileWatcherEventKind.Changed);
258259
}
259260
},
260261
invokeFileDeleted(path: string) {
261262
const normalizedPath = realFileSystem.normalizePath(path);
262263

263264
if (!deletedFiles.get(normalizedPath)) {
264-
invokeFileWatchers(path, ts.FileWatcherEventKind.Deleted);
265+
invokeFileWatchers(path, typescript.FileWatcherEventKind.Deleted);
265266
invokeDirectoryWatchers(path);
266267

267268
deletedFiles.set(normalizedPath, true);

src/typescript-reporter/reporter/ControlledWatchCompilerHost.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { TypeScriptHostExtension } from '../extension/TypeScriptExtension';
33
import { ControlledTypeScriptSystem } from './ControlledTypeScriptSystem';
44

55
function createControlledWatchCompilerHost<TProgram extends ts.BuilderProgram>(
6+
typescript: typeof ts,
67
parsedCommandLine: ts.ParsedCommandLine,
78
system: ControlledTypeScriptSystem,
89
createProgram?: ts.CreateProgram<TProgram>,
@@ -11,7 +12,7 @@ function createControlledWatchCompilerHost<TProgram extends ts.BuilderProgram>(
1112
afterProgramCreate?: (program: TProgram) => void,
1213
hostExtensions: TypeScriptHostExtension[] = []
1314
): ts.WatchCompilerHostOfFilesAndCompilerOptions<TProgram> {
14-
const baseWatchCompilerHost = ts.createWatchCompilerHost(
15+
const baseWatchCompilerHost = typescript.createWatchCompilerHost(
1516
parsedCommandLine.fileNames,
1617
parsedCommandLine.options,
1718
system,
@@ -33,7 +34,7 @@ function createControlledWatchCompilerHost<TProgram extends ts.BuilderProgram>(
3334
): TProgram {
3435
// as compilerHost is optional, ensure that we have it
3536
if (!compilerHost) {
36-
compilerHost = ts.createCompilerHost(options || parsedCommandLine.options);
37+
compilerHost = typescript.createCompilerHost(options || parsedCommandLine.options);
3738
}
3839

3940
hostExtensions.forEach((hostExtension) => {

src/typescript-reporter/reporter/ControlledWatchSolutionBuilderHost.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { TypeScriptHostExtension } from '../extension/TypeScriptExtension';
44
import { ControlledTypeScriptSystem } from './ControlledTypeScriptSystem';
55

66
function createControlledWatchSolutionBuilderHost<TProgram extends ts.BuilderProgram>(
7+
typescript: typeof ts,
78
parsedCommandLine: ts.ParsedCommandLine,
89
system: ControlledTypeScriptSystem,
910
createProgram?: ts.CreateProgram<TProgram>,
@@ -15,6 +16,7 @@ function createControlledWatchSolutionBuilderHost<TProgram extends ts.BuilderPro
1516
hostExtensions: TypeScriptHostExtension[] = []
1617
): ts.SolutionBuilderWithWatchHost<TProgram> {
1718
const controlledWatchCompilerHost = createControlledWatchCompilerHost(
19+
typescript,
1820
parsedCommandLine,
1921
system,
2022
createProgram,

0 commit comments

Comments
 (0)