How to list scope variables in node debugger - node.js

I was wondering if there was a way to list all scope variables (and possibly outer scopes as well) in the built in node.js debugger. So far I've managed to access the global scope using:
debug> repl
> global
but is there a function that lists local scope variables or a pointer to the local scope?
See the debugger commands and global object for more info.

no, currently it's not implemented in built in cli debugger. If you really need it I encourage you to try and add support yourself - the code is in /lib/_debugger.js and command is "scope". It's doable in less than 50 lines of code

Related

How do I find a variable in NODEJS

Good day,
I am trying to read a variable from a process. With javascript, I know, you can use console.log(window['variable-name']) to find a variable's contents using a string.
However, for NodeJs, I know you can use console.log(global['variable-name']), but the variable needs to be global, how can I read module local variables?
Short answer: only by exporting them (module.exports.your_var = your_var) or by setting the variable on global (global.your_var = your_var).
Longer answer:
Modules, when loaded by Node.js, are being wrapped within a Javascript function and then called when required the first time. Function variables belong to the function's scope and they are unaccessible from outside.

JavaScript cannot be run in InstallShield Express?

I am using InstallShield Express to create a setup project.
I try to add a custom action for Uninstallation, before "System Changes".
The custom action is a JavaScript which will open a window, as below:
window.open("https://www.example.com/", "_blank");
However, when I try to uninstall the program, I get an error said "Microsoft JScript Runtime Error, 'window' is not defined.
Why?
Update:
Finally I choose to use a MSI DLL instead of the script to solve the problem. What should I do with this question? THanks.
The windows object does not exist in NodeJS. However, if you just want to declare a global variable to use it later, you can add the open method in the global object like:
glboal.open = function whatever(url, param2){
// does the stuff you want
};
And then you can use it this way:
conosle.log(global.open('https://www.example.com/','_blank'));
But i still do not recommend creating a global variable for this. Make a function in a file and import it when you need it. Global variables can cause coupling, and make code harder to read. Also, this variable will exist the entire lifetime of the application, and this might not be good if you are going to make more of them.
If you want to read more about why global variables are bad: https://wiki.c2.com/?GlobalVariablesAreBad

Setting NODE_PATH from within NodeJS application

We have a node project that does not require our own submodules from a relative path, but instead needs the NODE_PATH environment variable be set to lib to find all submodules.
I wanted to handle this standard case within the program source code but it seems like it is impossible by now.
I found several solutions which all do not work as expected.
module.paths.push("./lib");
Was suggested in another stackoverflow article but this causes an error message in the newer Node versions and refers the developer to using NODE_PATH.
Instead I tried to do the following as the very first line of my program.
process.env['NODE_PATH']="./lib";
This does not cause an error message but it does not work either. I think that this variable is read on the application start and not read lateron when requiering stuff.
All information you can find out from the source: module.js
... NODE_PATH error is thrown only when accessing via require.paths.
Search for _nodeModulePaths function: Module instance has generic Array object paths, with all lookup paths in it.
module.paths.unshift('./foo-baz');
var x = require('some-lib-name');
console.log(x);
So now, if you have the required module under ./foo-baz/some-lib-name/ it would be properly picked up.
What node version and what system you have?

'require' is not defined in console tab of node-inspector's repl

