How can I detect the entry file in Node.js?
For example, if I launch my application by typing node file1.js, how can I tell that file1.js was the entry point?
You can also use require.main.
Accessing the main module
When a file is run directly from Node,
require.main is set to its module. That means that you can determine
whether a file has been run directly by testing
require.main === module
For a file foo.js, this will be true if run
via node foo.js, but false if run by require('./foo').
Because module provides a filename property (normally equivalent to
__filename), the entry point of the current application can be obtained by checking require.main.filename.
hot sauce
process.argv[1] provides that information.
Related
I'm using SublimeText editor in combination with SublimeREPL which allows code snippets to be run from the text editor in different languages. I used this regularly with Python and now trying to use same with Node.js. I'm able to execute javascript from within the editor but have run into issue loading my own personal modules (local file). Below describes the issue.
I'm using SublimeREPL with node. I tried to load a module from a local file. The require command seems to run successfully but I get "not a function" when trying to run a function from within the module.
The same works fine when running from node command line.
Here is the contents of my primary js file:
console.log("Loading norm.js")
var norm=require("./norm.js")
console.log("Contents of norm module:")
console.log(norm)
// Now try to run a method from norm.js listed in exports
console.log("Output:")
let x=norm.normalizeAPI({ contact: {id:1, custom_field: {cf_country:'Canada'}}}, 'crm', 'contact')
console.log(x)
The module defines some functions and uses module.exports to export 3 of them.
When I run primary file from command line I get expected output:
> node test.js
Loading norm.js
Contents of norm module:
{
normalizeAPI: [Function: normalizeAPI],
normalizeBuiltins: [Function: normalizeBuiltins],
normalizeCustomFields: [Function: normalizeCustomFields]
}
Output:
{ custom_fields: { cf_country: 'Canada' }, id: 1 }
But when I try to run same from within SublimeREPL, I get following output:
Loading norm.js
Contents of norm module:
{ }
Output:
Uncaught TypeError: norm.normalizeAPI is not a function
I use process.chdir to change to directory where files are located. Both the primary file and the module are in same directory. require() must be finding the file because if I change the path to invalid filename I get error. It seems to me the problem is either no objects are being loaded or the exports are not set.
Inside the module, I have tried to export using module.exports= and exports=.
Is it possible to load a local file module from within SublimeREPL and if so, how?
After not getting response here or on the SublimeREPL github project (which as #MattDMo points out is a defunct project), I experimented with a workaround. I came up with the following which works pretty well.
So the initial goal was to run a single .js file that itself had references to my own personal modules in local files. Instead of using require, I go thru following process for each module:
Run all functions and properties in the module in SublimeREPL as normal (select all and execute in SublimeREPL)
create an object that is same name as what you store results of require into. E.g.:
norm={}
create objects inside norm for any functions or properties of the module in your exports list. E.g.:
norm.normalizeAPI=normalizeAPI
norm.normalizeBuiltins=normalizeBuiltins
norm.normalizeCustomFields=normalizeCustomFields
Now you can run other functions in your primary script without having to edit them. E.g.
norm.normalizeAPI(arg1, arg2)
To make it easy, I add a comment in the bottom of the module as follows:
/*
norm={}
norm.normalizeAPI=normalizeAPI
norm.normalizeBuiltins=normalizeBuiltins
norm.normalizeCustomFields=normalizeCustomFields
*/
Then I run this in SublimeREPL also.
Note: All functions and variables in the module are stored in the global namespace so name collision may be a problem with this approach but not for my use case.
I am having issues attempting to properly use pkg (nodejs module) properly.
I am doing a stand alone file manager (well, it would swap video/audio files to & from preselected directories, intended to allow it without any internet connection it self to remove & add files to a syncing folder like onedrive/dropbox/googledrive/etc. using a text file.)
The issue I am having, is I am at a loss of after I package it into a binary.. I do not understand how to allow/force it to create/read the text file outside compiled binary.
-- I would love for it to be within the same folder as the executable.
I am attempting to find a way to store data without having to share the sourcecode, or require node be installed on other machines.
-- I intend to have a minimal permissions as possible, and outside reading/writing the config & 'database' [which is simply a text file with what files are in the local storage, and what files are & are not in the remote storage]
What am I missing about pkg, & if it can store data internally some how... how do I get it to read an external file?
-- Though I would greatly prefer to have the txt files outside the binary & in plain text easy to read.
As a side question, I am not understanding how to pass an argument through & use it inside the program after it's compiled. [Hell, I'm having a heck of a time, properly understanding the readme for the pkg module]
Use fs features to load config object as in this three-lines of code
filename="./config.json";
let rawdata = fs.readFileSync(filename);
let config = JSON.parse(rawdata);
config.json must be in same direcory of pkg executable
If you need to change path of config.json, you will able to specify full-path of this file using command line arguments.
These can be read at runtime using process.argv variable as explained here
When debugging Node.js code with --inspect-brk and Chrome Devtools, I can step into a function call pretty easily by pressing (F11). However, when it comes to require() calls, e.g.
var cmd = require(path.join(__dirname, a + '.js'))
it will first step into path.join() (which is reasonable), but then into internal/modules/cjs/helpers.js:77, not actually the start of ./a.js file. I do not care about how Node.js handles require calls, only the code inside the required module.
So the question is, while using step into on require calls, how can I quickly skip the internal code and go straight to the file "required"?
One method I found, is that I can open the required module directly in Devtools and set a breakpoint:
add it to the workspace via Sources => Filesystem => +
open it in sources tab
set a breakpoint at line 1
resume script execution (F8). It will run until reaching the breakpoint.
However, it requires the path containing the required module to be added to the workspace, which can be slow depending on the size of the folder. Also, files inside node_modules are ignored by default.
I just started playing with node debugger and noticed a node.js file which is invoked at the very beginning of node execution.
As the comment in the file says
This file is invoked by node::Load in src/node.cc, and responsible for bootstrapping the node.js core.
I'd like to change content of this file to something else (yes, I know there's no need to do that), is there a way to replace content of that file / specify path to new file without compiling node from source?
Short answer: Nope.
If I read the source correctly, the file node.js gets compiled into the resulting binary, as a string - the file itself does not exist anywhere on the filesystem so you cannot modify it and, for the same reason, you cannot tell Node to execute your own version of it.
Best look at the sources - mainly the LoadEnvironment method.
I've been going slightly crazy trying to figure this out. I have some certs that I need to pass through to an authentication client from my api; however, the application continues to throw ENOENT exceptions even though the file clearly exists within the same directory (I've fiddled with this to make sure). I'm using readFileSync, effectively doing the following:
key: fs.readFileSync('./privateKey.pem'),
Strangely, if I run this on a standalone Node server not as a part of an api, the file is able to be found without a problem. Is there some consideration I'm not aware of when trying to use readFileSync in such a scenario?
Thanks!
In node you need to be very careful with relative file paths. The only place where I'd ever really use them is in require('./_____') statements, where ./ to mean "relative to this file". However, require is kind of a special case because it is a function that node automatically creates per-file, so it knows the path of the current file.
In general, standard functions have no way of knowing the directory containing the script that happened to call a function, so in almost all cases, ./ means relative to the current working directory (the directory you were in when you ran node <scriptname>.js). The only time that is not the case is if your script or a module you use explicitly calls process.chdir to set the working directory to something else. The correct way to reference files relative to the current script file is to explicitly use an absolute path by using __dirname + '/file.js'.