How can I define a global function in express.js, that without require
I can call it
The global object in JavaScript is an always defined object that provides variables and functions, and is available anywhere. In a web browser, the global object is the window object, while it is named global in Node. js. The global object can be accessed using the this operator in the global scope.
Node. js Global Objects are the objects that are available in all modules. Global Objects are built-in objects that are part of the JavaScript and can be used directly in the application without importing any particular module.
To set up a global variable, we need to create it on the global object. The global object is what gives us the scope of the entire project, rather than just the file (module) the variable was created in. In the code block below, we create a global variable called globalString and we give it a value.
"How" is simple enough:
global.fnName = function(){ return "hi"; }; // Andreas Hultgren's answer
But you don't need the global
prefix; the thing about the global
object is ...
fnName = function(){ return "hi"; }; // i.e. don't do: var name = function(){ ... }; console.log(fnName()); // this prints "hi" console.log(global.fnName()); // this also prints "hi" - it was assigned to global.
"Without require
" is a separate consideration: if you don't use require
there is no guarantee your "globals" will have been declared by the time you need them. It enforces loading order of dependencies, among other things.
"Why am I" and "Is it correct to" are now hidden questions you should consider. It is accepted in javascript that Global Variables ...
... should be reserved for objects that have system-wide relevance and they should be named to avoid ambiguity and minimize the risk of naming collisions - Angus Croll, Namespacing in Javascript
i.e. global
truly is Global: it is used by every author of every plugin or library you pull in to your application, not just you. Naming collisions between global variables break your application. This applies equally in node.js.
Global variables are also thought of as a code smell. In the detail sections below here you will see you can quickly get into trouble by using global variables, and they should really be treated as something that pushes you towards dependency injection and/or namespaces and modules.
Here's a good rule: if you upload it to a web server, or share it with other people, don't use global variables.
global
is permissible in tiny "Saturday afternoon" apps in node.js with express.js, but tend to cause problems later if they get adopted into production. Therefore:
exports
is best practice. require
to ensure they exist by the time you need them:You should really consider app.locals
data, and/or middleware functions, for anything that is view data related.
// call this as a function with an input object to merge // the new properties with any existing ones in app.locals app.locals.({ sayHello: function() { return "hi"; } }); // now you can also use this in a template, like a jade template =sayHello()
If you are creating global vars/functions for configuration settings purposes the below comments about namespaces still apply, and there are conventions emerging such as config.json files (still using require
) for settings that are globally accessed.
It is simple enough to declare a global variable in javascript, and for a function the process is no different. Simply omit the var
keyword which would normally force a local scope on the declaration:
// app.js blah = "boo"; sayHello = function(string toWho) { return "hello " + toWho; } getVersion = function() { return "0.0.0.1"; } // routes/main.js console.log(blah); // logs: "boo" console.log(global.blah); // logs: "boo" console.log(sayHello("World")); // logs: "hello World" console.log(global.sayHello("World")); // logs: "hello World" console.log(getVersion()); // logs: "0.0.0.1"
But what if two separate plugins in your project use a global getVersion
function - how do you get the right version number? Also, how do you ensure that getVersion
exists before you need it, or exists at all?
require
?To quote the nodejitsu docs the built in require
function ...
... is the easiest way to include modules that exist in separate files. The basic functionality of
require
is that it reads a javascript file, executes the file, and then proceeds to return theexports
object
"So", you may ask, "require
just makes sure that a module from another file is included? Why bother?" It's better than that: you can make a whole folder a module, making your code easier to organise and test test test, it will recognise various extensions for file modules, not just .js
, and it will look in various folders as well. Of course, it caches as well.
So, now that require
has found your module, it ensures the code inside it is executed, and puts the objects your created into a "namespace":
// module file ./myModule.js exports.blah = "boo"; exports.sayHello = function(string toWho) { return "hello " + toWho; } // routes/main.js var demoModuleReference = require('./myModule.js'); console.log(demoModuleReference.blah); // logs: "boo" console.log(demoModuleReference.sayHello("World")); // logs: "hello World"
In that sample, demoModuleReference
is an object that looks like:
{ blah: "foo", sayHello: [Function] }
Seems complicated now? Surely global variables are easier? requires
ensures the following:
global
through the exports
object.This application at mankz.com (chrome or firefox only) is fascinating. Depending on how you use your js code, you are very likely to have variable name conflicts within the global scope. Name conflicts come from everywhere. In a browser, for instance, they can come from extensions. node.js is slightly different, but it is becoming more and more extended by compatible plugins as time goes on (you can load jquery in right now, for example). As the versions go on frameworks will get added, and name collisions in global will become more likely. My last run of that app in chrome showed over 1200 global namespace variables.
This global namespace pollution was publicised early on by Douglas Crockford through Eric Miraglia in the article "A JavaScript Module Pattern". In summary:
Example:
ANDYBROWNSONICSUITE.BoomBox.SoundModule = function () { var privateField = "can't touch this"; return { play: function() { console.log(privateField); } } }
global
namespace members in the world by one, but this member contains as many items as you like. When you read the Crockford reference along with the Croll reference (Direct Assignment section) I mentioned at the start, you see why it looks this complicated rather than just doing: sound.play = function() { ... }
- ease of maintenance, refactoring the namespace etc. being just one reason.
In summary:
var
keyword before the declaration.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With