feat: add support for win32 paths
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
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.
Also please fix ts problems, thank you
@davakh Hello, friendly ping :star:
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.
I'll take a look on failed tests
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.
Yeah, we need refactor our tests
I refactored existing tests in forked version, but there are more things to think about:
-
memfsis partially supporting win32 paths: you can't createC:\volume files or any absolute win32 path to test it against current tests inenhanced-resolve. So, if we want to correctly run tests for Windows, we should require changes frommemfsor switch to another library. This is huge change for existing tests. Shorter: it's impossible to create volume inmemfsand write/read with absolute win32 paths - 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'spath.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:
- Replace or expand
memfslibrary to use in tests. Maybe use another library exclusively for Windows tests. - 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
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?
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.
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
I think we can solve this - https://github.com/webpack/enhanced-resolve/issues/430 too, using logic above
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