Skip to content

Use throwIfNoEntry in tryStatSync to avoid throwing on every missing path - #37

Closed
Sager611 wants to merge 1 commit into
wooorm:mainfrom
Sager611:perf/try-stat-sync-no-throw
Closed

Sager611 wants to merge 1 commit into
wooorm:mainfrom
Sager611:perf/try-stat-sync-no-throw

Conversation

@Sager611

@Sager611 Sager611 commented Oct 8, 2026

Copy link
Copy Markdown

Initial checklist

  • I read the support docs
  • I read the contributing guide
  • I agree to follow the code of conduct
  • I searched issues and couldn't find a duplicate

Description of changes

tryStatSync has a note that throwIfNoEntry: false can be used from Node 15. Every supported Node (the package already uses statSync(url, {throwIfNoEntry: false}) a few lines further down in lib/resolve.js) has it, so this switches tryStatSync to it. Return values are unchanged (undefined for a missing path; other errors are still swallowed by the existing catch).

Why it matters: resolution probes many paths that do not exist (every node_modules/<pkg>/package.json up the tree). Each miss currently allocates an ENOENT error and captures a stack trace just to be thrown away. import-meta-resolve is inlined by mlly, which is bundled by jiti (used by Nuxt, Tailwind, ESLint, pi, ...), so this hits every TypeScript extension/config load there.

Measured:

  • micro benchmark, 200k probes of a missing path, Node 24: 21.6 µs/call (throws) -> 2.1 µs/call with throwIfNoEntry: false.
  • real workload: loading 10 TypeScript extensions through jiti 2.7.0 (which bundles this code): 530 thrown ENOENT stats -> 1; the full 40-extension setup: 2304 -> 27, which is about 50 ms of CPU saved per process start (measured in place, 47-57 ms spent in throwing stats before, 0.4 ms after).

Tests: added a test that a missing package still ends in ERR_MODULE_NOT_FOUND after walking up every node_modules (covers the changed code path). node test/index.js: 4 pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant