In my server.js file I included the Underscore.js library.
var _ = require('underscore')
I have my routes like this:
// require routes
require('./routes/document');
In the document route, I want to use Underscore.js. But it seems like the _ variable is not inherited/inside the document scope. Does that mean I have to set the _ variable on every single required route? Or is there a more intelligent way to do this?
Yes, you should set the _ in the files that needs it to be available.
Alternatively, you can put it in the global scope by removing the var part.
_ = require('underscore');
require('./routes/document'); // _ will be visible in document as well
Check the Node.js module documentation where require() is thoroughly explained.
http://nodejs.org/docs/v0.4.5/api/modules.html
As for your specifics:
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.
Hence, if you require('underscore') in both your parent library and './routes/document', only one instance of the underscore module will be loaded and hence. Both variables will be in fact the same object.
And by the way, you don't want to define variables in the global scope as it might generates side effects and potentially overwrite properties in other modules.
Finally, the util module provides an inherits method to subclass another constructor and inherit from its prototypes.
http://nodejs.org/docs/v0.4.5/api/util.html#util.inherits
As far as I know Node.js engine "requires/charges" a module/file.js in a different scope (I don't know exactly how), for security reasons (imagine a module could change the variables were it's required. That would be dangerous! More information about this concern: Information hiding).
The only exception are global Node.js objects that are exposed into the module scope.
A global object is, precisely the object "global", and everything you define without var keyword actually is added to that global object:
foo_var = "Whatever"
means that:
console.log(global.foo_var) // Logs "Whatever"
Related
What is the impact of the following declaration in a Sails JavaScript application?
var DataService = {};
module.exports = DataService;
module.exports = {
// module code
}
I understand this is a "hack" that allows WebStorm intellisense to recognize DataService and its members globally, but will the code behave exactly the same with and without the 2 first lines?
Tks!
Short answer:
Probably (because of the optimizer).
Long answer:
This horrible hack probably won't create any perceivable differences in how the code functions. In theory, you create a new object, which would take up space in memory and cost some CPU cycles, but in all likelihood the optimizer will simply elide that part of the code as long as you don't reference the created object anywhere (I am guessing...)
Suggestion:
Try to use https://www.jetbrains.com/help/webstorm/2016.1/configuring-javascript-libraries.html#configure to register your library in a more robust fashion.
An aside about intellisense in javascript
Note that this behaviour appears to be due to Webstorm not really
understanding about JavaScript modules yet. For a node.js-based
project, anything declared inside an imported context (like
DataService.js) is scoped to that import (file), unless you explicitly export it.
However, the same piece of code, running in the browser in a SCRIPT
tag src file, would end up in the global context.
When you declare var DataService = {} in your application, WebStorm incorrectly assumes that you are placing the DataService variable into global scope, meaning that any other file which adds members (props/methods) to the referenced variable would end up as members of the DataService object you created.
You will note that this assumption wouldn't be strictly true, even if the variable did end up in global scope, because more than one file would declare the variable, thus overwriting the object you create in your file. JavaScript intellisense always involves a bit of guesswork because the language is very loosely typed and an object's properties can't really be determined without actually executing the code.
In general, if you declare a member in a file or against a variable named DataService somewhere in the indexed codebase, WebStorm (and most other IDEs) will bring it up as a potential member of the variable you are referencing. You can't rely on intellisense to guarantee the presence of a property through static analysis like you would in a more statically typed language like Java or C#.
First, you define a variable called DataService and you equals it to an empty object. After that, you are assigning to the module.exports object the value of the DataService variable, which is an empty object. Finally, your are overriding the module.exports object with again an empty object, but directly defined. It will have the same behavior, because in the two cases, the object has the same data, which is an empty object.
The variable name DataService is used as a reference to the empty object in the local namespace. Assigning a value to the module.exportsobject is giving it the data of the variable, not the name. For example, when you will want to use the module, you will require it,
var dataService = require('./data-service');
If DataService was an object, then you could access its properties
var example = dataService.example;
But in your case, dataService is directly an empty object, not a DataService object. So you can not
var example = dataService.DataService ;
I often use prototypes such as these:
requiring the same or similar functions over and over in different files.
Would it be better to require Element inside the scope or outside the scope as done so below?
I guess it's should be outside, otherwise I will be creating lots of copies of Element all over my code, No?
var Element = require("./Element.js")
var _ = function(){
this.element = new Element();
this.stuff;
}
_.prototype.setStuff = function(stuff){
this.stuff = stuff
}
_.prototype.doStuff = function(){
this.stuff();
}
module.exports = _;
Thanks.
Since this is a node.js module, there are several considerations here:
require() is synchronous. Thus you don't ever want to use it inside of live server requests because that blocks the scalability of your server. You will generally want to use require() once when a module is initialized and your server is being initialized.
Variables declared within a node.js module are scoped only to the module. Technically the module scope is inside a module function so any variables declared there are already local variables and thus don't need any extra scope protection.
Modules are cached. So, it is very fast if you do require() multiple times on the same path. After the first time when the module is actually loaded and initialized, all subsequent calls just return the same cached module handle. So, don't try to mess with the structure of your code to reduce the number of places you call require(). Write clean code and if that necessitates calling require() a few times on the same module, that's no big deal.
requiring the same or similar functions over and over in different
files. Would it be better to require Element inside the scope or
outside the scope as done so below?
You usually want to put require() statements at the highest level in your node.js modules because you want to initialize them once when the module is first initialized and you want to share that module handle with all the code in the module. If your code is complex enough that you feel like calling require() for the same module in several different places to keep your code more partitioned, then you probably should be breaking your code into separate modules anyway and let each module require() in whatever it needs itself.
I guess it's should be outside, otherwise I will be creating lots of
copies of Element all over my code,
Outside at the highest scope in your module. There's really little reason not to just load the module once and share the module handle with all the code in the module that might want to use it.
There are a few special cases where you might want to dynamically load modules only in some specific conditions at run-time only when a module is needed. This is rare and has performance consequences when doing so because of the synchronous nature of loading modules so it is rarely done. So, I didn't want to be absolute in my earlier recommendation, but also wanted to explain that loading something only on-demand is rare and has consequences.
Here Element should be defined inside the _ function scope unless it is defined inside a IIFE.
If it is defined inside IIFE then there won't be any issue else Element will be exposed into window scope and using console we can override the Element function.
Hope this helps you.
Are there any security issuses or something with using global variables and assignig modules to global variables in nodejs?
example:
client = new Client();
Without the var statement, so i can use it everywhere?
It's not that it's a security problem, it's considered bad practice though and it can lead to other problems such as trying to override a Node.js global variable.
Try not to pollute the global namespace and if you really really need global variables, just use one with sub-objects.
I don't think there are security issues per se, but you will be polluting the global namespace. As your project grows (especially with more than one programmer) the risk of conflicts gets bigger. And what if you later on add a third party library to your project that has a variable named 'client'?
I've been using Node for a couple of years and I had the same "problem" you have and is frustrating. Nevertheless I can give you the solution I reached and it works for me.
Node doesn't allows global variables in the way you ask since variables defined as global in a module are global only for that module. But exists a GLOBAL object that ban be used for what you need.
Global variables are a bad idea in general (always), but having a global cache of useful functions in it's own namespace is not a crime at all since it will not override anything and lets you use it along your code. So I'll tell you what I do to share functions and objects between modules and keep source organized (that's important for me at least!):
1st Create a resource file where you place all important functions and objects you want to share across your code. I call mine "R.js", R from Resources
2st Define the "R" object that will store all functions and objects and assign it to node's GLOBAL object:
var R = {};
GLOBAL.R = R; // Adds resource module to global
3rd For sake of simplicity and avoid extra requires all arround the code, I do all needed requires inside R.js. After that you only need to use them with R.require_variable.function_or_property
// All needed requires
R.fs = require('fs');
R.net = require('net');
R.http = require('http');
R.dbClient = require('mysql').Client;
...
4th Create the shared functions, variables and objects you like inside the R object
5th Where needed arround your code, require the R.js file and access to it's member by using the R object
R.<property_or_function>
2 warning notes.
Remember to always call shared functions or user shared objects placind "R." in front of it
Althought you can assign new functions, objects and properties to R object anywhere this can lead to the same inconsistencies you would have with global variables if you don't plan it in advance - i.e. you call a shared function before assigning it to R - so as a methodology, create everything in the R.js file instead of doing it all arround your code. This way all shared things will be in R.js and that is the only place to look for shared code.
So in Firefox extensions it's encouraged for your extension's objects to live in sub-objects like com.contoso.myExtension . That way you have not put any objects in the global namespace and extensions generally stay out of each other's hair. (At least in the common browser.xul window)
But from what I have understand about Javascript code modules (JSMs), is that while the module itself is working in a separate namespace, the symbols that it exports will end up in the global namespace of whatever code imports it. Furthermore, it's impossible for an extension to be "nice" and only try to build sub-objects; those exported symbols will just whack whatever global variables already existed. Also you can't export a symbol like com.contoso.myExtension. It's only a simple global variable.
So what's the protocol for playing nice when using JSMs? Just make really long variable names and hope they won't collide?
First off, I haven't seen a hard a true standard for how to handle this. But we can definitely do much better than just long variable names...
You are correct about the Javascript Code Modules living in a separate namespace (so to speak), however when you import them, you don't have to import them into the global namespace. If you look at the Components.utils.import documentation, you see that you can import onto a specific scope. That is, you don't have to pollute the global namespace at all.
You can collect your modules into a myExtension namespace.
var myExtension = {};
Components.utils.import("resource://.../module.jsm", myExtension);
And wrapping this inside a self-executing function doesn't let any variables leak into the global namespace, not even myExtension!
(function(){
var myExtension = {};
Components.utils.import("resource://.../module.jsm", myExtension);
})();
I know that global variables are bad.
But if I am using node's module "util" in 40 files in my framework, isn't it better to just declare it as a global variable like:
util = require('util');
in the index.js file instead of writing that line in 40 files?
Cause I often use the same 5-10 modules in each file, that would save a lot of time instead of copy paste all the time.
Isn't DRY good in this case?
You could just have a common module.
common.js:
Common = {
util: require('util'),
fs: require('fs'),
path: require('path')
};
module.exports = Common;
app.js:
var Common = require('./common.js');
console.log(Common.util.inspect(Common));
Each module is supposed to be independent. The require doesn't cost anything anyways after the first one for each module.
What if you wanted to test one module alone? You'd be having a lot of issues because it wouldn't recognize some "global" requires that you have in your app.
Yes, globals are bad, even in this case. Globals almost always ruin: testability, encapsulation and ease of maintenance.
Updated answer Jan. 2012
The global object is now a global inside each module. So every time you assign to a global variable (no scope) inside a module, that becomes part of the global object of that module.
The global object is therefore still not global, and cannot be used as such.
Updated Dec. 2012
The global object now has the global scope within the application and can be used to store any data/functions that need to be accessed from all modules.
global.util = require('util');
There's a section about global objects in the node documentation.
However, globals should be used with care. By adding modules to the global space you reduce testability and encapsulation. But there are cases where using this method is acceptable. For example, I add functions and objects to the global namespace to use within my unit test scripts.
I'm confused by the answers in this thread.
I am able to do this...
File: test.js
global.mytest = {
x: 3,
y: function() { console.log('Works.'); }
};
File: test2.js
console.log('Does this work?');
mytest.y();
File: server.js
require('test.js');
require('test2.js');
And it seems to work as the question needed. The first require places the mytest object into the global scope, then the second require can access that object without any other qualifiers.
I was trying to figure this out (which brought me to this thread from a Google search) and I wanted to post what seems to work for me now. Maybe things have changed since the original answers.
I have successfully been using the process object for passing around my configuration object. While in theory suffering from the exact same issues as mentioned above (encapsulation, testability and so forth) it works fine when using only non-state modifying properties (a hash table with primitives, basically).
If you wrap your modules in blocks (e.g. anon functions) you can bind to a local name (via parameter or 'var') and then have any arbitrary long (perhaps "package" labeled) name you want (if you even need a global at this point).
For instance, my modules often look similar to:
;(function ($, $exp, other) {
$(...)
other.xyz()
$exp.MyExportedObject = ...;
})(jQuery, window, some_module.other_expression) // end module
I use jQuery with noConflict, this the former, and the latter show you can do this for any expression -- global, require, computed, in-line, whatever... this same "wrapping" approach can be used to eliminate all (or almost all) "special named" globals -- globals must exist at some level, however, removing potentially conflicts is a very big win.