Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On Windows, Node can be inconsistent in what case builtin functions use for drive letters #6624

Closed
thorn0 opened this issue May 6, 2016 · 11 comments
Labels
module Issues and PRs related to the module subsystem. path Issues and PRs related to the path subsystem. windows Issues and PRs related to the Windows platform.

Comments

@thorn0
Copy link

thorn0 commented May 6, 2016

  • Version: 6.0.0
  • Platform: Windows 7 x64
  • Subsystem: path, module, process

When cmd.exe is run via a shortcut that has a lowercase drive letter in its 'Start in' field (e.g. d:\dev) and Node is run from this cmd instance, Node's builtin functions behave in an unexpected way. Some of them return the drive letter in upper case (D:\dev\foo) whereas the other in lower (d:\dev\foo).

test.js:

var exprs = ['__dirname', '__filename', 'require.resolve("./test")', 
    'require("path").resolve("test.js")', 'process.cwd()'];
for (var expr of exprs) {
    console.log(expr, eval(expr));
}

In cmd:

d:\dev\foo>node test
__dirname D:\dev\foo
__filename D:\dev\foo\test.js
require.resolve("./test") D:\dev\foo\test.js
require("path").resolve("test.js") d:\dev\foo\test.js
process.cwd() d:\dev\foo

If I change the case of the drive letter in the "Start in" field of the shortcut for cmd, everything becomes consistent.

D:\dev\foo>node test
__dirname D:\dev\foo
__filename D:\dev\foo\test.js
require.resolve("./test") D:\dev\foo\test.js
require("path").resolve("test.js") D:\dev\foo\test.js
process.cwd() D:\dev\foo

This leads to issues like webpack/webpack#2362.

So what can be done about it?

  1. It'd be great if Node always used upper case.
  2. Also now Node resolves d:\test.js and D:\test.js as two different modules. Should it stay like this?
d:\dev\foo>echo console.log('load')>bar.js
d:\dev\foo>node
> require('d:\\dev\\foo\\bar.js')
load
{}
> require('d:\\dev\\foo\\bar.js')
{}
> require('D:\\dev\\foo\\bar.js')
load
{}
@addaleax addaleax added module Issues and PRs related to the module subsystem. windows Issues and PRs related to the Windows platform. path Issues and PRs related to the path subsystem. labels May 6, 2016
@jhamhader
Copy link
Contributor

#3594 might be part of this issue.

@orangemocha
Copy link
Contributor

  1. It'd great if Node always used upper case.

Node changed behavior a few times in the past. From what I can reacall, what was finally deemed the 'proper' way was to never have Node normalize the drive case. So it could change based on the process current directory, as you noted, but at least it would be consistent everywhere internally.

Are you seeing any place where Node is changing the case and making it different than process.cwd or what was passed in the command line? If so it should be considered a bug, IMO.

Also now Node resolves d:\test.js and D:\test.js as two different modules. Should it stay like this?

I think it shouldn't. See nodejs/node-v0.x-archive#6774. I'll add it to my todo list to revive that.

@thorn0
Copy link
Author

thorn0 commented May 12, 2016

Are you seeing any place where Node is changing the case and making it different than process.cwd or what was passed in the command line?

Yes.

d:\dev\foo>node test
__dirname D:\dev\foo
__filename D:\dev\foo\test.js
require.resolve("./test") D:\dev\foo\test.js
require("path").resolve("test.js") d:\dev\foo\test.js
process.cwd() d:\dev\foo

@Jeff-Lewis
Copy link

Jeff-Lewis commented May 24, 2016

YES

Even when using only relative paths to modules './../myModule', something changes require.resolve from using the uppercase C:\ path of a module initially to use the lowercase c:\ path during the loading of a project.

In our case, from looking at the require.cache order of modules, it switches from "C:\..." to "c:\.." after completing the first cycle of module reference chains. My guess is that it might have something to do when require is resolving circular referencing module chains and starts working on the 2nd and n- number of loops to resolve modules.

When this occurs, it can load some modules twice which we just experienced when cwd() is initially set with an uppercase "C:\..."

*** Edited ***
Removed suggestion about using uppercase drive letters. It's not a good suggestion...

node: v4.4.4
Windows 10

/cc @mousetraps

#3594
nodejs/node-v0.x-archive#6774
nodejs/node-v0.x-archive#7031
nodejs/node-v0.x-archive#8145
nodejs/node-v0.x-archive#7806

@orangemocha
Copy link
Contributor

In cmd:

