Inject a global variable into node context - node.js

Could i inject a global variable into node context, like "document" in html's script, which any javascript files could access this variable, and it isn't needed to import or require it?
//var document = require('document') // i don't need to require it by myself
document.findById('111')

To create a global in node.js, you assign to the global object.
// define global
global.myGlobal = 3;
// then use it anywhere
console.log(myGlobal);
Here's a good article on module-level variables and globals: Using global variables in node.js.
FYI, the node.js module architecture makes it so you do not need to use globals at all. You can simply require() in shared modules in order to share variables. If you're new to node.js, this may seem a bit odd and a bit inefficient, but you will get used to it and it is the preferred way to develop in node.js because it leads to modularity, testability and robust code.
Here's an interesting article on: Why global variables are bad.

Related

how to define user defined constant globally in nodejs

Here, my question is, we use define function in php to define the
contant globally but how can i achive same thing in nodejs
in php:
define(nameofthecontant, value);
in nodejs how to?
var dataBaseInfo = result.databaseInfo;
// global.DB_HOST = dataBaseInfo['DB_HOST'];
for(var keys in dataBaseInfo) {
global.keys = dataBaseInfo[keys];
}
i have data in result.databaseInfo from database xml file and m trying to create global contant using for loop, its not working
This is how you can define a variable in the global namespace:
global.nameofthecontant = value
This is something that you don't want to do in node.js though. Your question possibly is a duplicate of this question: node.js global variables?
Change your code from this:
global.keys = dataBaseInfo[keys];
to this:
global[keys] = dataBaseInfo[keys];
When you want to access or assign a property and the property name is in a variable, you use the obj[variableName] syntax.
You could also use Object.assign here if you just want to copy a bunch of properties from one object to another:
Object.assign(global, databaseInfo);
As others have said, it is usually frowned upon to use globals in this way in node.js. Instead, you would typically expose these constants in a module and then just require in the module in any other module that wants to access the constants. This makes your code more modular and makes each module more self-contained.

node.js setting a global variable

I'm new to node js. I searched a lot on stack overflow on this question below, none what I need.
I have an app.js file which initiates node server and a router file. I want to be able to store a global value once and shared across other server side .js files which contains my functions. I also want this variable to be accessible in my .jade file. (I use express BTW)
Is there a way to accomplish this?
Thanks.
The Node.js documentation says under Module Caching
Caching 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.
Multiple calls to require('foo') may not cause the module code to be
executed multiple times. This is an important feature. With it,
"partially done" objects can be returned, thus allowing transitive
dependencies to be loaded even when they would cause cycles.
If you want to have a module execute code multiple times, then export
a function, and call that function.
Which means you can easily expose a global object simply by putting it in its own module.
//config.js
var config = {
dbUrl: 'mogodb://localhost:2107/persons'
};
module.exports = config;
And then when you want to gain access to that object, you simply do:
var config = require('./config');
And that's done, you get access to the same instance everywhere.
You'll want to limit the usage of global vars in Node. This is because unlike any other server side language, Node is a persistent process that share all request. So you cannot setup user state globally as those will be shared across all user accessing your site.
In raw node, there's two global context:
global.foo = 'bar';
// and the process object
process.some_var = 1;
In Express, you can setup application wide vars using app.set
But, most of the time you'll want to share data by adding them to the request or the response objects. That is because those objects are "user" specifics, unlike the global namespace.
For the template, you'll always want to pass in the context:
app.render('email', Object.assign( aSharedObject, {
specific: 'values'
}));
i would use process.env or if you are using nconf put it into the app configuration as Jordan said, globals are BAD idea, also if you don't want to include nconf or any other conf module or use process.env then you can create a module and export a set of getters and setters to handle the value

Why does accessing variables declared without `var` work without having to use `require` in other files?

Here's an example
$ cat main.js
App = {
version : 1.1
};
require('./mymod.js');
$ cat mymod.js
console.log(App.version);
$ node main.js
1.1
Note how I declared App in main.js without var. This allowed me to access App from mymod.js without having to call require. If I declare App with a var, this won't work.
I want to understand why this happens? Is it the intended behaviour for node.js or a bug? Is this behavior consistent with ECMAScript or CommonJS standards?
This trick gives a powerful mechanism to circumvent the require module system of node.js. In every file define your objects and add them to the top level App namespace. Your code in other files will be automatically have access to those objects. Did I miss something?
If you assign a variable without using var, it is automatically a global variable. That's just the way JavaScript works. If you put 'use strict'; (quotes required) at the top of your js file, this becomes an error instead.
All has to do with local scope vs global scope.
You can even do this (which is much neater):
app.js:
exports = {
version : 1.1
};
main.js:
var App = require('./app.js');
console.log(App.version);
Defining a variable without a preceding var will place it into the global namespace which is visible to all of your JavaScript code.
While this may seem a useful feature, it is generally considered bad practice to "pollute" the global namespace and can lead to subtle, hard-to-locate bugs when two non-related files both rely upon or define variables with the same name.
In nodeJS environment there is a global scope referenced by 'global' , just like the way we have 'window' in browser environments. In effect every javascript host enviroments always start with creating a global object.
When require('main.js') is executed, there is this following function that is created and executed against the global scope 'global'.
(function(exports,...){
//content of main.js
App = {
version : 1.1
};
})(module.exports,..);
When the above function is executed and since there is no var declaration for App , a property with name 'App' is created on global object and assigned the value.This behavior is according to ECMA spec.
That is how the App gets into global scope and is accessible across all modules.
require has been introduced to standardize development of modules that can be ported and used.

How to stub "global" module variables in node.js with Coffeescript without --bare?

I have some environment variables from Heroku and for readability, I tend to assign them to global variables for readability:
ACCESS_TOKEN = process.env.ACCESS_TOKEN
Now I'd like change value for that in tests. I have tried rewire and sandboxed-module. However, they are both setting global variables directly, whereas coffeescript variables are wrapped in anonymous function.
Is there any way around this, or do I really have to use --bare if I want to test my code?
I'm not familiar with node, but the approach I'd use, and that I've used in other technologies is wrap up globals or external dependencies in an object which can be swapped out for a stub or mock object when needed in test.
Say rather than storing the value in ACCESS_TOKEN you made a herokuEnvironment object and gave it the method accessToken(). Wherever you need to use the properties you inject the object. Then in production that method calls process.env.ACCESS_TOKEN. If you need a safe version to inject into a test situation, you just supply { accessToken: function () {return 'foo';}}

Is there a better way to structure global variables in Node.js?

Trying to understand what would be the best way to structure some variables. For example in my Node.js Express app, I have the following in app.js:
var poolModule = require('generic-pool');
global.pools = {
/* ... */
};
Where pools is my global variable that keeps track of MySQL and Redis pools. I am also wondering if I can do the same with actual Redis and MySQL objects (and maybe configs variable) so I don't have to require them all over the app. And since they are going to be used the most.
Is this bad practice, and if yes, what's a better way to structure this kind of code?
Edit: added global.
If you require a file you are actually always requiring the same object. So that means you can do:
module.exports = {
// same object for everybody that requires me
};
You have the right idea, but you want to use module.exports to export your object as a module. The CommonJS approach is to have local variables within the module and exported variables for use outside the module. In this way modules can access each others' variables through the use of require. These variables aren't really "global", but in a way are more like "friend" classes in C++. You can in fact have your poolModule do more than store variables for you--you could put methods and other functionality in there too and make it reusable across your whole application.

Resources