ESM package works in a different fashion from CJS. ESM package imports required modules asynchronously and have no support for several functions related to system files and directories. ESM follows Javascript cores that are implemented in the browser. There is no such entity like __dirname
, __filename
, require()
, and so on.
If we want to detect whether a module is a main module that is being run in CJS, we can compare the value of require.module
and module
. If it is the same, the module is being run as the main module. Meanwhile, for a module in the ESM package, we can use the following approach.
- Get the value of
process.argv[1]
that contains information of the main file that is being called by Node. - Get the value of
import.meta.url
that contains information of the module's location that is being accessed. - Transform the information to have a similar format, then compare it.
For example, we have a module in an ESM package, named module1.js
.
import { realpath } from 'fs/promises';
import { fileURLToPath } from 'url';
const moduleLocation = import.meta.url;
const modulePath = fileURLToPath(moduleLocation);
const moduleRealPath = await realpath(modulePath);
const mainPath = process.argv[1];
const mainRealPath = await realpath(mainPath);
if (moduleRealPath === mainRealPath) {
console.log('It is run as main module');
}
export default () => { console.log('It is run as an imported module') };
Then, we create another module as a program that calls the previous module, named module2.js
.
import module1 from './module1.js';
module1();
Finally, we can check the result by calling both scripts using Node.
node module1.js
The command above will output a message, "It is run as the main module".
node module2.js
While, the command above will output only a message, "It is run as an imported module".
Comments
Post a Comment