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 | Show 6 more comments2 Answers
Reset to default 6Just 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"
},
main
directly toindex.es.js
? – trk Commented Sep 26, 2018 at 5:20main
to the commonJS one was to make sure it works locally withnode
as well. If I'd point to theindex.es.js
file - which usesexport default
- node will not run it. – mesqueeb Commented Sep 26, 2018 at 5:22main
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 thepackage.json
. – Jake Holzinger Commented Sep 26, 2018 at 5:24export default
) but only commonJS compiled files. That's why I setmain: "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 cannpm i
andimport 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