Skip to content

fix: treat only a whole file: URL as one when parsing a request - #670

Merged
alexander-akait merged 3 commits into
mainfrom
fix/file-url-request-detection
Sep 13, 2026
Merged

alexander-akait merged 3 commits into
mainfrom
fix/file-url-request-detection

Conversation

@alexander-akait

Copy link
Copy Markdown
Member

Summary

parseIdentifier tested for a file URL with an unanchored /file:/i, so any request merely containing file: was handed to fileURLToPath and threw ERR_INVALID_URL: /foo/file:bar.js, ./a/file:b.js, and /tmp/profile:1.js — whose profile: contains file: — all crash resolution today. It now reuses the anchored isFileURL added in #668, so a file: inside a path segment stays part of the path and only a whole file:// URL is converted. That also leaves one definition of "is a file URL" in the codebase instead of two, and reads one character before any regexp runs on this hot path (the old test scanned the whole string).

What kind of change does this PR introduce?

fix.

Did you add tests for your changes?

Yes — test/identifier.test.js gains a file: in a path segment group (the four inputs above, one with a query and fragment) and a file: URLs group pinning what must still convert, percent-encoding and an upper-case scheme included. The four path-segment cases throw without the change.

Does this PR introduce a breaking change?

No — every request that resolved before still resolves; only the ones that threw now work. A single-slash file:/abs/x.js is no longer converted, but nothing produces that form (pathToFileURL and import.meta.resolve() both emit file:///…) and no test covered it.

If relevant, what needs to be documented once your changes are merged or what have you already documented?

n/a

Use of AI

Written with Claude Code. It found the unanchored test while working on #668, reproduced the crash, made the change and the tests, and ran the full lint and test suites locally (1544/1544 green); every claim above was verified by running it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TmnzpSwSysywhmNw9p3uT5


Generated by Claude Code

The test was unanchored, so any request carrying `file:` anywhere went to
`fileURLToPath` and threw `ERR_INVALID_URL` - `/foo/file:bar.js`, and
`/tmp/profile:1.js`, whose `profile:` contains it. It now reuses the
anchored `isFileURL`, which also reads one character before any regexp
runs on this hot path.
@changeset-bot

changeset-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b034a55

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
enhanced-resolve Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov

codecov Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.14%. Comparing base (835c4fe) to head (b034a55).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #670   +/-   ##
=======================================
  Coverage   98.14%   98.14%           
=======================================
  Files          49       49           
  Lines       10042    10046    +4     
=======================================
+ Hits         9856     9860    +4     
  Misses        186      186           
Flag Coverage Δ
integration 98.14% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

A literal `file:///foo/bar.js` names no absolute path on Windows, so
`fileURLToPath` threw there and three cases failed on the Windows runners.
Deriving each input with `pathToFileURL` carries the drive letter, and a
path with a space keeps the percent-encoding the test is for.
@codspeed-hq

codspeed-hq Bot commented Sep 13, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 10.63%

⚡ 1 improved benchmark
✅ 141 untouched benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory node-compare: node require.resolve x 1000 75.8 KB 68.5 KB +10.63%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix/file-url-request-detection (b034a55) with main (835c4fe)

Open in CodSpeed

Node's URL parser normalizes `file:/abs/x.js` to three slashes and
`import()` loads it, but the anchored test wanted two - so that form was
kept as a literal path. It now needs one slash after the scheme, which
still leaves `file:x.js` the relative-looking request it reads as rather
than the `/x.js` Node makes of it.
@alexander-akait
alexander-akait merged commit a00ff09 into main Sep 13, 2026
40 checks passed
@alexander-akait
alexander-akait deleted the fix/file-url-request-detection branch September 13, 2026 11:59
alexander-akait pushed a commit that referenced this pull request Sep 13, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## enhanced-resolve@5.25.1

### Patch Changes

- Read a `file:` URL the way Node does when parsing a request. (by
[@alexander-akait](https://github.com/alexander-akait) in
[#670](#670))

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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