Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check in NodeJS JavaScript runtime code if running as CommonJS or ESM Module

I am writing a JS function that could be used in both CommonJS & ESM Module system.

But it would do something different depending on which it ran in.

Is there any way to test in runtime code which system we are in?

like image 825
ChrisNY Avatar asked Jul 08 '26 11:07

ChrisNY


1 Answers

My approach uses a separate spawned process to detect the current module system a file is running under.

The script run as a child process:

checkType.js

import('node:process').then(({ stdout }) => {
  try {
    require.main
  } catch {
    stdout.write('module')
    return 'module'
  }

  try {
    import.meta
  } catch {
    stdout.write('commonjs')
    return 'commonjs'
  }
})

The parent process used to determine the runtime module context:

moduleType.js

import { resolve } from 'node:path'
import { spawnSync } from 'node:child_process'

export const moduleType = () => {
  const { stdout, stderr } = spawnSync('node', [resolve(import.meta.dirname, 'checkType.js')])
  let type = 'unknown'

  // Only one of these will be non-falsy strings
  const err = stderr.toString()
  const out = stdout.toString()

  /**
   * Based on error messaging from v8
   * @see https://github.com/nodejs/node/blob/bc13f23f7e25d750df9b0a7bfe891a3d69f995f3/deps/v8/src/common/message-template.h#L124
   */
  if (/outside a module/i.test(err)) {
    type = 'commonjs'
  }

  if (out) {
    type = out
  }

  return type
}

moduleType.js gets converted to both ESM and CJS modules during a build, and this might be useful in other toolchains like TypeScript.

some-file.ts

import { moduleType } from 'node-module-type'

console.log(`ts file running in module mode ${moduleType()}`

Now when you execute this file with something like tsx, the module type is determined by whatever the "type" is in package.json, or the file extension (.cts or .mts).

Whether this is ultimately useful depends on if any use cases exist beyond publishing dual packages. FWIW, I made this functionality available on npm under node-module-type.

like image 63
morganney Avatar answered Jul 11 '26 02:07

morganney



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!