'How to choose 'module' instead of 'main' file in package.json

I have created some npm modules and compile them to:

  • commonJS (using exports.default =) and
  • esm (using export default)

I set up my package.json like so:

main: "index.cjs.js",
module: "index.esm.js"

When I npm install the package and I simple import it like:

import myPackage from 'my-package'

It will automatically choose the main file, not the module.

My question:

Is there a way to import the module file instead when doing import myPackage from 'my-package' in a JavaScript file?

Why I choose the commonJS file for "main":

I noticed that using Node, importing an esm file is not possible because of export default, it has to be commonJS. I have some simple helper JS functions like this and this, and I would want them to be usable to the widest audience. That's why I chose cjs for the "main" path in package.json.

Why I define a separate "module" in package.json:

Lots of famous libraries like Vue.js are already doing this. See further information on this Stackoverflow thread:

What is the "module" package.json field for?

Why do I want to be able to import the "module" file instead of the "main" file:

There is currently a bug in Rollup where it will not properly show JSDoc comments when coding after having imported a cjs file, but it does work when importing a es file.

The workaround I want to avoid:

Just set "main" to the esm file in package.json, right? But then all users who are using my packages in Node apps will not be able to use it anymore...

→ I'm really confused about all this as well, but I think I did enough research to make sense of all it. That being said, if anyone knows a better approach or any other advice, please do tell me in the comments down below!!



Solution 1:[1]

Nodejs does not support "module" but does support the newer "exports" spec.

https://nodejs.org/api/packages.html#exports

https://github.com/nodejs/node/blob/v16.14.0/lib/internal/modules/esm/resolve.js#L910

  "exports": {
    "import": "./main-module.js",
    "require": "./main-require.cjs"
  },

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jamie Pate