I tried to
require('fs').writeFileSync('o.json', JSON.stringify(anObject));
for debugging, and I got RefrenceError: require is not defined.
This is bizarre. What kind of an environment is it that doesn't have require?
In Node.js, the require function is not defined globally. When you require a module, its source code is wrapped by a function that takes several arguments and require is one of them:
(function (exports, require, module, __filename, __dirname) {/* your code */
});
You can see that wrapper in Node Inspector when you look at the content of any source file.
Now there are two different scenarios for evaluating code from Node Inspector's console:
The debugged process is running. Expressions are evaluated in the global context, i.e. you have access only to globally defined symbols. require is not among them.
The debugged process is paused on a break point. The expression is evaluated in the context of the select stack frame and have access too all variables in the current scope (which include variables captured by closures from by outer functions). However: most functions don't call require, therefore this variable is not captured in any closure and you can't access it.
I had a short chat with one of the Node core developers about exposing require as a global symbol, because it would simplify injecting code from Node Inspector, but my arguments were not convincing enough.
It is possible to use require in node-inspector, by hitting a breakpoint where 'require' is in scope (Tested with NodeJS v0.10.25, node-inspector#0.7.0-2):
An example (a super simple 2-byte 'REPL' for Node): create a file (for example r.js) containing just:
0;
then use
$ node --debug-brk r.js
and start node-inspector and the browser in the usual way,
-or- (using node-debug module from NPM) use:
$ node-debug r.js
Now switch to the node-inspector console in the browser and verify that require is indeed defined, then do something with it, like:
> typeof require;
"function"
> fs = require('fs');
undefined
> fs.writeFileSync('bla.txt', 'blup');
undefined
and verify that this file gets written in the directory where you started node.
Note: the browser part of node-inspector can be quite glitchy: when debuggong different scripts one after the other, I often need to refresh (causing a debugger disconnect), then restart Node until the script shows up correctly in the browser.
P.S. This method has an uncanny similarity to creating a Perl 'REPL' by running it as perl -de '0;'... Coincidence?
FWIW, just by starting with node-debug _mocha, stopping at a breakpoint and selecting the lowest frame on the call stack in the right-side panel, I got to a context where require() was available: require('fs') worked OK, but require('q') and other installed modules didn't, even if I specified an absolute path. Will get back if I come across the solution.
require() is implemented in all CommonJS environments, which include Node.js, but not in the browser's console, which is what node-inspector is based on (to be specific, the Blink Developer Tools):
> require
ReferenceError: require is not defined

cmake, lost in the concept of global variables (and PARENT_SCOPE or add_subdirectory alternatives)

I have a cmake project in which I have some modules and I'm using Find-*.cmake for including the shared modules in the application.
For not taking in account every module that I add, I have defined a kind of global LIB variables tor the linker:
# inside a Find-*.cmake or in the CMakeLists.txt of the modules:
set(LIB ${LIB} ...)
so in one of the final applications that uses some modules I can just do:
target_link_libraries(${APP_NAME} ${LIB})
Then, I'd like to have the compiled modules in the /project_path/modules/foo/build so that if a module is really big to compile it can be compiled once for all the application that use it. The way I'm achieving this is to load the CMakeLists.txt of the module from the Find-*.cmake in this way:
# Inside FindFoo.cmake, for loading /project_path/modules/foo/CMakeLists.txt
# and compile it in /project_path/modules/foo/build
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}
${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}/build
)
include_directories(${CMAKE_CURRENT_LIST_DIR}/../modules/${PACKAGE_NAME}/include)
But it happened sometimes that some module require another modules so that the add_subdirectory creates new scopes and can correctly load LIB but cannot write it (when I use set it is in the deeper scope and not changes the upper scope). For bypass this I have to add PARENT_SCOPE in the set).. So I have tried to add it in some module that I think could be nested and hidden in some dependencies but compiling all the application I suddenly faced with:
CMake Warning (dev) at /path_to_repo/cmake/FindFooX.cmake:6 (set):
Cannot set "LIB": current scope has no parent.
Call Stack (most recent call first):
CMakeLists.txt:14 (find_package)
This warning is for project developers. Use -Wno-dev to suppress it.
I am afraid that this can change from app to app in respect to which module I need or in respect of the dependecies tree in the modules itself so I'm looking for a cleaner solution.
You can 'simulate' GLOBAL variable behavior, by using properties with GLOBAL scope :
SET_PROPERTY(GLOBAL PROPERTY MyGlobalProperty "MyGlobalPropertyValue")
Then you can extract your global property by using
GET_PROPERTY(MyLocalVariable GLOBAL PROPERTY MyGlobalProperty)
Then, MyLocalVariable contains "MyGlobalPropertyValue".
Because PARENT_SCOPE extends variable definitions to the only parent directory (and not to its parents), there are cases it's not enough, for example if you have a deep source tree...
All variables in CMake are local by default. While you can use the PARENT_SCOPE parameter to increase the scope of a local variable by one layer, that mostly makes sense for return values of functions.
For find scripts on the other hand you usually want the behavior of a global variable: Once the find script is called by anyone, you want the results to be available everywhere. In particular, a second call to the same find script should just reuse the results of the first call.
In CMake this is achieved by storing variables to the cache. The various find_* calls already do this automatically, so you should prefer using those where applicable. For any additional custom variables, set offers the capability to store to the cache as well:
set(MY_GLOBAL_VARIABLE "Some value" CACHE STRING "Description")
Note that local variables can hide cached variables of the same name in their scope.

Resources