Thanks to visit codestin.com
Credit goes to github.com

Skip to content

chore(haste-map): replace walker and hand-rolled traversal with fdir#16187

Merged
SimenB merged 16 commits into
jestjs:mainfrom
SimenB:fdir-replacement
May 16, 2026
Merged

chore(haste-map): replace walker and hand-rolled traversal with fdir#16187
SimenB merged 16 commits into
jestjs:mainfrom
SimenB:fdir-replacement

Conversation

@SimenB
Copy link
Copy Markdown
Member

@SimenB SimenB commented May 16, 2026

Summary

jest-haste-map has two hand-rolled directory walkers:

  • crawlers/node.ts — a recursive fs.readdir loop with a manual activeCalls counter, used as the JS fallback when find(1) is unavailable or forceNodeFilesystemAPI is set.
  • watchers/common.js recReaddir and FSEventsWatcher.ts — both wrap the walker npm dep to enumerate the initial file tree at watcher startup.

Both walk a tree and lstat each entry. This PR replaces them with a single shared helper at lib/walk.ts, backed by fdir.

fdir fans readdir calls out across libuv's threadpool natively. The lstat phase uses a bounded callback pool (no Promise-per-file overhead) — the pool size defaults to Math.max(os.availableParallelism() * 4, 32) so the threadpool stays saturated on large trees without queuing all callbacks at once.

What's unchanged:

  • findNative (the find(1) shell-out in crawlers/node.ts) — still the fastest path on large POSIX trees; still gated behind hasNativeFindSupport.
  • forceNodeFilesystemAPI — still functional; now forces the fdir path instead of the old fs.readdir recursion.
  • WatchmanWatcher and the watchman crawler — untouched.

Test plan

yarn build:js
yarn jest packages/jest-haste-map   # 154 tests, all pass
yarn typecheck:tests
yarn lint
yarn check-changelog
yarn constraints
yarn dedupe --check

SimenB added 5 commits May 16, 2026 13:56
Introduces a shared `lib/walk.ts` that replaces the two hand-rolled
directory walkers in jest-haste-map:

- `crawlers/node.ts` `find()` — recursive readdir with activeCalls counter
- `watchers/common.js` `recReaddir` — wraps the `walker` npm dep

