Up to Node v8.5.0, publishing a module written in ES6 to NPMJS was a straightforward process: transpile the ES6 code using a tool like Babel, and publish to NPMJS the resulting lib
directory, while your GitHub repo contains the src
files.
With v8.5.0, Node has released experimental support for native modules (export
/import
) via the --experimental-modules
flag. It is now possible to publish purely-ES6 modules to NPMJS, and use them without any transpilation, as long as the files involved have an .mjs extension.
How can I publish an ES6 module (.mjs) so that it can also be used with older Node versions, which don't support ES native modules?
This is possible with 13.7.0+ using conditional exports (which as of 13.10.0+ are no longer experimental). It's not well documented or obvious how to do this in a completely backwards-compatible way, but here's the trick which I previously researched back when it was experiemental:
node_modules/mod/package.json
{
"main": "./lib.js",
"exports": {
".": [
{
"import": "./lib.mjs",
"require": "./lib.js",
"default": "./lib.js"
},
"./lib.js"
]
}
}
node_modules/mod/lib.js
exports.format = 'cjs';
node_modules/mod/lib.mjs
export const format = 'mjs';
Now it's possible to use both CommonJS:
main.js
const {format} = require('mod');
console.log(format);
$ node main.js
cjs
And ES Modules:
main.mjs
import {format} from 'mod';
console.log(format);
$ node main.mjs
mjs
Prior to this is was possible at one point to just use an extension-less main
entry in package.json
, but this feature was removed. See the revision history on this answer if interested.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With