Skip to main content

babel-plugin-cjs-esm-interop

Build Status npm version

Transform the differences between CommonJS code (.js, .cjs) and ECMAScript module code (.mjs), based on the official Node.js documentation.

We suggest writing your code as ESM (.mjs, .ts, .tsx, .js with module type) and compiling down to CJS instead of the reverse. This means using new syntax like import.meta, import(), etc!

// Input: mjs
const self = import.meta.url;
// Output: cjs
const self = __filename;

Installation

yarn add --dev babel-plugin-cjs-esm-interop

Add the plugin to your root babel.config.* file and configure the output format option with either mjs (default) or cjs.

module.exports = {
plugins: [['babel-plugin-cjs-esm-interop', { format: 'mjs' }]],
};

Requirements

  • Linux, OSX, Windows
  • Node 18.12+

Transforms

The following transforms and error handling are applied.

CJS output

  • export, export default
    • Will throw an error if used.
  • import.meta.url -> __filename (with file:// contextually)
  • path.dirname(import.meta.url) -> __dirname (with file:// contextually)

MJS output

  • require(), require.resolve(), require.extensions, require.cache, exports.<name>, module.exports, process.env.NODE_PATH
    • Will throw an error if used.
  • __filename -> import.meta.url
  • __dirname -> path.dirname(import.meta.url)

How to's

If you want to support ESM code, you'll need to move away from certain features, in which you have a few options.

What to replace require() with?

  • Use import() for JS files. Be aware that this is async and cannot be used in the module scope unless top-level await is supported.
  • Use the fs module for JSON files: JSON.parse(fs.readFileSync(path))
  • Use module.createRequire(), which returns a require-like function you may use. More info.

What to replace require.resolve() with?

  • Use the resolve npm package.
  • Use module.createRequire(), which returns a require-like function with a resolver you may use. More info.

Index

Functions

Interfaces