d:\dev\foo>node test
__dirname D:\dev\foo
__filename D:\dev\foo\test.js
require.resolve("./test") D:\dev\foo\test.js
require("path").resolve("test.js") d:\dev\foo\test.js
process.cwd() d:\dev\foo

This exemplifies the issue very well, thank you!

We could attempt to normalize the casing of __dirname and __filename to match that of process.cwd(). That might have other unwanted side effects though. The real answer is to always make case insensitive path comparisons on Windows.

This is on my queue of fixes.

@RobCannon
Copy link

This is causing issues in webpack. Waiting eagerly for a fix.

bcoe pushed a commit to istanbuljs/nyc that referenced this issue Jul 24, 2016
bzoz added a commit to JaneaSystems/node that referenced this issue Aug 5, 2016
This reverts parts of nodejs@b488b19
restoring javascript implementation of realpath and realpathSync.

Fixes: nodejs#7175
Fixes: nodejs#6861
Fixes: nodejs#7294
Fixes: nodejs#7192
Fixes: nodejs#7044
Fixes: nodejs#6624
Fixes: nodejs#6978
@bzoz bzoz closed this as completed in 08996fd Aug 12, 2016
cjihrig pushed a commit that referenced this issue Aug 15, 2016
This reverts parts of b488b19
restoring javascript implementation of realpath and realpathSync.

Fixes: #7175
Fixes: #6861
Fixes: #7294
Fixes: #7192
Fixes: #7044
Fixes: #6624
Fixes: #6978
PR-URL: #7899
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@thorn0
Copy link
Author

thorn0 commented Aug 29, 2016

So, as of Node 6.4, the case of the drive letter returned by all the builtin functions is consistent and is determined by the case returned by process.cwd().

D:\dev\zzz>node test
__dirname D:\dev\zzz
__filename D:\dev\zzz\test.js
require.resolve("./test") D:\dev\zzz\test.js
require("path").resolve("test.js") D:\dev\zzz\test.js
process.cwd() D:\dev\zzz

D:\dev\zzz>C:

C:\>cd d:\dev\zzz

C:\>d:

d:\dev\zzz>node test
__dirname d:\dev\zzz
__filename d:\dev\zzz\test.js
require.resolve("./test") d:\dev\zzz\test.js
require("path").resolve("test.js") d:\dev\zzz\test.js
process.cwd() d:\dev\zzz

d:\dev\zzz>

Why instead not make it always upper (lower) case? The case returned by process.cwd() is a quasi-random value (see the example above, it depends on just how I typed the cd command). It's effectively never is intentionally chosen. Yet it can unexpectedly change the behaviour of the program.

Also d:\test.js and D:\test.js are still resolved as two different modules.

@usulpro
Copy link

usulpro commented May 7, 2017

To get rid of problems with lowercase drive letter on Windows you can try this https://www.npmjs.com/package/driveup as a hotfix for this issue. It changes the drive letter the UpperCase:

e:\your_project_path>driveup
 
E:\your_project_path>

or to launch your shell:

e:\>startcmd cmder e:\your_project_path

You can setup cmder or cmd launching to always have uppercase drive letter

@sokra
Copy link
Contributor

sokra commented Feb 1, 2021

hmm.. yeah. This looks like a bug in the jest CommonJs implementation.

To reproduce it run cmd and cd c:\somewhere (lower case drive letter)

Create a file index.js with console.log(require.resolve("./index.js")).

node index.js reports c:\somewhere\index.js

but when running the file with jest it reports: C:\somewhere\index.js.

cc @SimenB

@SimenB
Copy link
Member

SimenB commented Feb 1, 2021

Might have something to do with us running realpath? Can you open up an issue in Jest's issue tracker?

(Playing around with no-oping realpath in https://github.com/facebook/jest/blob/baf9f9937720e87d2b2bd09f4c053fa4f16424ec/packages/jest-resolve/src/defaultResolver.ts#L34 would be interesting data as well, if you're up for it)

@nowakj
Copy link

nowakj commented Feb 6, 2021

I am facing the same problem on node 14.14.0. On a windows docker I use in a TeamCity build for the following two calls I get different results:
__dirname
-> C:\BuildAgent\work\fbf3ed1f3c286972
process.cwd()
-> C:\buildagent\work\fbf3ed1f3c286972

I can't reproduce this problem on my local Windows machine. Not sure what's special about how the code is run on the docker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
module Issues and PRs related to the module subsystem. path Issues and PRs related to the path subsystem. windows Issues and PRs related to the Windows platform.
Projects
None yet
Development

No branches or pull requests

10 participants