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 not 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.