Skip to content

Commit 95050eb

Browse files
Speeds up project reference build and doesnt store the result in memory (#1202)
* Output files are on disk so dont store their text in memory * Get rid of version from output * remove time * Since the files are on disk, dont read them unless needed. * add to CHANGELOG Co-authored-by: John Reilly <[email protected]>
1 parent f99c7c4 commit 95050eb

File tree

22 files changed

+306
-1411
lines changed

22 files changed

+306
-1411
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## v8.0.7
4+
* [Speeds up project reference build and doesnt store the result in memory](https://github.com/TypeStrong/ts-loader/pull/1202) - thanks @sheetalkamat
5+
36
## v8.0.6
47
* [Fixed further deprecation warning on webpack@5](https://github.com/TypeStrong/ts-loader/issues/1196) - thanks @appzuka
58

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ts-loader",
3-
"version": "8.0.6",
3+
"version": "8.0.7",
44
"description": "TypeScript loader for webpack",
55
"main": "index.js",
66
"types": "dist",

src/index.ts

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -329,27 +329,18 @@ function updateFileInCache(
329329
instance.changedFilesList = true;
330330
}
331331
} else {
332-
if (
333-
instance.watchHost !== undefined ||
334-
instance.solutionBuilderHost !== undefined
335-
) {
332+
if (instance.watchHost !== undefined) {
336333
fileWatcherEventKind = instance.compiler.FileWatcherEventKind.Created;
337334
}
338335
file = { fileName: filePath, version: 0 };
339336
if (!isReferencedFile(instance, filePath)) {
340337
instance.files.set(key, file);
341338
instance.changedFilesList = true;
342-
} else {
343-
instance.otherFiles.set(key, file);
344339
}
345340
}
346341
}
347342

348-
if (
349-
(instance.watchHost !== undefined ||
350-
instance.solutionBuilderHost !== undefined) &&
351-
contents === undefined
352-
) {
343+
if (instance.watchHost !== undefined && contents === undefined) {
353344
fileWatcherEventKind = instance.compiler.FileWatcherEventKind.Deleted;
354345
}
355346

@@ -376,8 +367,7 @@ function updateFileInCache(
376367
file.modifiedTime = new Date();
377368
instance.version++;
378369
if (
379-
(instance.watchHost !== undefined ||
380-
instance.solutionBuilderHost !== undefined) &&
370+
instance.watchHost !== undefined &&
381371
fileWatcherEventKind === undefined
382372
) {
383373
fileWatcherEventKind = instance.compiler.FileWatcherEventKind.Changed;
@@ -395,16 +385,6 @@ function updateFileInCache(
395385
instance.hasUnaccountedModifiedFiles;
396386
}
397387

398-
if (
399-
instance.solutionBuilderHost !== undefined &&
400-
fileWatcherEventKind !== undefined
401-
) {
402-
instance.solutionBuilderHost.invokeFileWatcher(
403-
filePath,
404-
fileWatcherEventKind
405-
);
406-
}
407-
408388
// push this file to modified files hash.
409389
if (!instance.modifiedFiles) {
410390
instance.modifiedFiles = new Map();
@@ -438,10 +418,9 @@ function getEmit(
438418
defFilePath.match(constants.dtsDtsxOrDtsDtsxMapRegex) &&
439419
// Remove the project reference d.ts as we are adding dependency for .ts later
440420
// This removed extra build pass (resulting in new stats object in initial build)
441-
(!instance.solutionBuilderHost ||
442-
!instance.solutionBuilderHost.getOutputFileKeyFromReferencedProject(
443-
defFilePath
444-
))
421+
!instance.solutionBuilderHost?.getOutputFileKeyFromReferencedProject(
422+
defFilePath
423+
)
445424
) {
446425
addDependency(defFilePath);
447426
}
@@ -469,12 +448,18 @@ function getEmit(
469448
defFilePath =>
470449
path.relative(loaderContext.rootContext, defFilePath) +
471450
'@' +
472-
(
473-
instance.files.get(instance.filePathKeyMapper(defFilePath)) ||
474-
instance.otherFiles.get(instance.filePathKeyMapper(defFilePath)) || {
475-
version: '?',
476-
}
477-
).version
451+
(isReferencedFile(instance, defFilePath)
452+
? instance
453+
.solutionBuilderHost!.getInputFileStamp(defFilePath)
454+
.toString()
455+
: (
456+
instance.files.get(instance.filePathKeyMapper(defFilePath)) ||
457+
instance.otherFiles.get(
458+
instance.filePathKeyMapper(defFilePath)
459+
) || {
460+
version: '?',
461+
}
462+
).version)
478463
);
479464

480465
return getOutputAndSourceMapFromOutputFiles(outputFiles);

src/instances.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ export function buildSolutionReferences(
507507
{ verbose: true }
508508
);
509509
solutionBuilder.build();
510-
ensureAllReferences(instance);
510+
instance.solutionBuilderHost.ensureAllReferenceTimestamps();
511511
instancesBySolutionBuilderConfigs.set(
512512
instance.filePathKeyMapper(instance.configFilePath!),
513513
instance
@@ -517,28 +517,6 @@ export function buildSolutionReferences(
517517
}
518518
}
519519

520-
function ensureAllReferences(instance: TSInstance) {
521-
// Return result from the json without errors so that the extra errors from config are digested here
522-
for (const configInfo of instance.solutionBuilderHost!.configFileInfo.values()) {
523-
if (!configInfo.config) {
524-
continue;
525-
}
526-
// Load all the input files
527-
configInfo.config.fileNames.forEach(file => {
528-
const resolvedFileName = instance.filePathKeyMapper(file);
529-
const existing = instance.otherFiles.get(resolvedFileName);
530-
if (!existing) {
531-
instance.otherFiles.set(resolvedFileName, {
532-
fileName: path.resolve(file),
533-
version: 1,
534-
text: instance.compiler.sys.readFile(file),
535-
modifiedTime: instance.compiler.sys.getModifiedTime!(file),
536-
});
537-
}
538-
});
539-
}
540-
}
541-
542520
export function forEachResolvedProjectReference<T>(
543521
resolvedProjectReferences:
544522
| readonly (typescript.ResolvedProjectReference | undefined)[]

src/interfaces.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ export type ResolveSync = (
4242
moduleName: string
4343
) => string;
4444

45-
export type Action = () => void;
46-
4745
export interface HostMayBeCacheable {
48-
clearCache?: Action;
46+
clearCache?(): void;
47+
fileExistsCache?: Map<string, boolean>;
48+
directoryExistsCache?: Map<string, boolean>;
49+
realpathCache?: Map<string, string>;
4950
}
5051

5152
export interface CacheableHost extends HostMayBeCacheable {
@@ -130,39 +131,40 @@ export interface SolutionBuilderWithWatchHost
130131
>,
131132
WatchFactory {
132133
diagnostics: SolutionDiagnostics;
133-
writtenFiles: OutputFile[];
134+
writtenFiles: typescript.OutputFile[];
134135
configFileInfo: Map<FilePathKey, ConfigFileInfo>;
135136
outputAffectingInstanceVersion: Map<FilePathKey, true>;
137+
getInputFileStamp(fileName: string): Date;
138+
updateSolutionBuilderInputFile(fileName: string): void;
136139
getOutputFileKeyFromReferencedProject(
137140
outputFileName: string
138141
): FilePathKey | undefined;
139-
getOutputFileFromReferencedProject(
140-
outputFileName: string
141-
): OutputFile | false | undefined;
142142
getOutputFileAndKeyFromReferencedProject(
143143
oututFileName: string
144-
): { key: FilePathKey; outputFile: OutputFile | false } | undefined;
144+
): { key: FilePathKey; outputFile: string | false } | undefined;
145+
getOutputFileTextAndKeyFromReferencedProject(
146+
oututFileName: string
147+
): { key: FilePathKey; text: string | undefined } | undefined;
145148
getInputFileNameFromOutput(outputFileName: string): string | undefined;
146-
getOutputFilesFromReferencedProjectInput(inputFileName: string): OutputFile[];
149+
getOutputFilesFromReferencedProjectInput(
150+
inputFileName: string
151+
): typescript.OutputFile[];
147152
buildReferences(): void;
153+
ensureAllReferenceTimestamps(): void;
148154
clearCache(): void;
155+
close(): void;
149156
}
150157

151158
export interface ConfigFileInfo {
152159
config: typescript.ParsedCommandLine | undefined;
153160
outputFileNames?: Map<
154161
FilePathKey,
155-
{ inputFileName: string; outputNames: FilePathKey[] }
162+
{ inputFileName: string; outputNames: string[] }
156163
>;
157164
tsbuildInfoFile?: string;
158165
dtsFiles?: string[];
159166
}
160167

161-
export interface OutputFile extends typescript.OutputFile {
162-
time: Date;
163-
version: number;
164-
}
165-
166168
export interface TSInstance {
167169
compiler: typeof typescript;
168170
compilerOptions: typescript.CompilerOptions;

0 commit comments

Comments
 (0)