Friday, June 21, 2024

ECMAScript module equivalent of CommonJS module usage: const x = require('myModule')(options);

A common, concise idiom of CommonJS modules that export factory functions is:

const instance = import('myModule')(myOptions);

This is concise and minimizes consumption of the name space.

With ECMAScript modules and the import declaration, the same or similar is not possible because the import declaration is not an expression that returns a value and it must be at the top level of the module: they cannot be within a block or function, including an immediately invoked function expression (IIFE).

Assuming the module in question exports a factory function as its default export, then the nearest equivalent would be something like:

import myFactory from 'myModule';

const instance = myFactory(myOptions);

If a named export the something like:

import { exportName as myFactory } from 'myModule';

const instance = myFactory(myOptions);

This is a little less concise: two lines of code instead of one, and an additional name consumed in the module name space. But otherwise gives the same result.

Something more equivalent is possible with the dynamic import keyword. This is function-like and can occur within a function, including an IIFE.

const instance = (await import('myModule')).default(myOptions);

This is only a little less concise than the CommonJS syntax. Similar construct is possible with named exports, by simply replacing 'default' with the name of the named export.

Using dynamic import keyword instead of the import declaration, one gives up the static analysis made possible by the import declaration, and there may be other benefits of the declaration over the keyword.

No comments:

Labels