13

How can I detect if an ECMAScript module is the main module? This is easy for CommonJS modules (see Detect if called through require or directly by command line).

  • There is no require or require.main

  • No process.mainModule

  • The import.meta has no clues, only has url

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415

2 Answers2

9

You could use es-main.

From the package README:

import esMain from 'es-main';
 
if (esMain(import.meta)) {
  // Module run directly.
}

NOTE: This module will only work in a Node.JS environment, because the module code uses native Node.JS modules.

Take-Some-Bytes
  • 918
  • 1
  • 8
  • 21
  • 1
    `es-main` [does](https://github.com/tschaub/es-main/blob/8a569c0ca2345221e62a1dedeb00f9a29301178f/main.js#L20) `fileURLToPath(import.meta.url) === process.argv[1]`, possibly stripping the extension from the module path if it's missing from the script name. – Boris Verkhovskiy Sep 29 '21 at 19:49
3

In the browser I don't know, but in node with .mjs module the following seems to work :

const isMainModule = import.meta.url.endsWith(process.argv[1])

Explanation:

import.meta.url begins with the protocole file:// eg:

file:///path/to/my/module.mjs

but in node, process.argv[1] is shorter, eg:

/path/to/my/module.mjs

so endsWith is useful here.

Joseph Merdrignac
  • 3,510
  • 2
  • 19
  • 16
  • I suspect this doesn't work if the path contains any characters that are quoted in URLs, and may not work on Windows at all. – Dietrich Epp May 12 '22 at 04:43
  • Worked perfectly on linux with TypeScript + [@tsconfig/node16-strictest-esm/tsconfig.json](https://github.com/tsconfig/bases#node-16--esm--strictest-tsconfigjson) + `moduleResolution: "node"`. – Jan Święcki Jun 27 '22 at 13:56