npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

babel-plugin-replace-import-extension

v1.1.4

Published

Babel plugin to replace extension of file name written in import statement and dynamic import

Downloads

16,064

Readme

babel-plugin-replace-import-extension

Babel plugin to replace extension of file name written in import statement and dynamic import.

Installation

npm install --save-dev babel-plugin-replace-import-extension

Example

With the option:

{ "extMapping": { ".js": ".mjs" }}

In

import { foo } from './module1.js';
export { bar } from './module2.js'; // Works for re-exporting
const promise = import('./module3' + '.js'); // Also works for dynamic import!

Out

import { foo } from './module1.mjs';
export { bar } from './module2.mjs';

// In dynamic import, function to replace extension is inserted.
// Note the actual code is not exactly the same.
const promise = import(__transformExtension('./module3' + '.js'));

Why We Need This Plugin?

When you develop a npm package that includes both ESModule and CommonJS version of the code, there is two ways to tell Node which file is which version.

  • Distinguish files by their extension, mjs for ESModule and cjs for CommonJS.
  • If two versions are located in separate directories, put a package.json with a type field specified to the directory.

If you choose the former and you write your code in ESModule and transpile it to CommonJS, you have to change the extension of the files while transpiling.

In Babel CLI, extension of the output file name can be changed with --out-file-extension option. But the file name referenced inside the code is not changed. In this case, this plugin comes into play.

Note that the conversion is performed only on relative file name (starts with ./ or ../), because built-in packages or packages importing from node_modules should not be converted.

Usage

If project root package.json has type field of module, Babel config of

{
  "plugins": [
    ["replace-import-extension", { "extMapping": { ".js": ".cjs" }}],
    ["@babel/transform-modules-commonjs"]
  ]
}

will convert the file extension from .js to .cjs and convert ESModule to CommonJS, allowing both version's code exist together while Node can handle each versions correctly. (@babel/plugin-transform-modules-commonjs must be installed.) Or if you also need other translations, @babel/env preset can be used together like,

{
  "presets": [["@babel/env"]],
  "plugins": [
    ["replace-import-extension", { "extMapping": { ".js": ".cjs" }}]
  ]
}

If project root package.json has no type field or has type field of cjs, ESModule files must be explicitly marked by mjs extension, which can be done by Babel config of

{
  "plugins": [
    ["replace-import-extension", { "extMapping": { ".js": ".mjs" }}]
  ]
}

Once again, --out-file-extension option must be used together to change the output file extension.

Supporting both mjs and cjs in the same package

If you are using .mjs for your source files, you can use babel to generate .cjs files for backwards compatibility:

{
  "presets": [["@babel/env"]],
  "plugins": [
    ["replace-import-extension", { "extMapping": { ".mjs": ".cjs" }}]
  ]
}

In your package.json specify the entries accordingly:

{
  "main": "dist/index.cjs",
  "module": "src/index.mjs",
  "source": "src/index.mjs",
  "exports": {
    ".": {
      "require": "dist/index.cjs",
      "import": "src/index.mjs"
    },
    "src/index.mjs": {
      "import": "src/index.mjs"
    },
    "dist/index.cjs": {
      "require": "dist/index.cjs",
      "import": "dist/index.cjs"
    }
  },
  "scripts": {
    "build.cjs": "babel -d dist/ src/ --out-file-extension .cjs",
    "prepare": "npm run build.cjs"
  }
}

Options

extMapping

Object, defaults to {}.

Mapping of original extension to converted extension. Leading . is mandatory.

Both the original and the converted extensions can be empty string '', which means no extension. You can use this feature to add or remove extension.