Detect Whether Es Module Is Run From Command Line In Node
Solution 1:
Use
if (import.meta.url === `file://${process.argv[1]}`) {
// module was not imported but called directly
}
See the MDN docs on import.meta
for details.
Update Sep 27, 2021
Perhaps more robust, but involving an extra import (via Rich Harris)
import url from'url'if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
// module was not imported but called directly
}
Solution 2:
There is none - yet (it's still experimental!). Although the prevailing opinion is that such a check is a bad practice anyway and you should just provide separate scripts for the library and the executable, there is an idea to provide a boolean import.meta.main
property for this purpose.
Solution 3:
The module
global variable will be defined in CommonJS, but won’t exist at
all in an ES module. Yes, there is an inconsistency there, that ES modules are
the things that don’t have module
variables.
You can check for an undefined variable by seeing if typeof v
is the string
(not value!) 'undefined'
.
That turns into:
const inCommonJs = typeofmodule !== 'undefined';
console.log(`inCommonJs = ${inCommonJs}`);
If we put that exact code into both .cjs
and .mjs
files, we get the correct answers:
$ node foo.mjs
inCommonJs = false$ cp foo.mjs foo.cjs
$ node foo.cjs
inCommonJs = true
Solution 4:
I like import.meta.url === `file://${process.argv[1]}`
, but it does not work in Windows inside bash shell. This is the alternative that is only checking the basename:
const runningAsScript = import.meta.url.endsWith(path.basename(process.argv[1]));
Solution 5:
It looks like there is a documented way to do this now:
if (require.main === module) {
console.log('executed directly');
. . .
}
Post a Comment for "Detect Whether Es Module Is Run From Command Line In Node"