Skip to content

Commit 4ef999a

Browse files
authored
[heft-swc] Reduce set of watched folders (#5295)
* [heft-swc] Fix watch infinite loop * Adjust normalization * Use enum value --------- Co-authored-by: David Michon <[email protected]>
1 parent 25c9267 commit 4ef999a

File tree

2 files changed

+41
-63
lines changed

2 files changed

+41
-63
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@rushstack/heft-isolated-typescript-transpile-plugin",
5+
"comment": "Manually process wildcard directories for watching instead of watching all read directories.",
6+
"type": "patch"
7+
}
8+
],
9+
"packageName": "@rushstack/heft-isolated-typescript-transpile-plugin"
10+
}

heft-plugins/heft-isolated-typescript-transpile-plugin/src/SwcIsolatedTranspilePlugin.ts

Lines changed: 31 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22
// See LICENSE in the project root for license information.
33

4-
import type { Dirent, Stats } from 'node:fs';
4+
import type { Dirent } from 'node:fs';
55
import path from 'node:path';
66
import { type ChildProcess, fork } from 'node:child_process';
77

@@ -159,68 +159,6 @@ async function transpileProjectAsync(
159159
});
160160
const { ts } = tool;
161161

162-
if (getWatchFs) {
163-
const watchFs: IWatchFileSystem = getWatchFs();
164-
const { system } = tool;
165-
const emptyFileSystemEntries: { files: string[]; directories: string[] } = { files: [], directories: [] };
166-
// Copied from TypeScript, but using the watch file system
167-
function getAccessibleFileSystemEntries(directory: string): { files: string[]; directories: string[] } {
168-
try {
169-
const entries: Dirent[] = watchFs.readdirSync(directory || '.', { withFileTypes: true });
170-
const files: string[] = [];
171-
const directories: string[] = [];
172-
for (const dirent of entries) {
173-
const entry: string = dirent.name;
174-
if (entry === '.' || entry === '..') {
175-
continue;
176-
}
177-
let stat: Stats | Dirent | undefined;
178-
if (dirent.isSymbolicLink()) {
179-
const name: string = ts.combinePaths(directory, entry);
180-
stat = watchFs.statSync(name);
181-
if (!stat) {
182-
continue;
183-
}
184-
} else {
185-
stat = dirent;
186-
}
187-
188-
if (stat.isFile()) {
189-
files.push(entry);
190-
} else if (stat.isDirectory()) {
191-
directories.push(entry);
192-
}
193-
}
194-
files.sort();
195-
directories.sort();
196-
return { files, directories };
197-
} catch {
198-
return emptyFileSystemEntries;
199-
}
200-
}
201-
202-
system.readDirectory = (
203-
dirPath: string,
204-
extensions?: string[],
205-
excludes?: string[],
206-
includes?: string[],
207-
depth?: number
208-
): string[] => {
209-
return ts.matchFiles(
210-
dirPath,
211-
extensions,
212-
excludes,
213-
includes,
214-
system.useCaseSensitiveFileNames,
215-
buildFolderPath,
216-
depth,
217-
getAccessibleFileSystemEntries,
218-
system.realpath!,
219-
system.directoryExists
220-
);
221-
};
222-
}
223-
224162
const tsconfigPath: string = getTsconfigFilePath(heftConfiguration, pluginOptions.tsConfigPath);
225163
const parsedTsConfig: TTypeScript.ParsedCommandLine | undefined = loadTsconfig({ tool, tsconfigPath });
226164

@@ -229,6 +167,36 @@ async function transpileProjectAsync(
229167
return;
230168
}
231169

170+
if (getWatchFs && parsedTsConfig.wildcardDirectories) {
171+
// If the tsconfig has wildcard directories, we need to ensure that they are watched for file changes.
172+
const directoryQueue: Map<string, boolean> = new Map();
173+
for (const [wildcardDirectory, type] of Object.entries(parsedTsConfig.wildcardDirectories)) {
174+
directoryQueue.set(path.normalize(wildcardDirectory), type === ts.WatchDirectoryFlags.Recursive);
175+
}
176+
177+
if (directoryQueue.size > 0) {
178+
const watchFs: IWatchFileSystem = getWatchFs();
179+
180+
for (const [wildcardDirectory, isRecursive] of directoryQueue) {
181+
const dirents: Dirent[] = watchFs.readdirSync(wildcardDirectory, {
182+
withFileTypes: true
183+
});
184+
185+
if (isRecursive) {
186+
for (const dirent of dirents) {
187+
if (dirent.isDirectory()) {
188+
// Using path.join because we want platform-normalized paths.
189+
const absoluteDirentPath: string = path.join(wildcardDirectory, dirent.name);
190+
directoryQueue.set(absoluteDirentPath, true);
191+
}
192+
}
193+
}
194+
}
195+
196+
logger.terminal.writeDebugLine(`Watching for changes in ${directoryQueue.size} directories`);
197+
}
198+
}
199+
232200
if (emitKinds.length < 1) {
233201
throw new Error(
234202
'One or more emit kinds must be specified in the plugin options. To disable SWC transpilation, ' +

0 commit comments

Comments
 (0)