Skip to content

Instantly share code, notes, and snippets.

@wojtekmaj
Created January 28, 2025 22:39
Show Gist options
  • Save wojtekmaj/17a0b0929c6e628c745ee889f1970bc2 to your computer and use it in GitHub Desktop.
Save wojtekmaj/17a0b0929c6e628c745ee889f1970bc2 to your computer and use it in GitHub Desktop.
A function to determine if a path is going to be loaded as ESM or CJS
import assert from 'node:assert';
import path from 'node:path';
async function esmOrCjs(filepath) {
const absolutePath = import.meta.resolve(filepath).replace('file://', '');
const ext = path.extname(absolutePath);
switch (ext) {
case '.mjs':
return 'esm';
case '.js': {
let currentDir = path.dirname(absolutePath);
while (currentDir !== path.dirname(currentDir)) {
const packageJsonPath = path.join(currentDir, 'package.json');
try {
const { default: packageJson } = await import(packageJsonPath, { with: { type: 'json' }});
const { type = 'commonjs' } = packageJson;
return type === 'module' ? 'esm' : 'cjs';
} catch {
// Ignore and move up one directory
}
currentDir = path.dirname(currentDir);
}
// Falls through
}
default:
return 'cjs';
}
}
// Test the function
// Known CJS module: bcryptjs
// Known ESM module: is-valid-nip
assert.equal(await esmOrCjs('bcryptjs'), 'cjs');
assert.equal(await esmOrCjs('is-valid-nip'), 'esm');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment