You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Repro of Node loading modules twice on Windows #6978
Demonstration of how node modules can be loaded twice on Windows under the following circumstances:
command line launching initial node module must use uppercase drive letter, ex. C:\server.js
There must be a circular reference between modules somewhere along the dependency chain where
a child module (in this example moduleB) must be require()'ed with lowercase drive letter, ex. require(path.join('dir','moduleB'))
When moduleB requires moduleA, it will use the lowercase drive letter in it's path.
A dirty diagram...
C:\moduleA -> c:\moduleB -> c:\moduleA
WebStorm IDE by default uses uppercase letters in the command line when debugging node.
Loading modules by way of path.join() is common in many frameworks.
Why should this be fixed?
The case of the drive letter on Windows should not affect the node run-time and how modules are loaded. _Once this case occurs, all require() paths will be changed causing node to potentially load ALL subsequent modules again._
The test failures were because of require.cache exposes the cache key and with my change I changed the case of it. I think the solution is to make require.resolve also normalize the case and update the documentation to clarify that require.cache should always be keyed with the result of require.resolve
I tracked down why the keys currently always have an uppercase drive letter. It is because the full path is resolved based on the requiring module __filename, and that is calculated using fs.realPath. That in turn uses GetFinalPathNameByHandleW in libuv, which performs the normalization even if I pass in FILE_NAME_OPENED.
I think the cache key normalization change can be made regardless of the __filename drive normalization, but I wanted to make sure I understood the whole picture.
I am on vacation now and unfortunately I didn't have enough time to open the PR and defend it before leaving. I am going to resume this as soon as I get back on July 1st.
I just had my issues with this: I'm connecting mongoose in one place, only to have it disconnected in another. Tracking this down took a lot of time too.
Let's just hope you guys can solve this soon.
One other thing: I don't think the scenario is the one stated by @Jeff-Lewis , instead, a much broader one - at least in my case, using vscode.
The thing is that the first module loaded by node "inherits" the drive letter casing from the command line, and everything it requires ends up with the same casing. However, indirect dependencies, the ones required by the modules that the main module loads, ends up having lower case drive letter.
If this is true, the work around would be simple, just adding a proxy main module that delegates to the actual one.
I will properly test this hypothesis later and will come back with results.
Activity
orangemocha commentedon May 26, 2016
I'll revive nodejs/node-v0.x-archive#6774, which I think is an appropriate fix for this issue.
win,module: make module cache case-insensitive
luisrudge commentedon May 27, 2016
I'm having this issue as well and is specially annoying using front end libs because you load two of them (React, for example) and everything blows up
Jeff-Lewis commentedon May 31, 2016
Awesome @orangemocha. Is more needed for a PR?
orangemocha commentedon May 31, 2016
I am investigating a unit test failure with those changes. It should be ready shortly.
Jeff-Lewis commentedon Jun 18, 2016
Hi @orangemocha. How is the testing going? This issue bit be again in another project today.
orangemocha commentedon Jun 21, 2016
I think I have all the pieces of the puzzle now:
require.cacheexposes the cache key and with my change I changed the case of it. I think the solution is to makerequire.resolvealso normalize the case and update the documentation to clarify thatrequire.cacheshould always be keyed with the result ofrequire.resolve__filename, and that is calculated using fs.realPath. That in turn usesGetFinalPathNameByHandleWin libuv, which performs the normalization even if I pass in FILE_NAME_OPENED.I think the cache key normalization change can be made regardless of the __filename drive normalization, but I wanted to make sure I understood the whole picture.
I am on vacation now and unfortunately I didn't have enough time to open the PR and defend it before leaving. I am going to resume this as soon as I get back on July 1st.
Jeff-Lewis commentedon Jul 2, 2016
ref #7175 for another discussion on changes to
fs.realPathbruno-brant commentedon Jul 24, 2016
I just had my issues with this: I'm connecting mongoose in one place, only to have it disconnected in another. Tracking this down took a lot of time too.
Let's just hope you guys can solve this soon.
One other thing: I don't think the scenario is the one stated by @Jeff-Lewis , instead, a much broader one - at least in my case, using vscode.The thing is that the first module loaded by node "inherits" the drive letter casing from the command line, and everything it requires ends up with the same casing. However, indirect dependencies, the ones required by the modules that the main module loads, ends up having lower case drive letter.If this is true, the work around would be simple, just adding a proxy main module that delegates to the actual one.I will properly test this hypothesis later and will come back with results.Tried to confirm my hypothesis, no luck.
orangemocha commentedon Jul 26, 2016
The real cause of this regression is documented at #7726
fs: restore JS implementation of realpath
fs: restore JS implementation of realpath