Using the global namespace responsibly

I’m seeking opinions here. I have logger class (my own) that I “require” in each module that I intend to log in. Frankly I cannot see any reason why I shouldn’t place the single instance in Node’s global namespace. It is only for my apps, it is only for my library, I know I have placed the logger there. Is there any major downside to doing that or some incredible upside to adding “require my logger” to the top of every file that I’m missing?

Real quick I’m not looking for “you’re polluting the global namespace” I understand the basics :slight_smile: and the the global namespace exists for a reason.

Thanks.

but but bbut, you are polluting the global namespace!

@wh0 is a good person to ask about this

2 Likes

Thanks :slight_smile: I asked on a JS group and they immediately said I might define global variables and nobody would be able to read my code and, and, and one bad thing after another none of which was I going to do…it is even explained on the Node support documents so it isn’t like nobody uses it.

And it isn’t like I’m editing Node, it is a runtime environment, the first few lines of code would clearly insert my logger.

Are you inserting into window? I do this all of the time especially when using functions and webpack

suppose you did do that, where you have a script that adds a global logger symbol instead of exporting it from the module like you currently do. now what does it look like when you want to log something?

  1. you run that script to set up the global logger symbol
    require('./logging.js');
    
  2. you access that logger symbol directly
    logger.log('hi logs');
    

you’ve saved all the typing of const logger = .

but won’t need those requires everywhere, I’m going to require it once in my top level script
– whoever, right after I post this

even then, the cost is that you’re committing to a codebase where “the value of logger depends on control flow. control flow across files, no less.” it’s more for someone reading code to understand, and it’s more for someone writing code to get right.

one thing I’d look out for is if you ctrl-click logger (or equivalent in different IDEs), can you see where it’s defined? this works well for const logger = require(...);. it may be possible to set up some special declarations to make it work with a global symbol too, but would that (1) be worth the effort and (2) add less than one extra line to each file?

you’re asking for opinions, so I’ll leave mine: when it comes to choosing between making the codebase easier to understand and easier to access with various tools vs. saving one require, I’d prefer the former.

2 Likes

This is what I was hoping for. Let me think… yes of course I require it whenever I feel like logging. Granted it isn’t much typing and Node optimizes things and finds it in it’s cache so it isn’t like anything slows down.

A logger is a bit like a database service though there should generally only be one instance. If this was a web site I would implement (both) as services and as such they would be injected in the background. A service can get to the other services and the routes are passed a request object that contains access to all the services. Neither of these uses require.

I mean alternatively I could pass an object where I might pass a simpler value which is how Hapi does it. Services get a parameter that is the server itself. They do that of course to avoid the public definition but it is a sort of “we’ve provided some magic” and in principle the logger lives in their server as opposed to the environment that also contains their server.

I haven’t made the change yet, I don’t mind the require lines but it strikes me as a bit funny. Node could conceivably make console a separate library. If you wanted to output to the console it would only be one more require right? And if Node adds one or two more libraries we just start to call the methods we don’t say “gee I wish I had to require these”.

I’m still on the fence but I definitely understand where you’re coming from and appreciate the conversation. Let me ask something that may not have an answer, is there anything that you would add to the global namespace and if not any idea why it is set up that way? No real way to avoid it perhaps?

Thanks.

I had recently wished that process and Buffer needed to be required :laughing:. They’re not available in the browser, and there’s this troublesome thing where webpack can’t fix those up in the usual module.resolve way.

Dunno, I’d maybe use it for some elaborate prank.

Well I not only didn’t implement by logger solution as a global but I removed the little class I had put there as well. Thanks all.

1 Like

The only side effect I can think of is probaly your autocomplete/ide being confused and not knowing where in the world logger came from but maybe IDEs/editors are smarter than I think.

I thought a bit more about this. Another way to look at it is say you open every single file including the files in your node_modules and paste in logger = require("./sharedlogger"), since adding to the global namespace kind of does that.

I believe you’re overthinking it at this point. :slight_smile: The point of a single insertion into the global namespace is (among other things) the counter opposite of adding require statements. You can see it in your example if you imagine what you’ve typed being used.

Instead of the sharedLogger.js file one wishes to use the colorizedLogger.js as the standard logger. What will you do? I think open every source file and change the name of the required file. The global solution permits a single change in the startup file app.js. It now inserts the colorized logger or the dbLogger.js and all the code continues to work without change.