node js behaviour for this keyword - node.js

Let's have a look to this very basic program.js:
console.log(this);
Here is the output:
$ nodejs program.js
{}
Now, if i do the samething in the repl console:
$ nodejs
> console.log(this)
I see a log of things at undefined at the end.
Why do we not get the same result ?
Thanks

You are experiencing two different behaviors because you're basically executing code in two different environments.
In program.js, this answer applies. You're in a node.js module, so this is the same as module.exports.
In the node.js repl, this answer applies. You're not in a node.js module; you're in the repl which uses the global context. this is the same as global. If you executed the same code in-browser, it'd reference the window object instead of global.

Related

How to fix unresolved function inspection in WebStorm 10

I'm using WebStorm 10.
When I use some lib like bluebird that make code like
var foo = require("foo"); // I will call foo.doSomething
Promise.promisifyAll(foo);
foo.doSomethingAsync(...).then(...)
the doSomethingAsync will be marked as unresolved function inspection.
So what can I do something like config *Async in WebStorm to avoid unresolved function mark?
Best solution at the time is use namespace reserving.
Webstorm supports using comments in order to mark stuff as legitimate:
/** #namespace foo.doSomethingAsync */
var foo = Promise.promisifyAll(require('foo'));
foo.doSomethingAsync(...)
.then(...)
This doesn't solve the actual issue, and won't get you suggestions for the arguments when using the function, but it's surely a convenience, helping clean up the insane amount of warnings generated when promisifying.
I hope this helps..
Got a similar issue when working with TypeScript and Angular 2 (following its Heroes tutorial) using ES2015, but for the Promise object.
Promises are part of the Standard Built-in Objects, so I thought that WebStorm 2016 could use the TypeScript definitions and be able to get it, but by default it didn't.
Everything worked except for this.
So, I went to Settings > Languages & Frameworks > JavaScript and changed the JavaScript language version to ECMAScript 6.
I thought that it would not having nothing to do since I was using TypeScript, but it does.
Now the Promise object reference works and links to lib.es6.d.ts, which is an internal WebStorm definition of ES2015 objects for TypeScript.

Write a module that works both in nodejs and requirejs

I wrote a small parser that currently works in node app, but wondering if there is a way that I can make a module that will work both in NodeJS app and client side app that uses requirejs?
path/to/lib/index.js
function someRandom(strings) {
// we are doing something here
return strings
}
exports.someRandom = someRandom;
Right now I'm getting this in client-side
Uncaught ReferenceError: exports is not defined
I know that I can use node requirejs and then change the structure to use define but is there other way without adding node requirejs?
This is my js/main.js file
require(["path/to/lib/index"], function(something) {
// will do something here
});
The way I prefer to do it is to write all my modules in the AMD syntax (use define) and use amd-loader to load them in Node. Note that this solution is not using RequireJS, even though the AMD syntax is used.
However, there's a way to do it without having to use the AMD syntax. You can use r.js to wrap your Node modules. For instance, if you put your tree of Node modules in in, you can do:
$ r.js -convert in out
This will create in out a tree of files that correspond to those in in but wrapped with the define call. You can then load these in the browser using RequireJS. There are limitations. Some are obvious, like not being able to use the Node modules that depend on the Node runtime (like fs, child_process, etc.). Some are more subtle, like the fact that you can't use require(foo) where foo is a variable (RequireJS will handle only string literals there). See the documentation for the details.

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.

Cannot set breakpoint inside function when using require inside closure

Using node-inspector, I'm unable to set breakpoint in the following node.js code. (Content of main.js)
(function() {
require('underscore');
var doSomething = function(callback) {
callback('doSomething Finished');
}
doSomething(function(x) {
console.log(x);
});
}).call(this);
I can easily set a breakpoint on line 2, line 4 or line 8, however no matter how hard I try the debugger won't let me set a break point on line 5 or line 9. To be clear, I'm using the following commands to run node-inspector
node --debug-brk main.js
node-inspector
I also tried to debug in web storm, however the issue persists. If I remove the line require('underscore');, then the problem immediately goes away and I'm able to set break point inside function body again. The problem also goes away if I remove the outermost closure function. It seems that the interaction between require and file level closure is screwing up the node debugging functionality. Has anyone experienced this problem themselves and / or knows any workarounds to be able to break inside function body?
EDIT: My node js version
Tony:~ $ node --version
v0.10.12
Tony:~ $
I ran exactly into the same issue with the same setup.
I've added a breakpoint after the definition of the target-function (that was the only place i could actually add a breakpoint). When the debugger reached that breakpoint and the function was actually defined, i was able to add breakpoints to the actual target-function...
This may not be the answer that you want to hear as it doesn't explain why you can't set any breakpoints, but I would simply remove your require statement from the closure and place it top-level. I would go even further and recommend that you don't use a closure like the one above at all.
The reason is that node uses its own module system, and unlike Javascript in the browser, declaring variables top-level does not pollute the global namespace. This is where require(...) comes in. So, you gain nothing by wrapping your code in an immediately invoked function (unless of course you want your module to be able to run both client side and server side).
I would guess that the reason that you are not able to set any breakpoints is that the V8 runtime is recognizing an unnecessary closure and then optimizing your code for you. The rewritten code may not have the correct source mapping and so breakpoints cannot be set.
So, two suggestions:
require calls are not like regular statements. They are more similar to import statements in Java and are handled specially by the compiler. They should always be top-level in a node file.
No need to wrap your code in an anonymous function when in Node.

What causes differences in global variables (interactive vs. scripts)

I'm running to the following issue with Node.js v0.10.1 (demonstrated with a quick example):
While running node in the interactive command line:
> global.require
{ [Function: require] . . . }
> require
{ [Function: require] . . . }
When running the following script.js I get unexpected results:
console.log(global.require); // 1.
console.log(require); // 2.
undefined // 1. `global.require` is undefined!
{ [Function: require] . . .} // 2. `require` by itself works however.
I've removed extra code denoted by .... Run it locally to see the full extent of what is actually shown.
What causes this to happen?
Node.js contains a repl module that allows you to create your own Read-Evaluate-Print-Loops (this is what repl stands for). Using this module there is a function start that you use to create a new repl.
This function takes an options object where you can configure your repl. One of these options is called useGlobal. According to the documentation for this option the following sentence is valid:
if set to true, then the repl will use the global object, instead of running scripts in a separate context. Defaults to false.
Now when you start Node.js in interactive mode, this is basically nothing but a repl like those you could create for yourself using the repl module. I guess (and please note that this is only a guess!) that Node.js's default repl has useGlobal set to true.
Hence you have a global object, which is in turn the very same as the global namespace anyway. Hence all the functions such as require that you can find on the global namespace you will again find on the global object.
Once you start a Node.js application in non-interactive mode, there is no repl, hence there is no global object.
Does that make sense to you?
Many of the Globals won't normally be in the global scope or members of the global object:
These objects are available in all modules. Some of these objects aren't actually in the global scope but in the module scope - this will be noted.
These are "globals" more by the 2nd interpretation:
Of the top-most scope.
Of an accessible scope other than the current local scope.
Also, as noted for require():
To require modules. See the Modules section. require isn't actually a global but rather local to each module.
The REPL module, that manages the interactive mode, has an option to promote them to the global scope:
useGlobal - if set to true, then the repl will use the global object, instead of running scripts in a separate context. Defaults to false.

Resources