Node.js, require.main === module
Quite late me answer, but i leave it here for reference.
When a file is the entry point of a program, it's the main module. e.g.
node index.js OR npm start
, theindex.js
is the main module & the entry point of our application.But we might need to run it just as a module, and NOT as a main module. This can happen if we
require
theindex.js
like so:
node -e "require('./index.js')(5,6)"
We can check if a file is the main module in 2 ways.
require.main === module
module.parent === null
Lets say that we have a simple index.js
file, that it either console.log()
,when it is the main module, or it exports a sum function, when it is not the main module:
if(require.main === module) {
// it is the main entry point of the application
// do some stuff here
console.log('i m the entry point of the app')
} else{
// its not the entry point of the app, and it behaves as
// a module
module.exports = (num1, num2) => {
console.log('--sum is:',num1+num2)
}
}
Ways to check the above condition:
node index.js
--> will printi m the entry point of the app
node -e "require('./index.js')(5,6)"
--> will print--sum is: 11
require
is a function. .main
is a property on that function so you can reference require.main
. That part of the doc you are referring to says that you can write code like this:
if (require.main === module) {
// this module was run directly from the command line as in node xxx.js
} else {
// this module was not run directly from the command line and probably loaded by something else
}
module
in that above code is a variable that is passed to all modules that are loaded by node.js so that code basically says that if require.main
is the current module, then the current module is what was loaded from the command line.
The code for setting that property is here: https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/helpers.js#L44.
When running ECMAScript Modules with Node.js, require.main
is not available. As of Node 13.9.0, there is not a succinct way to determine whether a module was run directly or imported by another module. It is possible that an import.meta.main
value will allow for such a check in the future (comment on the modules issue if you think this makes sense).
As a workaround, it is possible to check if the current ES module was run directly by comparing the import.meta.url
value to process.argv[1]
. For example:
import { fileURLToPath } from 'url';
import process from 'process';
if (process.argv[1] === fileURLToPath(import.meta.url)) {
// The script was run directly.
}
This does not handle the case where the script is called without the .js
extension (e.g. node script
instead of node script.js
). To handle this case, any extension could be trimmed from both import.meta.url
and process.argv[1]
.
The es-main
package (caveat: I am the author) provides a way to check if an ES module is run directly, accounting for the different ways it can be run (with or without an extension).
import esMain from 'es-main';
if (esMain(import.meta)) {
// The script was run directly.
}