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

Require with an uppercase make a new instance of module on mac osx #5143

Closed
samrm111 opened this issue Feb 8, 2016 · 16 comments
Closed

Require with an uppercase make a new instance of module on mac osx #5143

samrm111 opened this issue Feb 8, 2016 · 16 comments
Labels
doc Issues and PRs related to the documentations. module Issues and PRs related to the module subsystem.

Comments

@samrm111
Copy link

samrm111 commented Feb 8, 2016

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') and require('./Test.js')
Tested on Mac osx 10.11.1 with node 4.2.4

@samrm111 samrm111 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 Feb 8, 2016
@bnoordhuis
Copy link
Member

That's expected. HFS is (by default) case insensitive but node is not. You get the same behavior with NTFS on Windows.

@hgwood
Copy link
Contributor

hgwood commented Feb 11, 2016

@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.js and ./Test.js do 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?

@bnoordhuis
Copy link
Member

The documentation should probably clarify the distinction between file paths and file objects. If you open a pull request, I'll review it.

@hgwood
Copy link
Contributor

hgwood commented Feb 11, 2016

I'm afraid I do not have the skills to do that :(.

@bnoordhuis
Copy link
Member

I'll be happy to walk you through the process. The file you want to edit is doc/api/modules.markdown. Make sure you read CONTRIBUTING.md in the top-level directory as well. Let me know if you have questions.

@hgwood
Copy link
Contributor

hgwood commented Feb 12, 2016

Oh I was not talking about how to contribute, that's fine, but about how to improve the doc and how the require function 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. :)

@ChALkeR ChALkeR added module Issues and PRs related to the module subsystem. doc Issues and PRs related to the documentations. labels Feb 12, 2016
@bnoordhuis
Copy link
Member

You can find the logic for the module loader in lib/module.js, the logic in src/node.js is 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.

@hgwood
Copy link
Contributor

hgwood commented Feb 19, 2016

@bnoordhuis

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?

@hgwood
Copy link
Contributor

hgwood commented Feb 19, 2016

Just opened a PR that doesn't modify any of the existing content but adds to it to explain this particular case.

@samrm111
Copy link
Author

👍 thanks for the PR!

@bnoordhuis
Copy link
Member

How can the same module be "resolved" to 2 different absolute paths without symlinks?

Think require('foo') from a/index.js and b/index.js.

@hgwood
Copy link
Contributor

hgwood commented Feb 23, 2016

Oh, I think I get it. require('foo') from a/index.js could be a/node_modules/foo.js while require('foo') from b/index.js could be b/node_modules/foo.js. Is that correct?

@bnoordhuis
Copy link
Member

Yes, that's right.

@hgwood
Copy link
Contributor

hgwood commented Feb 23, 2016

Thanks a lot for your patience. :)

@michmerr
Copy link

michmerr commented May 6, 2016

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.

@FransGH
Copy link

FransGH commented May 14, 2016

PR #8145 addresses this issue.

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

No branches or pull requests

6 participants