Can't require() default export value in Babel 6.x

JavascriptEcmascript 6Babeljs

Javascript Problem Overview


In Babel 5.x, I can write the following code:

app.js

export default function (){}

index.js

require('babel/register');
require('./app')();

Then, I can run node index.js with no errors. However, using Babel 6.x, running the following code

index.es6.js

require('babel-core/register');
require('./app')();

results in an error

> require(...) is not a function

I want to know why?

Javascript Solutions


Solution 1 - Javascript

TL;DR

You have to use

const app = require('./app').default;
app();

Explanation

Babel 5 used to have a compatibility hack for export default: if a module contained only one export, and it was a default export, it was assigned to module.exports. So, for example, your module app.js

export default function () {}

would be transpiled to this

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = function () {};

module.exports = exports["default"];

This was done purely for compatibility with require-ing Babel-transpiled modules (like you are doing). It was also inconsistent; if a module contained both named and default exports, it could not be require-d.

In reality, according to the ES6 module spec, a default export is no different than a named export with the name default. It is just syntactic sugar which can be statically resolved at compile time, so this

import something from './app';

is the same as this

import { default as something } from './app';

That being said, it appears that Babel 6 decided to drop the interoperability hack when transpiling modules. Now, your module app.js is transpiled as

'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

exports.default = function () {};

As you see, no more assignment to module.exports. To require this module, you need to do

const app = require('./app').default;
app();

Or, more concisely, and closer to your original code:

require('./app').default();

Solution 2 - Javascript

Just to follow up with the correct answer above.

If you wanna use default export behavior of babel@5, you can try babel-plugin-add-module-exports plugin.

It's working pretty well for me.

Solution 3 - Javascript

If this doesn't work

require('./app').default()

use

require('./app').default

Without the function call at the end.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionXGHeavenView Question on Stackoverflow
Solution 1 - JavascriptIgor RaushView Answer on Stackoverflow
Solution 2 - JavascripthaotangView Answer on Stackoverflow
Solution 3 - JavascriptSkaView Answer on Stackoverflow