Skip to content

Commit 6f5f09d

Browse files
authored
[heft] Add options to only resolve symlinks that are within node_modules (#5011)
* [node-core-library] Add RealNodeModulePathResolver * [heft-typescript] Add onlyResolveSymlinksInNodeModules option * [heft-jest] Add node module symlink resolver * Test resolver * Use features in local-node-rig * Fix duplicate types * Disable CI fail-fast * Pay extra lstat * Fix unit tests --------- Co-authored-by: David Michon <[email protected]>
1 parent b8f1b2b commit 6f5f09d

File tree

21 files changed

+649
-22
lines changed

21 files changed

+649
-22
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
jobs:
1010
build:
1111
strategy:
12+
fail-fast: false
1213
matrix:
1314
include:
1415
- NodeVersion: 18.18.x

build-tests/heft-webpack5-everything-test/config/jest.config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
"coverageReporters": ["cobertura", "html"],
88

99
// Use v8 coverage provider to avoid Babel
10-
"coverageProvider": "v8"
10+
"coverageProvider": "v8",
11+
"resolver": "@rushstack/heft-jest-plugin/lib/exports/jest-node-modules-symlink-resolver"
1112
}

build-tests/heft-webpack5-everything-test/config/typescript.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,7 @@
4949
// "excludeGlobs": [
5050
// "some/path/*.css"
5151
// ]
52-
}
52+
},
53+
54+
"onlyResolveSymlinksInNodeModules": true
5355
}
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-jest-plugin",
5+
"comment": "Add a custom resolver that only resolves symlinks that are within node_modules.",
6+
"type": "minor"
7+
}
8+
],
9+
"packageName": "@rushstack/heft-jest-plugin"
10+
}
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-typescript-plugin",
5+
"comment": "Add \"onlyResolveSymlinksInNodeModules\" option to improve performance for typical repository layouts.",
6+
"type": "minor"
7+
}
8+
],
9+
"packageName": "@rushstack/heft-typescript-plugin"
10+
}
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/node-core-library",
5+
"comment": "Add `RealNodeModulePathResolver` class to get equivalent behavior to `realpath` with fewer system calls (and therefore higher performance) in the typical scenario where the only symlinks in the repository are inside of `node_modules` folders and are links to package folders.",
6+
"type": "minor"
7+
}
8+
],
9+
"packageName": "@rushstack/node-core-library"
10+
}

common/config/rush/nonbrowser-approved-packages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@
230230
"name": "@rushstack/package-extractor",
231231
"allowedCategories": [ "libraries", "vscode-extensions" ]
232232
},
233+
{
234+
"name": "@rushstack/real-node-module-path",
235+
"allowedCategories": [ "libraries" ]
236+
},
233237
{
234238
"name": "@rushstack/rig-package",
235239
"allowedCategories": [ "libraries" ]

common/reviews/api/heft-typescript-plugin.api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export interface ITypeScriptConfigurationJson {
5555
buildProjectReferences?: boolean;
5656
emitCjsExtensionForCommonJS?: boolean | undefined;
5757
emitMjsExtensionForESModule?: boolean | undefined;
58+
onlyResolveSymlinksInNodeModules?: boolean;
5859
// (undocumented)
5960
project?: string;
6061
staticAssetsToCopy?: IStaticAssetsCopyConfiguration;

common/reviews/api/node-core-library.api.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
/// <reference types="node" />
88

99
import * as child_process from 'child_process';
10-
import * as fs from 'fs';
10+
import * as nodeFs from 'fs';
11+
import * as nodePath from 'path';
1112

1213
// @public
1314
export enum AlreadyExistsBehavior {
@@ -213,7 +214,7 @@ export type FileSystemCopyFilesAsyncFilter = (sourcePath: string, destinationPat
213214
export type FileSystemCopyFilesFilter = (sourcePath: string, destinationPath: string) => boolean;
214215

215216
// @public
216-
export type FileSystemStats = fs.Stats;
217+
export type FileSystemStats = nodeFs.Stats;
217218

218219
// @public
219220
export class FileWriter {
@@ -231,7 +232,7 @@ export const FolderConstants: {
231232
};
232233

233234
// @public
234-
export type FolderItem = fs.Dirent;
235+
export type FolderItem = nodeFs.Dirent;
235236

236237
// @public
237238
export interface IAsyncParallelismOptions {
@@ -605,6 +606,14 @@ export interface IReadLinesFromIterableOptions {
605606
ignoreEmptyLines?: boolean;
606607
}
607608

609+
// @public
610+
export interface IRealNodeModulePathResolverOptions {
611+
// (undocumented)
612+
fs: Pick<typeof nodeFs, 'lstatSync' | 'readlinkSync'>;
613+
// (undocumented)
614+
path: Pick<typeof nodePath, 'isAbsolute' | 'normalize' | 'resolve' | 'sep'>;
615+
}
616+
608617
// @public (undocumented)
609618
export interface IRunWithRetriesOptions<TResult> {
610619
// (undocumented)
@@ -834,6 +843,13 @@ export class ProtectableMap<K, V> {
834843
get size(): number;
835844
}
836845

846+
// @public
847+
export class RealNodeModulePathResolver {
848+
constructor(options?: IRealNodeModulePathResolverOptions);
849+
clearCache(): void;
850+
readonly realNodeModulePath: (input: string) => string;
851+
}
852+
837853
// @public
838854
export class Sort {
839855
static compareByValue(x: any, y: any): number;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## API Report File for "@rushstack/real-node-module-path"
2+
3+
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4+
5+
```ts
6+
7+
/// <reference types="node" />
8+
9+
// @public
10+
export function clearCache(): void;
11+
12+
// @public
13+
export const realNodeModulePath: (input: string) => string;
14+
15+
// (No @packageDocumentation comment for this package)
16+
17+
```

0 commit comments

Comments
 (0)