最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to choose 'module' instead of 'main' file in package.json - Stack Overflow

programmeradmin4浏览0评论

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!!

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!!

Share Improve this question edited Sep 27, 2018 at 10:23 mesqueeb asked Sep 26, 2018 at 4:26 mesqueebmesqueeb 6,3247 gold badges51 silver badges85 bronze badges 11
  • 1 I don't think 'module` is a valid key for package.json. You might want to work around using something explained here: stackoverflow.com/a/16631079/1971378. I have elaborated that in an answer. Hope that helps. – trk Commented Sep 26, 2018 at 5:17
  • ... on second thoughts is there a reason why you are not pointing main directly to index.es.js ? – trk Commented Sep 26, 2018 at 5:20
  • 1 @82Tuskers Thanks for the link, but your answer is a bit "off". First, module in package.json is widely used by many famous libraries & frameworks. Second, your link points to an explanation on how to export different functions... I'm talking about the same function compiled as both CommonJS and ES5. Finally, my reason for directing main to the commonJS one was to make sure it works locally with node as well. If I'd point to the index.es.js file - which uses export default - node will not run it. – mesqueeb Commented Sep 26, 2018 at 5:22
  • What is the goal? If you're using this module in Node, then you should configure the main to point at the "module" script. If you're using this in a browser then it is up to you to choose how it is delivered to the client, not the package.json. – Jake Holzinger Commented Sep 26, 2018 at 5:24
  • @JakeHolzinger Oh? In my experience node can't import files compiled to es5 (which use export default) but only commonJS compiled files. That's why I set main: "index.cjs.js". > " If you're using this in a browser then it is up to you to choose how it is delivered to the client, not the package.json" I'm not sure what you mean by this. If I write a small JS helper function that people can npm i and import x from 'my-pkg' then the JavaScript will automatically choose the file set at "main":, I don't think you can choose another inpoint. That is exactly what my question is! : D – mesqueeb Commented Sep 26, 2018 at 5:28
 |  Show 6 more comments

2 Answers 2

Reset to default 6

Just don't use extension for main file and have es6 and CommonJS version as two separate files with the same name and in the same directory, but with different extension, so:

index.js // transpiled CommonJS code for old nodejs
index.mjs // es6 module syntax

and in package.json:

{
  "main": "index"
}

If node is launched with --experimental-modules flag, it would use *.mjs file, otherwise *.js.

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"
  },
发布评论

评论列表(0)

  1. 暂无评论