babel-plugin-cjs-esm-interop
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 likeimport.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
(withfile://
contextually)path.dirname(import.meta.url)
->__dirname
(withfile://
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.