Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs require - module name case sensitive issue

recently i found out a strange problem regarding the node.js require mechanism

you might think, due to windows file system it doesn't matter if required modules are case sensitive or not. So ...

Module A:

require("fancyModule");

Module B:

require("fancymodule");

are both leading to to the same fancymodule.js file. but the constructor of that object will be called twice. so

var FancyModule = {
    var name = "unkown";
    var setName = function(val){
        name = val
    }
    return {
        setName:setName
    }
}
module.exports = FancyModule();

will result into two separate FancyModule instances. so be aware of it.

I know that i always have to care about the right file name - no matter if the file system is case sensitive or not.

my question is, is there any way to setup or configure nodejs to prevent that - or at least print out a warning ?

like image 329
Daniel E. Avatar asked Apr 25 '14 09:04

Daniel E.


People also ask

For what require () is used in Node JS?

In NodeJS, require() is a built-in function to include external modules that exist in separate files. require() statement basically reads a JavaScript file, executes it, and then proceeds to return the export object.

Is node js case-sensitive?

JavaScript is a case-sensitive language. This means that language keywords, variables, function names, and any other identifiers must always be typed with a consistent capitalization of letters.

Can we use import instead of require in node JS?

You can now start using modern ES Import/Export statements in your Node apps without the need for a tool such as Babel. As always, if you have any questions, feel free to leave a comment.

Is NPM case-sensitive?

NPM packages are not allowed upper case characters in their name, seemingly because unix filesystems are case-sensitive, which creates "a recipe for confusion and nonportable software".


1 Answers

First of all, never make assumptions about the filesystem you are using. Always expect it to be case sensitive, in case you run it in a different environment.

Now to your problem:

When you require a module in node, node will cache the import exactly to prevent the case where you want to export a singleton and not have it initialized twice. While the filesystem lookup will return the same exact file because it's case insensitive, require's cache still treats the two cases as different modules. That's because it has to assume that it runs in a case sensitive environment, so there could actually be two different modules behind that.

That's why it initializes your singleton twice. It actually treats them as two different modules.

You were asking if there's any way to prevent it. There is a very easy but horrible way to do it. You can patch global.require to lowercase your imports:

var patchRequire = function () {
    var oldRequire = global.require;
    global.require = function (moduleName) {
        return oldRequire.call(global, moduleName.toLowerCase());
    };
};

patchRequire();
require('Foo-Bar'); // Will require 'foo-bar' instead

But please don't do that. Better make sure to keep your imports consistent and use all lower case names separated by dashes.

like image 146
Tim Avatar answered Sep 21 '22 22:09

Tim