enhanced-resolve icon indicating copy to clipboard operation
enhanced-resolve copied to clipboard

feat: add support for win32 paths

Open davakh opened this issue 2 years ago • 13 comments

I implemented general logic for resolving win32 relative paths in library. It's hard to say what else to cover with tests because it's hard to fully mock Node.js's path module and easily switch between win32/posix paths resolving in jest.

If you have thoughts on what else should I cover, I would like to hear about it and I can improve coverage if it's required.

fixes https://github.com/webpack/enhanced-resolve/issues/401

davakh avatar Feb 07 '24 16:02 davakh

CLA Signed

The committers listed above are authorized under a signed CLA.

  • :white_check_mark: login: davakh / name: Danil Vakhrushev (773fe09628b70254bade5cbc5111c1bc50450725, 503ee0ed6f5738daacf291da5bf3f9944144c846, a070b9aba12046662bcb9ff5e9be8a5a6bb1df09)

Codecov Report

Attention: Patch coverage is 61.11111% with 21 lines in your changes missing coverage. Please review.

Project coverage is 92.18%. Comparing base (58464fc) to head (a070b9a). Report is 64 commits behind head on main.

Files with missing lines Patch % Lines
lib/util/path.js 35.48% 15 Missing and 5 partials :warning:
lib/SelfReferencePlugin.js 66.66% 1 Missing :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #402      +/-   ##
==========================================
- Coverage   92.85%   92.18%   -0.67%     
==========================================
  Files          43       44       +1     
  Lines        2042     2085      +43     
  Branches      598      619      +21     
==========================================
+ Hits         1896     1922      +26     
- Misses        118      131      +13     
- Partials       28       32       +4     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Feb 08 '24 10:02 codecov[bot]

Also please fix ts problems, thank you

alexander-akait avatar Feb 08 '24 10:02 alexander-akait

@davakh Hello, friendly ping :star:

alexander-akait avatar Feb 27 '24 16:02 alexander-akait

Hello, sorry that it took so long. In new version, I've added tests and rewritten the original path tests based on the fact that this repository has separate runners for Windows. Also, I'm still not sure what you mean by "real examples" and want to ask for a hint about that, but I've added platform-based tests to the main resolve function, so it should cover more cases.

davakh avatar Mar 06 '24 01:03 davakh

I'll take a look on failed tests

davakh avatar Mar 07 '24 08:03 davakh

It's hard for me to debug on Windows, and it feels like it requires refactoring of almost all existing tests because they're not based on path.sep from the Node.js path package, and all the existing tests are using POSIX-char separators.

I think it would have a greater impact with a lower cost and a lower chance of breaking something in conclusion if we are going to apply something like this path.relative(....).split(path.win32.sep).join(path.posix.sep); at the beginning of resolving path.

It is hard for me to decide because I don't like this solution. If you agree, I can add this solution to codebase, but if you have any other ideas about solving this, I would like to know about it.

davakh avatar Sep 23 '24 05:09 davakh

Yeah, we need refactor our tests

alexander-akait avatar Sep 25 '24 13:09 alexander-akait

I refactored existing tests in forked version, but there are more things to think about:

  1. memfs is partially supporting win32 paths: you can't create C:\ volume files or any absolute win32 path to test it against current tests in enhanced-resolve. So, if we want to correctly run tests for Windows, we should require changes from memfs or switch to another library. This is huge change for existing tests. Shorter: it's impossible to create volume in memfs and write/read with absolute win32 paths
  2. Also, there's an issue with UNC paths that can later be resolved, but rn it feels like developers of node.js just want to keep it like this because many project can relate to this behavior. Related issue: https://github.com/nodejs/node/pull/51513 . It means win32 paths can be referenced to UNC (Universal Naming Convention) paths rather than posix paths because of this concatenation before normalization - two trailing slashed before path should be processed as UNC by the specification of paths. i.e. path.normalize('//./a') # /./a/ but on win32 paths it's path.normalize('\\\\.\\a') # \\\\.\\a\\. Shorter: posix node.js path module can't handle UNC paths, but it handles UNC paths correctly on win32.

Current Node.js behavior with UNC paths:

> path.normalize('\\\\.\\a')
'\\\\.\\a' # Works as expected
> path.normalize('//./a');
'/a' #  Doesn't recognize UNC paths

Possible solutions:

  1. Replace or expand memfs library to use in tests. Maybe use another library exclusively for Windows tests.
  2. This line can be replaced to
winNormalize(`${rootPath}${rootPath === '\\' ? '.\\' : '\\'}${request}\`);

to keep expected behavior - cause it feels more expected behavior to transfer \\\\.\\a -> \\.\\a\\ rather than \\\\a\\ (actual with win32 paths) based on usage of this function in ehanced-resolve library.

Reasoning behind this message: I'm still thinking about how to better resolve all these questions, but right now while I'm thinking about it, it feels like it can be helpful to someone if I let these thoughts exist at least here. Also, maybe i should write it down in issue, but I'm not sure about it...

davakh avatar Oct 20 '24 21:10 davakh

@davakh

Replace or expand memfs library to use in tests. Maybe use another library exclusively for Windows tests.

Maybe we can fake the behavior in places we need it just for testing?

alexander-akait avatar Oct 21 '24 16:10 alexander-akait

Replace or expand memfs library to use in tests. Maybe use another library exclusively for Windows tests.

Maybe we can fake the behavior in places we need it just for testing?

Okay, I dug deeper and with current set of methods required to use by fs in library, memfs works correctly for most cases. We can keep memfs like this with a few changes to the tests.


About current progress: I investigate how Node.js works with exports/imports fields of package.json and how I can apply win32 paths to existing functionality of the library. It's not obvious because it requires from package.json paths to start with posix-slash ./ at least by the Node.js documentation:

All paths defined in the "exports" must be relative file URLs starting with ./.

Because of this requirement to exports/imports fields, I have a lot of thoughts about returning to another option: modify win32 path at the beginning of any library public api and work in the library only with posix slash (/) paths even on Windows because path.win32 also can work with the posix slash.

davakh avatar Oct 21 '24 23:10 davakh

Because of this requirement to exports/imports fields, I have a lot of thoughts about returning to another option: modify win32 path at the beginning of any library public api and work in the library only with posix slash (/) paths even on Windows because path.win32 also can work with the posix slash.

Sounds good for me - less changes in code

alexander-akait avatar Oct 23 '24 16:10 alexander-akait

I think we can solve this - https://github.com/webpack/enhanced-resolve/issues/430 too, using logic above

alexander-akait avatar Oct 23 '24 17:10 alexander-akait

Okay, sorry, I didn't expect for PR to be closed on force-push.. Related pull request: https://github.com/webpack/enhanced-resolve/pull/436

davakh avatar Oct 30 '24 20:10 davakh