When using CommonJS modules in Node, you can detect whether a script is being run from the command line using require.main === module
.
What is an equivalent way to detect whether a script is being run from the command line when using ES Modules in Node (with the --experimental-modules
flag)?
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.
Perhaps more robust, but involving an extra import (via Rich Harris)
import {pathToFileURL} from 'url'
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
// module was not imported but called directly
}
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.
The other answers get close, but will miss the mark for a pretty typical usecase - cli scripts exposed by the bin
property in package.json
files.
These scripts will be symlinked in the node_modules/.bin
folder. These can be invoked through npx
or as scripts defined in the scripts
-object in package.json
. process.argv[1]
will in that case be the symlink and not the actual file referenced by import.meta.url
Furthermore, we need to convert the file path to an actual file://
-url otherwise it will not work correctly on different platforms.
import { realpathSync } from "fs";
import { pathToFileURL } from "url";
function wasCalledAsScript() {
// We use realpathSync to resolve symlinks, as cli scripts will often
// be executed from symlinks in the `node_modules/.bin`-folder
const realPath = realpathSync(process.argv[1]);
// Convert the file-path to a file-url before comparing it
const realPathAsUrl = pathToFileURL(realPath).href;
return import.meta.url === realPathAsUrl;
}
if (wasCalledAsScript()) {
// module was executed and imported by another file.
}
I would have posted this as a comment on the accepted answer, but apparently I'm not allowed to comment with a fresh account.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With