babel-plugin-replace-import-extension

raw JSON →
1.1.5 verified Sat Apr 25 auth: no javascript

A Babel plugin that replaces file extensions in import statements and dynamic imports during transpilation. Current stable version is 1.1.5, with irregular release cadence. It solves the problem of co-existing ESModule and CommonJS builds by rewriting relative imports (starting with ./ or ../) so that, for example, .js becomes .mjs or .cjs. Unlike other extension replacement approaches, it handles dynamic imports by injecting a __transformExtension helper and avoids changes to bare specifiers (node_modules). It works with @babel/transform-modules-commonjs and is configured via an extMapping option.

error Cannot find module 'babel-plugin-replace-import-extension'
cause Missing npm package or incorrect plugin name in config.
fix
Run 'npm install --save-dev babel-plugin-replace-import-extension' and use plugin name 'replace-import-extension' (without the 'babel-plugin-' prefix) in .babelrc.
error TypeError: extMapping is not defined
cause Options object is missing the extMapping key or is malformed.
fix
Ensure config is an array with options object: ['replace-import-extension', { extMapping: { '.js': '.mjs' } }].
error Cannot read properties of undefined (reading 'call')
cause Plugin incompatible with Babel version (e.g., Babel 6 vs 7).
fix
Update to babel-plugin-replace-import-extension v1.1.5+ and ensure Babel 7 is installed.
error Dynamic import not transformed: 'import(' + expr + ')'
cause Dynamic import argument is not a constant string expression.
fix
Only string literals or concatenation of literals are supported. For variable expressions, consider a runtime helper.
gotcha Only relative imports (starting with './' or '../') are converted. Bare specifiers like 'lodash' are never modified.
fix Ensure all local file imports use relative paths if you expect extension replacement.
gotcha Dynamic import extension replacement only works when the import argument is a string literal or concatenation of string literals. Fully dynamic expressions like import(someVar) are not transformed.
fix Update to v1.1.4+ which handles constant dynamic imports. For fully dynamic, consider runtime helper.
breaking In v1.1.3, a fix was applied to avoid recursively loading babelrc or babel config, which could change behavior if your setup relied on recursive resolution.
fix Update to v1.1.3+ to avoid potential infinite loops.
gotcha The plugin injects a __transformExtension helper function for dynamic imports. This may conflict if you already have a global function or variable with that name.
fix Avoid using __transformExtension in your codebase, or check if plugin version allows renaming (not available by default).
deprecated No deprecation warnings yet, but the package has had infrequent releases (last release 2023). Verify compatibility with newer Babel versions.
fix Test with your Babel version; if issues, consider alternatives like babel-plugin-transform-import-extension or manual string replacement.
npm install babel-plugin-replace-import-extension
yarn add babel-plugin-replace-import-extension
pnpm add babel-plugin-replace-import-extension

Shows basic usage: install plugin, configure extMapping in Babel config, and expected transformation of static and dynamic imports.

// Install: npm install --save-dev babel-plugin-replace-import-extension
// Example .babelrc
{
  "plugins": [
    ["replace-import-extension", {
      "extMapping": {
        ".js": ".mjs"
      }
    }]
  ]
}

// Input
import { foo } from './module.js';
export { bar } from './utils.js';
const promise = import('./data' + '.js');

// Output
import { foo } from './module.mjs';
export { bar } from './utils.mjs';
// Dynamic import helpers are inserted at runtime
const promise = import(__transformExtension('./data' + '.js'));

// Build command (example): npx babel src --out-dir dist --out-file-extension .mjs