Skip to content

module: implement the "module" exports condition

This implements a new exports condition in Node.js that can be used to point to an ESM file no matter the package is loaded using import or require, so that it supports shipping patterns like this:

{
  "type": "module",
  "exports": {
    "node": {
      // On new version of Node.js, both require() and import get the ESM version
      "module": "./index.js",
      // On older version of Node.js, where "module" and require(esm) are not supported,
      // use the transpiled CJS version to avoid dual-module hazard. Library authors can decide
      // to drop support for older versions of Node.js when they think it's time.
      "default": "./dist/index.cjs"
    },
    // On any other environment, use the ESM version.
    "default": "./index.js"
  }
}

The "module" exports condition is chosen because it's been used by bundlers in the wild to support require(esm) in bundles targeting the Node.js environment. This patch implements the same condition for the native require(esm) implementation in Node.js to match bundler behaviors in the ecosystem.

The tests added in this patch match the output from webpack and esbuild bundles, will a small difference in rollup outputs. See https://github.com/joyeecheung/test-module-condition

Fixes: https://github.com/nodejs/node/issues/52173 Refs: https://github.com/joyeecheung/test-module-condition Refs: https://github.com/nodejs/node/issues/52697 Refs: https://webpack.js.org/guides/package-exports/#target-environment-independent-packages

Merge request reports

Loading