-
Notifications
You must be signed in to change notification settings - Fork 7.3k
path.join() changes casing of drive letter starting with 0.11.0 #7031
Comments
Changed the behaviour of normalize which is used by join: https://github.com/joyent/node/blob/b9bec2031e5f44f47cf01c3ec466ab8cddfa94f6/lib/path.js#L243 |
Modules should be using |
I crushed into the same problem with another plugin I used. Can you explain why the result of I know nothing of the implementation details of the path library, so from a users perspective it seems to me kinda odd, to handle the results (within one library) differently. Thanks for clarification! |
I have tried a similar .NET Framework methods to see whether they are updating the drive letter to a lower cap on Windows, but they didn't. I don't see a technical necessity behind this update. |
Thanks for your effort, but if this is an answer to my question, I did not grasp it. Sorry. Why are the results handled differently? |
I agree with you on consistency. IMHO I don't see the reason for a normalization that way, especially forcing drive letters to lowercase on Windows. Perhaps, there is a historical reason for that patch or simply not well considered on the bigger picture. |
This change also broke our code which _require_s some files using their full path: require(path.join(__dirname, 'other.js')); It works fine as long as the _require_d module wasn't already loaded using a relative path. But as soon as the newly loaded module _require_s other modules it loads all of them using a different case for the drive letter and thus all of them are loaded twice. Simple test case: console.log('Executing:', __filename);
var path = require('path');
require(__filename);
require(path.join(__filename)); The module _require_s itself which shouldn't do much. The first Expected output:
Actual output:
The module is loaded twice. D'oh. |
There is also a side effect with VM functions, in this case as you said you will obtain multiple copies in Module._cache, once you have joined or normalize the path via vm.runInNewContext(fs.readFileSync(... path.normalize(...), ..)) You will have multiple entries in Modules._cache for the same modules if you use relative paths, because the __dirname of the parent has now the drive letter in lowercase My 2 cents |
same issue. Some modules are loaded twice. |
I also ran into an issue with some modules loading more than once, leading to all sorts of issues. |
same issue.. provokes all kind of funny situations when using things like require-all, etc. We have currently a small workaround in place that enables us to continue for the moment. (disclaimer: hackish temporary solution, here be dragons, don't use it, etc.) |
@indutny ?? |
@zxc122333 ?? |
As fluidsonic said, the file will be loaded twice when I load it with
Is it a bug in node? Or I should use bschuedzig's patch? p.s. v0.11.13 has the same problem |
@create-renegr @obastemur I suppose, although documentation doesn't mention it, the toLowercase() change is to ensure a univocal representation of the given path on Windows (kind of What the documentation mentions is that for
|
From the Windows and it's frameworks point, there is no such functionality. (check .NET Framework's similar methods) All due respect to reasoning behind windows-drive-letter-case-update, IMHO changing one part of the entire framework to act like this has no sense. I had asked the reasoning to the owner of this commit months ago but no answer so far. |
AFAIK: windows itself ignores casing for file/directory access. It will create a file with the casing you desire, but you can access it after that no matter how the casing looks like. If you create a "TEST.TXT" it will show up with uppercases after that, but you can access it as "test.txt" or "tEsT.tXt" as well. The very core of windows does not care. Thus you won't be having any direct problems in either .NET or NodeJS. IMHO the "only" problem is that NodeJS stores require'd files in a key/value store, where casing for the key matters. This makes total sense for *NIX platforms, as you might be able to create a "test" and "Test" module side by side and include them separately. There are now many solutions on how to mitigate the problem, one would be at the very core (discussion about path.resolve/path.normalize), another one would be to have special handling for require on windows platforms. And I think, both can make sense (the latter one might be an easy fix for the time being, first one might be cleaner). I just love the whole NodeJS ecosystem and all the hard work that went into that from a lot of people. It would be very sad to have many "false errors" reported on all different kind of modules from programmers on windows platforms who encounter weird results (for example require-all). The effects are very misleading (I remember the time it took me to understand the behavior). |
- Calling resolve() doesn't fully normalize relative path on Windows (in Node v0.11.x, see nodejs/node-v0.x-archive#7031 ), i.e. doesn't lowercase drive letter, while normalize() does, which causes paths resulting from calling normalize() and join() (depending on normalize()) to differ and to break comparisons. Fixes cloudhead#42.
Calling `resolve()` on Windows (in Node v0.11.0+) result in a path where drive letter case isn't always lowercase (e.g. for a relative path like '.') while `normalize()` always returns a path with a lower case drive letter. This eventually breaks comparisons between results of `resolve()` and `join()` (which relies on `normalize()`) for the same path. Fixes nodejs#7031
This commit fixes an issue where the SDK would not correctly load with `require("aws-sdk")` on a Windows machine running Node.js 0.11.x. This error is caused by the following two behavioral changes in Node.js: * nodejs/node-v0.x-archive#6829 * nodejs/node-v0.x-archive#7031 In essence, Node.js `require()` calls return different objects for differently cased filenames, even on case-insensitive file systems. This, coupled with the fact that `path.join()` lowercases the drive letter in the path, causes the SDK to try to load core.js two separate times, creating two objects that do not have the correct properties attached. See #303 for more information.
That's only a half-truth. It's not a question of OS but file system. It so happens that the default NTFS configuration is to be case-insensitive and default ext4 & similar config is to be case-sensitive. OS X's HFS+ is case-insensitive be default as Windows. But you can mount a case-sensitive NTFS etc. Node should still work in such scenario which means Node should store things in a case-sensitive way when needed. |
@mzgol, interesting.. never heard of that. thanks for clarifying 👍 |
When adding a new module to the cache, and also when querying the cache, normalize the path so that modules don't get loaded more than once when they are referenced by the same filename but with different case. Fixes nodejs#7031.
When adding a new module to the cache, and also when querying the cache, normalize the path so that modules don't get loaded more than once when they are referenced by the same filename but with different case. Fixes nodejs#7031.
When adding a new module to the cache, and also when querying the cache, normalize the path so that modules don't get loaded more than once when they are referenced by the same filename but with different case. Fixes nodejs#7031.
When adding a new module to the cache, and also when querying the cache, normalize the path so that modules don't get loaded more than once when they are referenced by the same filename but with different case. Fixes nodejs#7031.
When adding a new module to the cache, and also when querying the cache, normalize the path so that modules don't get loaded more than once when: - They are referenced by the same filename but with different case for the drive letter on Windows. - They are referenced by two different paths that point to the same file. Fixes nodejs#7031.
I'm having issues with
I've also experienced issues with JSCS due to the drive letter casing inconsistency. What is the plan to fix this? Revert the behavior back to preserving the drive letter? Make all |
The npm piece of this should be fixed in I agree that in general this behavior is confusing; either Node or libuv should deal with taking care of path normalization issues so application developers don't need to be aware of the intricacies of case-folding / case-insensitive filesystems and drive letters. |
In general path functions don't change the case of a path. Making an exception for windows drive letters violates the principle of least surprise. Changing the drive letter case has caused a lot of issues, including nodejs#7031, nodejs#7806 and lots of bikeshedding about whether uppercase is the right case or lowercase. This effectively reverts nodejs/node-v0.x-archive@a05f973 PR-URL: nodejs/node#100
I'm not a node expert but I believe this casing issue on drive letters is really making lots of ink going down with none agreeing with each others. This probably means there is no good solution and thus I upvote reverting a05f973 like @piscisaureus seems to be advising. Not touching the path is far from perfect but at least it won't change the problems we already had because of it (and have mostly found workarounds for) instead of creating new ones and possibly breaking a lot of npm packages we don't know about. |
In general path functions don't change the case of a path. Making an exception for windows drive letters violates the principle of least surprise. Changing the drive letter case has caused a lot of issues, including nodejs#7031, nodejs#7806 and lots of bikeshedding about whether uppercase is the right case or lowercase. This effectively reverts nodejs/node-v0.x-archive@a05f973 PR-URL: nodejs/node#100
In general path functions don't change the case of a path. Making an exception for windows drive letters violates the principle of least surprise. Changing the drive letter case has caused a lot of issues, including nodejs#7031, nodejs#7806 and lots of bikeshedding about whether uppercase is the right case or lowercase. This effectively reverts nodejs/node-v0.x-archive@a05f973 Reviewed-by: Alexis Campailla <[email protected]> Reviewed-by: Julien Gilli <[email protected]>
Running this piece of code on Windows and Node.js 0.10.25 results as shown below.
Code:
Result (Node.js 0.10.25 on Windows 7 Pro x64):
Result running the same code on Node.js 0.11.0 and later on Windows 7 Pro x64:
As you can see, the drive letter now is lower case.
This behavior breaks modules like koa-send when it comes to using joined path instances.
The text was updated successfully, but these errors were encountered: