Enabling ES6 Features (Import and Export Default) In Node.js with Babel
Published: 2020-04-14 14:09:05

Despite preponderance of tutorials on existing knowledge, it is important to document our learning experiences so that newbies can learn from different perspectives. Most important, some of the things we learned or issues encountered and later resolved are scattered all over the ecosystem in questions on Stackoverflow and Github and blogs and tutorials on medium and many blogs out there.

To get past them we glean information from many sources. As a late comer to programming writing and tutorial, my goal is to try and bring these disparate knowledge I encounter together so that anyone who happens upon it will learn from all those sources at once and from an updated viewpoint. 

Sometimes, it is important to read the perspective of a learner so those who are learning can have a feel of what it was like before crossing the rubicon to the other side, from the unknown to the known.

[Node.js](https://medium.com/r/?url=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F40294870%2Fmodule-exports-vs-export-default-in-node-js-and-es6) is the Javascript standard platform for server-side development. Express is the oldest and most popular web framework for Node.js. Most beginners start from learning express. 

The default standard for Node.js module handling is CommonJS. Where we have [module.exports and require](https://blog.risingstack.com/node-js-at-scale-module-system-commonjs-require/). For Node.js in ES6 environment we will need a compiler to translate ES6 to [CommonJS](https://blog.risingstack.com/node-js-at-scale-module-system-commonjs-require/).

Recent Node.js 13.2.+ supports [ECMAScript modules](https://medium.com/r/?url=https%3A%2F%2Fhacks.mozilla.org%2F2018%2F03%2Fes-modules-a-cartoon-deep-dive%2F) inbuilt but the LTE (Latest Stable Edition) v12.16.2 does not. The latest support most likely will take some months or even another year before projects begin to move to that version features. The support for [Import and Export statements](https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm) in the LTE needs to be enabled and run via - experimental-module to use them. Example:

"start: node - experimental-modules ./src/index.js"

The key to enabling this behaving is including the below in package.json
["type": "module"](https://nodejs.org/api/esm.html)

Again, one of the [typical errors](https://stackoverflow.com/questions/61146112/error-while-loading-config-you-appear-to-be-using-a-native-ecmascript-module-c) that will be encountered is:

Error while loading config - You appear to be using a native ECMAScript module configuration file, which is only supported when running Babel asynchronously

This is because your project would have generated or you may have added babel config as Javascript file extension(babel.config.js). [Babel](https://babeljs.io/), very popular, "is a JavaScript compiler." Simply as it is on the [github page](https://github.com/babel/babel),

Babel is a tool that helps you write code in the latest version of JavaScript. When your supported environments don't support certain features natively, Babel will help you compile those features down to a supported version.

So we get modern Javascript features with Babel compiler. So in our Node.js project, the use of .mjs, cjs or js extension for the babel.config.extension is one of the requirements. For v12. the right file extension is .cjs which means CommonJS. So the configuration at the root of my directory becomes babel.config.cjs. See more about it [here](https://babeljs.io/docs/en/config-files) on babel docs. For deeper dive read [this](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/).

Don't forget that for all these to work on Node.js, this configuration is necessary in the babel.config.cjs.

module.exports = { 
  presets: [
     [ 
       '@babel/preset-env',
       {
        targets: {
          node: 'current'
         }
       }
     ]
   ]
};
Here is a related interesting read I will [recommend](https://humanwhocodes.com/blog/2019/01/stop-using-default-exports-javascript-module/). #Staysafe.