Skip to content

Fix resolver.blockList: [] hiding every file - #2227

Open
0z5a wants to merge 1 commit into
react:mainfrom
0z5a:fix/empty-blocklist
Open

0z5a wants to merge 1 commit into
react:mainfrom
0z5a:fix/empty-blocklist

Conversation

@0z5a

@0z5a 0z5a commented Nov 14, 2026

Copy link
Copy Markdown

Summary

flattenBlockList turns a blockList array into a single RegExp by joining the sources of its patterns with |. For an empty array the result is new RegExp(''), which matches every string. metro-file-map then adds its VCS directory pattern ((?:)|[/\\]\.(git|hg)[/\\]), and that still matches every path. So resolver: {blockList: []} gives an empty file map, and the first build fails with Failed to get the SHA-1 for: <projectRoot>/index.js.

The docs say setting blockList replaces the default, so an empty list should mean that nothing is blocked. Server-test.js already uses blockList: [] that way; it only passes because it mocks DependencyGraph. The existing regexes[0]?.flags ?? '' shows that an empty array was expected here.

This returns a pattern that never matches (/.^/, the same one resolver-test.js uses) for an empty array. Non-empty arrays and single RegExps are unchanged.

Changelog: [Fix] resolver.blockList: [] no longer hides every file from Metro

Test plan

I added a blockList config param block to packages/metro/src/DeltaBundler/__tests__/resolver-test.js. It builds a real DependencyGraph on the in-memory fs (linux and win32):

  • a blockList array hides a matching file and leaves the others resolvable (passes before and after; it's a control)
  • an empty blockList array hides nothing (fails before this change, passes after)
$ yarn jest packages/metro/src/DeltaBundler/__tests__/resolver-test.js -t 'blockList config param'

Before:

      ✓ hides files matching a pattern in a blockList array
      ✕ does not hide any file with an empty blockList array
      ✓ hides files matching a pattern in a blockList array
      ✕ does not hide any file with an empty blockList array
    Unable to resolve module ./a from C:\root\index.js:
    None of these files exist: ...
Tests:       2 failed, 262 skipped, 2 passed, 266 total

After:

      ✓ hides files matching a pattern in a blockList array
      ✓ does not hide any file with an empty blockList array
      ✓ hides files matching a pattern in a blockList array
      ✓ does not hide any file with an empty blockList array
Tests:       262 skipped, 4 passed, 266 total

Other checks:

$ yarn jest packages/metro/src/DeltaBundler/__tests__/resolver-test.js packages/metro/src/node-haste packages/metro/src/Server/__tests__/Server-test.js packages/metro-config packages/metro-file-map
Test Suites: 44 passed, 44 total
Tests:       13 skipped, 1278 passed, 1291 total
$ yarn flow check
No errors!
$ yarn eslint <changed files>   # clean
$ yarn prettier --check <changed files>   # clean

I also checked it end to end with Metro.runBuild on a two-file project. With blockList: [] the build failed with Failed to get the SHA-1 for: .../index.js before this change. After it, the bundle builds and runs, and the default, a one-pattern array and a single RegExp give the same results as before.

This change was drafted with Claude Code (claude-opus-5-5); the test results above are from the runs described.

flattenBlockList joined no patterns into new RegExp(''), which matches
every path, so an empty blockList array produced an empty file map.
Return a pattern that never matches for an empty array.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 14, 2026
@github-actions

Copy link
Copy Markdown

Metro review: Looks good

Risk: low · Commit: 1f9e4bf · 4 commands run, in a restricted sandbox after an automated safety assessment

With resolver.blockList: [], flattenBlockList used to build new RegExp(''), which matches every path, so the file map came out empty. This PR returns a never-matching /.^/ for an empty array instead. The fix is correct and minimal: non-empty arrays and single RegExps take the same code path as before. metro-file-map still appends its VCS-directory pattern to /.^/ as intended. The new test fails on the base and passes on the head.

No findings.

Verified
  • ✅ yarn jest --no-watchman packages/metro/src/DeltaBundler/__tests__/resolver-test.js packages/metro/src/node-haste (head) — 5 suites, 276 tests passed
  • ✅ yarn jest --no-watchman packages/metro/src/DeltaBundler/__tests__/resolver-test.js -t 'blockList config param' (base code with the PR's test file copied in) (failed as expected) — Fails on base: the empty-blockList test fails on both platforms and the array control passes, as the description says
  • ✅ yarn eslint packages/metro/src/node-haste/DependencyGraph/createFileMap.js packages/metro/src/DeltaBundler/__tests__/resolver-test.js
  • ✅ node -e (builds metro-file-map's combined ignorePattern from /.^/ plus VCS_DIRECTORIES and tests it on paths) — A regular file is not ignored; /.git/ and .hg\ paths are still ignored

Not run: No benchmark: the change only runs once at file map construction, and only for an empty array, so it can't plausibly affect cost. I didn't run yarn typecheck. The function's inferred return type is still RegExp, and the description reports a clean Flow run. The file map cache key changes only for configs with an empty blockList, which invalidates their previously broken, empty cache. That's desirable. No Windows run: separators don't matter to this logic, and the new test already runs under the win32 mock fs.

Automated review by Claude. Advisory only: it never approves or blocks, and a maintainer makes the call.

This branch has not been deployed

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

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant