确定是否直接使用 NodeJS 模块调用脚本

Determining if script was called directly with NodeJS Modules

你怎么知道一个脚本是直接用 NodeJS 模块调用的? (即 package.json 指定 "type": "module"

例如,您可能有两个文件,script1.jsscript2.js 我们可能会在 script2.js 中使用 script1.js 的一些实用程序,但我们不希望 script1.js导入时执行。

// script1.js
export const func = () => "A reusable function's output"

// TODO if executed with "node script1.js" execute this:
console.log("I did an operation: " + func())
// script2.js
import { func } from "./script1.js"

// There shouldn't be any output because script1 wasn't called directly!

在以前版本的 NodeJS(commonjs 样式)中,您可以使用 if (!module.parent) { /* ... */ },但是当使用带有 "type": "module"

的 NodeJS 时,模块未定义

您可以检查:

process.argv[1] 它将是启动 nodejs 的脚本的路径。

在文档中,他们展示了一个示例,其中命令行为:

$ node process-args.js

将为 process.argv[1] 显示此内容:

/Users/mjr/work/node/process-args.js

如果你解析文件名,那么你可以将它与你自己模块的文件名进行比较。

 import path from 'path';

 function getLaunchFile() {
     return path.basename(process.argv[1]);
 }

 if (getLaunchFile() === "script1.js") {
     // I am the main launch file
 }

而且,如果你想动态获取当前模块的文件名,你可以使用这个:

哪个会让你做这个:

import { fileURLToPath } from 'url';

function isLaunchFile() {
    const launchFile = process.argv[1];
    const moduleFile = fileURLToPath(import.meta.url);
    return moduleFile === launchFile;
}

为了后代,我已经将@jfriend00 的方法打包到一个名为 is-launch-file

的库中
import isLaunchFile from "is-launch-file"
 
if (isLaunchFile(import.meta.url)) {
    // This file was called directly.
}

原始解决方案的所有功劳都归功于@jfriend00。