Skip to content

Commit

Permalink
Speeds up project reference build and doesnt store the result in memo…
Browse files Browse the repository at this point in the history
…ry (#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 <johnny_reilly@hotmail.com>
  • Loading branch information
sheetalkamat and johnnyreilly committed Oct 24, 2020
1 parent f99c7c4 commit 95050eb
Show file tree
Hide file tree
Showing 22 changed files with 306 additions and 1,411 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,8 @@
# Changelog

## v8.0.7
* [Speeds up project reference build and doesnt store the result in memory](https://github.com/TypeStrong/ts-loader/pull/1202) - thanks @sheetalkamat

## v8.0.6
* [Fixed further deprecation warning on webpack@5](https://github.com/TypeStrong/ts-loader/issues/1196) - thanks @appzuka

Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "ts-loader",
"version": "8.0.6",
"version": "8.0.7",
"description": "TypeScript loader for webpack",
"main": "index.js",
"types": "dist",
Expand Down
51 changes: 18 additions & 33 deletions src/index.ts
Expand Up @@ -329,27 +329,18 @@ function updateFileInCache(
instance.changedFilesList = true;
}
} else {
if (
instance.watchHost !== undefined ||
instance.solutionBuilderHost !== undefined
) {
if (instance.watchHost !== undefined) {
fileWatcherEventKind = instance.compiler.FileWatcherEventKind.Created;
}
file = { fileName: filePath, version: 0 };
if (!isReferencedFile(instance, filePath)) {
instance.files.set(key, file);
instance.changedFilesList = true;
} else {
instance.otherFiles.set(key, file);
}
}
}

if (
(instance.watchHost !== undefined ||
instance.solutionBuilderHost !== undefined) &&
contents === undefined
) {
if (instance.watchHost !== undefined && contents === undefined) {
fileWatcherEventKind = instance.compiler.FileWatcherEventKind.Deleted;
}

Expand All @@ -376,8 +367,7 @@ function updateFileInCache(
file.modifiedTime = new Date();
instance.version++;
if (
(instance.watchHost !== undefined ||
instance.solutionBuilderHost !== undefined) &&
instance.watchHost !== undefined &&
fileWatcherEventKind === undefined
) {
fileWatcherEventKind = instance.compiler.FileWatcherEventKind.Changed;
Expand All @@ -395,16 +385,6 @@ function updateFileInCache(
instance.hasUnaccountedModifiedFiles;
}

if (
instance.solutionBuilderHost !== undefined &&
fileWatcherEventKind !== undefined
) {
instance.solutionBuilderHost.invokeFileWatcher(
filePath,
fileWatcherEventKind
);
}

// push this file to modified files hash.
if (!instance.modifiedFiles) {
instance.modifiedFiles = new Map();
Expand Down Expand Up @@ -438,10 +418,9 @@ function getEmit(
defFilePath.match(constants.dtsDtsxOrDtsDtsxMapRegex) &&
// Remove the project reference d.ts as we are adding dependency for .ts later
// This removed extra build pass (resulting in new stats object in initial build)
(!instance.solutionBuilderHost ||
!instance.solutionBuilderHost.getOutputFileKeyFromReferencedProject(
defFilePath
))
!instance.solutionBuilderHost?.getOutputFileKeyFromReferencedProject(
defFilePath
)
) {
addDependency(defFilePath);
}
Expand Down Expand Up @@ -469,12 +448,18 @@ function getEmit(
defFilePath =>
path.relative(loaderContext.rootContext, defFilePath) +
'@' +
(
instance.files.get(instance.filePathKeyMapper(defFilePath)) ||
instance.otherFiles.get(instance.filePathKeyMapper(defFilePath)) || {
version: '?',
}
).version
(isReferencedFile(instance, defFilePath)
? instance
.solutionBuilderHost!.getInputFileStamp(defFilePath)
.toString()
: (
instance.files.get(instance.filePathKeyMapper(defFilePath)) ||
instance.otherFiles.get(
instance.filePathKeyMapper(defFilePath)
) || {
version: '?',
}
).version)
);

return getOutputAndSourceMapFromOutputFiles(outputFiles);
Expand Down
24 changes: 1 addition & 23 deletions src/instances.ts
Expand Up @@ -507,7 +507,7 @@ export function buildSolutionReferences(
{ verbose: true }
);
solutionBuilder.build();
ensureAllReferences(instance);
instance.solutionBuilderHost.ensureAllReferenceTimestamps();
instancesBySolutionBuilderConfigs.set(
instance.filePathKeyMapper(instance.configFilePath!),
instance
Expand All @@ -517,28 +517,6 @@ export function buildSolutionReferences(
}
}

function ensureAllReferences(instance: TSInstance) {
// Return result from the json without errors so that the extra errors from config are digested here
for (const configInfo of instance.solutionBuilderHost!.configFileInfo.values()) {
if (!configInfo.config) {
continue;
}
// Load all the input files
configInfo.config.fileNames.forEach(file => {
const resolvedFileName = instance.filePathKeyMapper(file);
const existing = instance.otherFiles.get(resolvedFileName);
if (!existing) {
instance.otherFiles.set(resolvedFileName, {
fileName: path.resolve(file),
version: 1,
text: instance.compiler.sys.readFile(file),
modifiedTime: instance.compiler.sys.getModifiedTime!(file),
});
}
});
}
}

export function forEachResolvedProjectReference<T>(
resolvedProjectReferences:
| readonly (typescript.ResolvedProjectReference | undefined)[]
Expand Down
32 changes: 17 additions & 15 deletions src/interfaces.ts
Expand Up @@ -42,10 +42,11 @@ export type ResolveSync = (
moduleName: string
) => string;

export type Action = () => void;

export interface HostMayBeCacheable {
clearCache?: Action;
clearCache?(): void;
fileExistsCache?: Map<string, boolean>;
directoryExistsCache?: Map<string, boolean>;
realpathCache?: Map<string, string>;
}

export interface CacheableHost extends HostMayBeCacheable {
Expand Down Expand Up @@ -130,39 +131,40 @@ export interface SolutionBuilderWithWatchHost
>,
WatchFactory {
diagnostics: SolutionDiagnostics;
writtenFiles: OutputFile[];
writtenFiles: typescript.OutputFile[];
configFileInfo: Map<FilePathKey, ConfigFileInfo>;
outputAffectingInstanceVersion: Map<FilePathKey, true>;
getInputFileStamp(fileName: string): Date;
updateSolutionBuilderInputFile(fileName: string): void;
getOutputFileKeyFromReferencedProject(
outputFileName: string
): FilePathKey | undefined;
getOutputFileFromReferencedProject(
outputFileName: string
): OutputFile | false | undefined;
getOutputFileAndKeyFromReferencedProject(
oututFileName: string
): { key: FilePathKey; outputFile: OutputFile | false } | undefined;
): { key: FilePathKey; outputFile: string | false } | undefined;
getOutputFileTextAndKeyFromReferencedProject(
oututFileName: string
): { key: FilePathKey; text: string | undefined } | undefined;
getInputFileNameFromOutput(outputFileName: string): string | undefined;
getOutputFilesFromReferencedProjectInput(inputFileName: string): OutputFile[];
getOutputFilesFromReferencedProjectInput(
inputFileName: string
): typescript.OutputFile[];
buildReferences(): void;
ensureAllReferenceTimestamps(): void;
clearCache(): void;
close(): void;
}

export interface ConfigFileInfo {
config: typescript.ParsedCommandLine | undefined;
outputFileNames?: Map<
FilePathKey,
{ inputFileName: string; outputNames: FilePathKey[] }
{ inputFileName: string; outputNames: string[] }
>;
tsbuildInfoFile?: string;
dtsFiles?: string[];
}

export interface OutputFile extends typescript.OutputFile {
time: Date;
version: number;
}

export interface TSInstance {
compiler: typeof typescript;
compilerOptions: typescript.CompilerOptions;
Expand Down

0 comments on commit 95050eb

Please sign in to comment.