【问题标题】:`if __name__ == '__main__'` equivalent in javascript es6 modules`if __name__ == '__main__'` 等效于 javascript es6 模块
【发布时间】:2016-04-22 21:59:32
【问题描述】:

是否可以检查 JavaScript 文件是直接运行还是作为 es6 模块导入的一部分需要。

例如包含一个主脚本。

// main.js
import './other';

if (mainTest){
  console.log('This should run');
}

导入依赖项。

// other.js
if (mainTest){
  console.log('This should never run');
}

包括<script src=main.js></script> 应该导致来自main.js 的控制台消息,而不是other.js。

我找到了answer to this question with regards to node,但我对 es6 导入特别感兴趣

【问题讨论】:

标签: javascript module ecmascript-6


【解决方案1】:

ES6 模块的替代方案是 Node.js 中的 now supported。使用新的 import.meta 内置函数。 (不要忘记在package.json 中设置"type": "module"。)

示例

// main.js
import "./lib.js"
import { fileURLToPath } from "url";

if (process.argv[1] === fileURLToPath(import.meta.url)) {
  console.log("I print to stdout!");
}
// lib.js
import { fileURLToPath } from "url";

if (process.argv[1] === fileURLToPath(import.meta.url)) {
  console.log("I don't run, because I'm an imported module.");
}

$ node main.js 输出:

I print to stdout!

实用功能

我喜欢只 import { isMain } from "./lib/utils.js" 并将 import.meta.url 传递给 isMain()

import { argv } from "process"
import { fileURLToPath } from "url"
/**
 * Check if a module is the main module launched with the node process.
 * Meaning the module is NOT imported by another module,
 * but was directly invoked by `node`, like this: `$ node main.js`
 *
 * @example
 * ```js
 * // main.js
 * import lib from "./lib.js"
 * import { isMain } from "./utils.js"
 *
 * if (isMain(import.meta.url)) {
 *   console.log("I print to stdout")
 * }
 *
 * // lib.js
 * import { isMain } from "./utils"
 *
 * if (isMain(import.meta.url)) {
 *   console.log("I don't run, because I'm an imported module")
 * }
 * ```
 *
 * @param {string} moduleUrl needs to be `import.meta.url`
 * @returns {boolean} true if the module is the main module
 */
export function isMain(moduleUrl) {
  const modulePath = fileURLToPath(moduleUrl)
  const [_binPath, mainScriptPath] = argv
  return modulePath === mainScriptPath
}

【讨论】:

    【解决方案2】:

    如果您在 Node.js 中使用类型模块运行,并且不要将文件命名为相同,并且不想导入库,并且想要 1 行代码,那么这将起作用:

    if(process.argv[1].split('/')[process.argv[1].split('/').length - 1] === import.meta.url.split('/')[import.meta.url.split('/').length - 1]) {
      console.log("called from commandline")
    } else {
      console.log("imported")
    }
    

    【讨论】:

      【解决方案3】:

      module.parent 在 Node.js v14.6.0 中已弃用,但我们可以使用 require.main

      function main() {
          console.log("You're running the main file!");
      }
      
      if (require.main === module) {
          main();
      }
      

      相关答案可以在here找到。

      【讨论】:

      • 它只适用于 commonjs 而不是 es6 模块。
      【解决方案4】:

      module.parent 会帮助你:

      if(module.parent) {
          console.log('required module')
      } else {
          console.log('main')
      }
      

      【讨论】:

      • 这似乎也是特定于节点的。
      • 是的,ES6 模块不会在这里添加任何东西。另外,我想它可以用浏览器的 Webpack 以某种方式模拟。
      • 我正在寻找可以在浏览器中使用的东西。目前我使用汇总作为我的捆绑机制
      • 注意:module.parent 现在是deprecated
      【解决方案5】:

      我看到的解决方案只是在您要导入的脚本中定义变量。 IE。您在main.js 中定义mainTest,然后使用现有的if 块。

      【讨论】:

        猜你喜欢
        • 2011-06-09
        • 2011-01-15
        • 2015-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-22
        相关资源
        最近更新 更多