How can I define a global function in express.js, that without require
I can call it
2 Answers
"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.
Node.js and express - global vars and functions
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:
- Modules and
exports
is best practice. - Injection should also be used to reduce coupling between javascript files. But in all cases you will usually need
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.
Global variables - simple case
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?
Why do we need 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]
}
Why modules and not global variables (a.k.a namespacing and "Global is the new private")?
Seems complicated now? Surely global variables are easier? requires
ensures the following:
- It ensures ordered loading of dependencies
- It prevents variable name conflicts within
global
through theexports
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.
Namespaces - why?
This global namespace pollution was publicised early on by Douglas Crockford through Eric Miraglia in the article "A JavaScript Module Pattern". In summary:
- All objects that need to be used between js files are really global
- So, create a namespace object that will be unique
- Assign the return value an anonymous function
- Add private methods and variables inside that function
- Do something useful with the pattern
Example:
ANDYBROWNSONICSUITE.BoomBox.SoundModule = function () {
var privateField = "can't touch this";
return {
play: function() {
console.log(privateField);
}
}
}
Why is this good?
- Now you have only increased the
global
namespace members in the world by one, but this member contains as many items as you like. - Your application is far less likely to clash with other namespaces
- It's a pattern, other frameworks expect you to use it to interact with them properly. In that reference, jQuery is a browser plugin, but you can use it with node and therefore your app, so the library interactivity policy statement is a perfect example.
- It's a pattern, if we all follow it
weour programs are all more likely to get along
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.
Summary
In summary:
- Can I create globals? Yes, it's simple, omit the
var
keyword before the declaration. - Should I create globals? You should use the module pattern, which is implicitly supported by node, and by express
- Why am I creating globals? If it's for configuration, use a config namespace (e.g. How to store Node.js deployment settings/configuration files?)

- 1
- 1

- 18,961
- 3
- 52
- 62
-
Great answer - although FYI it's not entirely clear on what you intended for the relationship between namespaces/anonymous functions and the rest of the answer. What I mean to say is you do not clearly define when the module pattern (using an anonymous function) should be used: instead of global variables? Or when using require? Or when using require to make global variables? – Jodes Dec 16 '16 at 09:32
You can:
global.name = function(){};
But you really should avoid using globals, even if it's possible to use them.

- 14,763
- 4
- 44
- 48
-
5I find this confusing for people. You don't need 'global' to create global variables, you just need to omit the var keyword. I downvoted. Will re-upvote if you change this. I agree that it's probably better practice to use a convention like 'global', but this needs to be mentioned. – Alexander Mills Feb 16 '15 at 08:31
-
if you omit the "var" your code will fail in scrit mode "'use strict';" – AlainIb Jan 17 '17 at 15:09