diff --git a/CHANGELOG.md b/CHANGELOG.md index a6b1d88a6a8d..7bd83a409090 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ ### Performance +- `[jest-resolve]` Skip expensive error creation on not found stat calls. [#11749](https://github.com/facebook/jest/pull/11749) + ## 27.0.7 ### Chore & Maintenance diff --git a/packages/jest-resolve/src/__tests__/resolve.test.ts b/packages/jest-resolve/src/__tests__/resolve.test.ts index 2f2f56501429..dff81f7e5aa7 100644 --- a/packages/jest-resolve/src/__tests__/resolve.test.ts +++ b/packages/jest-resolve/src/__tests__/resolve.test.ts @@ -11,7 +11,7 @@ import * as fs from 'graceful-fs'; import {sync as resolveSync} from 'resolve'; import {ModuleMap} from 'jest-haste-map'; import userResolver from '../__mocks__/userResolver'; -import defaultResolver from '../defaultResolver'; +import defaultResolver, {ResolverOptions} from '../defaultResolver'; import nodeModulesPaths from '../nodeModulesPaths'; import Resolver from '../resolver'; import type {ResolverConfig} from '../types'; @@ -323,3 +323,11 @@ describe('Resolver.getModulePaths() -> nodeModulesPaths()', () => { expect(dirs_actual).toEqual(expect.arrayContaining(dirs_expected)); }); }); + +describe('defaultResolver', () => { + it('does not change outwardly stackTraceLimit', () => { + const oldStackTraceValue = Error.stackTraceLimit; + expect(() => defaultResolver('test', {} as ResolverOptions)).toThrow(); + expect(oldStackTraceValue).toBe(Error.stackTraceLimit); + }); +}); diff --git a/packages/jest-resolve/src/defaultResolver.ts b/packages/jest-resolve/src/defaultResolver.ts index 7b3dfe17a3bd..a2cbc30d4449 100644 --- a/packages/jest-resolve/src/defaultResolver.ts +++ b/packages/jest-resolve/src/defaultResolver.ts @@ -11,7 +11,7 @@ import {sync as resolveSync} from 'resolve'; import type {Config} from '@jest/types'; import {tryRealpath} from 'jest-util'; -type ResolverOptions = { +export type ResolverOptions = { basedir: Config.Path; browser?: boolean; defaultResolver: typeof defaultResolver; @@ -78,12 +78,21 @@ function statSyncCached(path: string): IPathType { } let stat; + const oldTrace = Object.getOwnPropertyDescriptors(Error).stackTraceLimit; try { + if(oldTrace.writable) { + Object.defineProperty(Error, 'stackTraceLimit', { + value: 0, + writable: false, + }); + } stat = fs.statSync(path); } catch (e) { if (!(e && (e.code === 'ENOENT' || e.code === 'ENOTDIR'))) { throw e; } + } finally { + Object.defineProperty(Error, 'stackTraceLimit', oldTrace); } if (stat) {