Skip to content

Babel plugin and helper functions for interoperation between Node.js native ESM and Babel ESM

License

Notifications You must be signed in to change notification settings

qnighy/node-cjs-interop

Repository files navigation

babel-plugin-node-cjs-interop, swc-plugin-node-cjs-interop and node-cjs-interop: fix the default import interoperability issue in Node.js

The problem to solve

Consider the following modules:

// a.js

export default function greet() {
  console.log("Hello, world!");
}
// b.js

import greet from "a.js";

greet();

They usually work, unless the following conditions are met:

  • a.js (the module being imported) is a simulated ESM. That is, the module is transpiled as a CommonJS module (by Babel or TypeScript) before execution. And,
  • b.js (the importing module) is a native ESM, That is, the module is run on Node.js' native ES Module support.

You can reproduce the above condition by placing the following files:

// a.cjs

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true,
});
exports.default = greet;

function greet() {
  console.log("Hello, world!");
}
// b.mjs

import greet from "./a.cjs";

greet();
$ node ./b.mjs
./b.mjs:3
greet();
^

TypeError: greet is not a function
    at ./b.mjs:3:1
    at ModuleJob.run (node:internal/modules/esm/module_job:185:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:65:12)

Solution 1: Babel/SWC plugin

Install the babel plugin:

npm install -D babel-plugin-node-cjs-interop
# or:
yarn add -D babel-plugin-node-cjs-interop

Configure it in your Babel configuration:

// .babelrc.js or babel.config.js

export default {
  presets: [
    /* ... */
  ],
  plugins: [
    // ...
    [
      "babel-plugin-node-cjs-interop",
      {
        packages: ["styled-components", "@babel/helper-plugin-test-runner"],
      },
    ],
  ],
};

See the package's README for details.

SWC version

There is the plugin for SWC too. See the package's README for details.

Solution 2: manually inserting the wrapper

npm install -D node-cjs-interop
# or:
yarn add -D node-cjs-interop
import styledOrig from "styled-components";
import { interopImportCJSDefault } from "node-cjs-interop";

const styled = interopImportCJSDefault(styledOrig);

See the package's README for details.

About

Babel plugin and helper functions for interoperation between Node.js native ESM and Babel ESM

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •