Repository navigation
Require with an uppercase make a new instance of module on mac osx #5143
Description
Activity
- changed the title
[-]Require with a caps make a new instance of module on mac osx[/-][+]Require with an uppercase make a new instance of module on mac osx[/+]on Feb 8, 2016 That's expected. HFS is (by default) case insensitive but node is not. You get the same behavior with NTFS on Windows.
@bnoordhuis The documentation about this is a little bit hard to understand:
Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object returned, if it would resolve to the same file.
Modules are cached based on their resolved filename. Since modules may resolve to a different filename based on the location of the calling module (loading from node_modules folders), it is not a guarantee that require('foo') will always return the exact same object, if it would resolve to different files.
In @samrm111's context,
./test.jsand./Test.jsdo resolve to the same file, so I would expect the same object to be returned. There's quite a long discussion about this in the 0.x archive.If this issue is not something that will be fixed, could the documentation be updated to make the problem clear?
The documentation should probably clarify the distinction between file paths and file objects. If you open a pull request, I'll review it.
I'm afraid I do not have the skills to do that :(.
I'll be happy to walk you through the process. The file you want to edit is
doc/api/modules.markdown. Make sure you readCONTRIBUTING.mdin the top-level directory as well. Let me know if you have questions.Oh I was not talking about how to contribute, that's fine, but about how to improve the doc and how the
requirefunction actually works. For example:every call to require('foo') will get exactly the same object returned, if it would resolve to the same file.
I have no idea if that is 100% false or if it is true in some definitions of "resolve" and "file" that I don't understand.
Since modules may resolve to a different filename based on the location of the calling module
Same thing. What does "resolve" mean here? I'm not sure.
But, anyway, that's not an excuse isn't it? I'll run some experiments and come back with sufficient knowledge and/or questions. :)
- addedmoduleIssues and PRs related to the module subsystem.Issues and PRs related to the module subsystem.docIssues and PRs related to Node.js documentation.Issues and PRs related to Node.js documentation.
on Feb 12, 2016 You can find the logic for the module loader in
lib/module.js, the logic insrc/node.jsis for built-in modules only.'Resolve' means 'look up relative to the file calling require()` (with an exception for built-in modules, those always take precedence.)
The path to the included file is turned into an absolute path, symbolic links are followed and the result is used as the key in the module cache.
The path to the included file is turned into an absolute path
If that is so, why would the documentation say
Since modules may resolve to a different filename based on the location of the calling module
How can the same module be "resolved" to 2 different absolute paths without symlinks?
Just opened a PR that doesn't modify any of the existing content but adds to it to explain this particular case.
👍 thanks for the PR!
How can the same module be "resolved" to 2 different absolute paths without symlinks?
Think
require('foo')froma/index.jsandb/index.js.Oh, I think I get it.
require('foo')froma/index.jscould bea/node_modules/foo.jswhilerequire('foo')fromb/index.jscould beb/node_modules/foo.js. Is that correct?Yes, that's right.
Thanks a lot for your patience. :)
This is actually a problem on NTFS when a symbolic link is created pointing to a target with casing different than the string used in the command. When querying the file system for the link target, it returns the string used to create the link instead of the actual name of the target.
C:\foo
Mklink /d BAR C:\FOO
Now paths under BAR will be resolved to strings with FOO, not foo.I've just run into this during the migration of a product build over to a system that creates links with this sort of mismatch. Components using gulp from inside their makefiles are blowing up when the module definitions extended a module using one variation of the path, but instances are created using another.
It is not obvious what the issue is when this happens.
I'm going to try to work around this by recreating the links on the fly, but an alignment of the link target string with the actual file system object somewhere upstream would make this a non issue.
PR #8145 addresses this issue.
Given a file named
test.js,Using require in those two way will works, but node will create a new instance for each:
require('./test.js')andrequire('./Test.js')Tested on Mac osx 10.11.1 with node 4.2.4