The First Cry of Atom Today is the first day of the rest of my life.

Babel add-module-exports

I’m now trying to convert td-client-node codebase to ES6.

Since ES6 provides us bunch of useful features and syntax which are not available in ES5. But nodejs (and backend V8) does not support full functionalities of ES6. You can check the overview of supported ECMAScript features by nodejs in this website. This blog post explained the detail of milestone to support ES6 features.

So here is Babel. Babel is a transpiler to convert ES6 codebase into ES5 code which can be run on nodejs. The usage of Babel is described here in detail. And overall Babel can convert my td-client-node codebase properly except for one thing.

Babel now does not support CommonJS default export behavior. In short, we cannot export a class directly from module anymore.

var TD = require('td');

val client = new TD(process.env.TREASURE_DATA_API_KEY);

It throws such exception.

var client = new TD(process.env.TREASURE_DATA_API_KEY);
             ^

TypeError: TD is not a constructor
    at Object.<anonymous> (/path/to/test.js:4:14)
    at Module._compile (module.js:573:30)
    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)

Looking the transpiled code, we can detect the cause. We need to refer the client class through default properly of exported object.

exports.default = TDClient;

Although we expect module.exports = TDClient, Babel core does not support such thing.

Then you can use Babel add-module-exports plugin. What this plugin does is very simple. Just adding one line, exports.default = exports['default'].

exports.default = TDClient;
module.exports = exports['default'];

By using this plugin you don’t have to use ugly default keyword in require statement.

$ npm install babel-plugin-add-module-exports --save-dev
$ cat .babelrc
{
  "presets": ["env"],
  "plugins": [
    "add-module-exports"
  ]
}

Reference