Both walk a tree and stat per entry. `walk` uses fdir's async crawl
(which fans readdir out across libuv's threadpool) plus a bounded
callback-based lstat pool (fdir's `.withCallback()` API, keeping all
internals callback-driven with a single Promise at the outer boundary)
that avoids Promise-per-file overhead on million-file trees.

Call sites are converted in follow-up commits.
Replace the hand-rolled fs.readdir recursive walker in crawlers/node.ts
with the new lib/walk helper. The find(1) shell-out path (findNative) is
unchanged; only the JS fallback path (used when find is unavailable or
forceNodeFilesystemAPI is true) is replaced.
Replace `walker` npm dep usage in `watchers/common.js` and the
private `recReaddir` in `FSEventsWatcher.ts` with the shared
`lib/walk` helper.
- Fix "This options" → "This option" in enableSymlinks JSDoc (jest-types,
  jest-schemas, docs)
- Fix inaccurate test comment in watchers/__tests__/index.test.ts — the
  ready-timeout is what triggers the rejection, not monkey-patching
- Delete unused WatcherBackend union from watchers/types.ts
- Add test for shouldUseWatchman(true) when isWatchmanInstalled() returns false
- Fix README: forceNodeFilesystemAPI, hasteImplModulePath, hasteMapModulePath,
  skipPackageJson, throwOnModuleCollision are all optional with sane defaults
- Note: HasteMapOptions.watchman is intentionally required (breaking change
  from the PR 16186 rewrite; callers must be explicit)
Copilot AI review requested due to automatic review settings May 16, 2026 11:57
@netlify
Copy link
Copy Markdown

netlify Bot commented May 16, 2026

Deploy Preview for jestjs ready!

Name Link
🔨 Latest commit 57c19e7
🔍 Latest deploy log https://app.netlify.com/projects/jestjs/deploys/6a08a1a6ae0a0e00082812f8
😎 Deploy Preview https://deploy-preview-16187--jestjs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Replaces jest-haste-map's hand-rolled directory walkers (the recursive fs.readdir loop in crawlers/node.ts and the walker npm dep used by FSEventsWatcher startup and watchers/common.js recReaddir) with a single shared helper at lib/walk.ts backed by fdir. The walker dependency is dropped from the package.

Changes:

  • New lib/walk.ts wraps fdir.crawl().withCallback() with a bounded callback-driven lstat pool and exposes a small walk(opts, done) API; covered by a new walk.test.ts.
  • crawlers/node.ts find and watchers/{FSEventsWatcher,common.js} switch to walk; findNative is simplified.
  • Misc cleanup: drops unused WatcherBackend type, fixes "This options" typo in three places, expands README defaults, adds CHANGELOG entry and updates CLAUDE.md.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/jest-haste-map/src/lib/walk.ts New fdir-backed walker with bounded lstat pool.
packages/jest-haste-map/src/lib/tests/walk.test.ts Tests for the new helper.
packages/jest-haste-map/src/crawlers/node.ts Rewrites find on top of walk; drops enableSymlinks plumbing and simplifies findNative.
packages/jest-haste-map/src/crawlers/tests/node.test.js Adjusts the graceful-fs mock for fdir (adds isFile, readdirSync, realpath, trailing-slash normalization).
packages/jest-haste-map/src/watchers/FSEventsWatcher.ts Replaces walker-based startup walk with walk; drops local recReaddir/normalizeProxy.
packages/jest-haste-map/src/watchers/common.js recReaddir now uses walk.
packages/jest-haste-map/src/watchers/types.ts Removes unused WatcherBackend export.
packages/jest-haste-map/src/watchers/tests/index.test.ts Tightens shouldUseWatchman tests; clarifies a comment.
packages/jest-haste-map/package.json Adds fdir, removes walker.
packages/jest-haste-map/README.md Marks several options as not required and documents defaults.
packages/jest-haste-map/CLAUDE.md Documents lib/walk.ts and updates crawler/watcher notes.
packages/jest-types/src/Config.ts, packages/jest-schemas/src/raw-types.ts, docs/Configuration.md Fixes "This options" → "This option" typo.
yarn.lock Reflects added fdir and dropped walker resolutions.
CHANGELOG.md Adds entry under Chore & Maintenance.

Comment thread packages/jest-haste-map/src/crawlers/node.ts Outdated
Comment thread packages/jest-haste-map/src/crawlers/node.ts
Comment thread packages/jest-haste-map/CLAUDE.md Outdated
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 16, 2026

Open in StackBlitz

babel-jest

npm i https://pkg.pr.new/babel-jest@16187

babel-plugin-jest-hoist

npm i https://pkg.pr.new/babel-plugin-jest-hoist@16187

babel-preset-jest

npm i https://pkg.pr.new/babel-preset-jest@16187

create-jest

npm i https://pkg.pr.new/create-jest@16187

@jest/diff-sequences

npm i https://pkg.pr.new/@jest/diff-sequences@16187

expect

npm i https://pkg.pr.new/expect@16187

@jest/expect-utils

npm i https://pkg.pr.new/@jest/expect-utils@16187

jest

npm i https://pkg.pr.new/jest@16187

jest-changed-files

npm i https://pkg.pr.new/jest-changed-files@16187

jest-circus

npm i https://pkg.pr.new/jest-circus@16187

jest-cli

npm i https://pkg.pr.new/jest-cli@16187

jest-config

npm i https://pkg.pr.new/jest-config@16187

@jest/console

npm i https://pkg.pr.new/@jest/console@16187

@jest/core

npm i https://pkg.pr.new/@jest/core@16187

@jest/create-cache-key-function

npm i https://pkg.pr.new/@jest/create-cache-key-function@16187

jest-diff

npm i https://pkg.pr.new/jest-diff@16187

jest-docblock

npm i https://pkg.pr.new/jest-docblock@16187

jest-each

npm i https://pkg.pr.new/jest-each@16187

@jest/environment

npm i https://pkg.pr.new/@jest/environment@16187

jest-environment-jsdom

npm i https://pkg.pr.new/jest-environment-jsdom@16187

@jest/environment-jsdom-abstract

npm i https://pkg.pr.new/@jest/environment-jsdom-abstract@16187

jest-environment-node

npm i https://pkg.pr.new/jest-environment-node@16187

@jest/expect

npm i https://pkg.pr.new/@jest/expect@16187

@jest/fake-timers

npm i https://pkg.pr.new/@jest/fake-timers@16187

@jest/get-type

npm i https://pkg.pr.new/@jest/get-type@16187

@jest/globals

npm i https://pkg.pr.new/@jest/globals@16187

jest-haste-map

npm i https://pkg.pr.new/jest-haste-map@16187

jest-jasmine2

npm i https://pkg.pr.new/jest-jasmine2@16187

jest-leak-detector

npm i https://pkg.pr.new/jest-leak-detector@16187

jest-matcher-utils

npm i https://pkg.pr.new/jest-matcher-utils@16187

jest-message-util

npm i https://pkg.pr.new/jest-message-util@16187

jest-mock

npm i https://pkg.pr.new/jest-mock@16187

@jest/pattern

npm i https://pkg.pr.new/@jest/pattern@16187

jest-phabricator

npm i https://pkg.pr.new/jest-phabricator@16187

jest-regex-util

npm i https://pkg.pr.new/jest-regex-util@16187

@jest/reporters

npm i https://pkg.pr.new/@jest/reporters@16187

jest-resolve

npm i https://pkg.pr.new/jest-resolve@16187

jest-resolve-dependencies

npm i https://pkg.pr.new/jest-resolve-dependencies@16187

jest-runner

npm i https://pkg.pr.new/jest-runner@16187

jest-runtime

npm i https://pkg.pr.new/jest-runtime@16187

@jest/schemas

npm i https://pkg.pr.new/@jest/schemas@16187

jest-snapshot

npm i https://pkg.pr.new/jest-snapshot@16187

@jest/snapshot-utils

npm i https://pkg.pr.new/@jest/snapshot-utils@16187

@jest/source-map

npm i https://pkg.pr.new/@jest/source-map@16187

@jest/test-result

npm i https://pkg.pr.new/@jest/test-result@16187

@jest/test-sequencer

npm i https://pkg.pr.new/@jest/test-sequencer@16187

@jest/transform

npm i https://pkg.pr.new/@jest/transform@16187

@jest/types

npm i https://pkg.pr.new/@jest/types@16187

jest-util

npm i https://pkg.pr.new/jest-util@16187

jest-validate

npm i https://pkg.pr.new/jest-validate@16187

jest-watcher

npm i https://pkg.pr.new/jest-watcher@16187

jest-worker

npm i https://pkg.pr.new/jest-worker@16187

pretty-format

npm i https://pkg.pr.new/pretty-format@16187

commit: 57c19e7

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 2 comments.

Comment thread packages/jest-haste-map/src/watchers/FSEventsWatcher.ts
Comment thread packages/jest-haste-map/src/crawlers/node.ts Outdated
Comment thread packages/jest-haste-map/src/crawlers/node.ts Outdated
Comment thread packages/jest-haste-map/src/crawlers/node.ts Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.

Comment thread packages/jest-haste-map/src/crawlers/node.ts Outdated
Comment thread packages/jest-haste-map/CLAUDE.md Outdated
Comment thread packages/jest-haste-map/src/lib/walk.ts Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.

Comment thread packages/jest-haste-map/src/lib/__tests__/walk.test.ts
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated no new comments.

@SimenB SimenB merged commit d6cdf48 into jestjs:main May 16, 2026
90 checks passed
@SimenB SimenB deleted the fdir-replacement branch May 16, 2026 17:25
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.

2 participants