How to correctly use ES6 "export default" with CommonJS "require"?
Asked Answered
M

2

34

I've been working through Webpack tutorial. In one of the sections, it gives the code example that contains one line of essence to this question:

export default class Button { /* class code here */ }

In the next section of said tutorial, titled "Code splitting", the class defined above is loaded on demand, like this:

require.ensure([], () => {
    const Button = require("./Components/Button");
    const button = new Button("google.com");
    // ...
});

Unfortunately, this code throws an exception:

Uncaught TypeError: Button is not a function

Now, I know that the right way to include ES6 module would be to simply import Button from './Components/Button'; at the top of the file, but using a construct like that anywhere else in the file makes babel a sad panda:

SyntaxError: index.js: 'import' and 'export' may only appear at the top level

After some fiddling with previous (require.ensure()) example above, I realized that ES6 export default syntax exports an object that has property named default, which contains my code (the Button function).

I did fix the broken code example by appending .default after require call, like this:

const Button = require("./Components/Button").default;

...but I think it looks a bit clumsy and it is error-prone (I'd have to know which module uses ES6 syntax, and which uses good old module.exports).

Which brings me to my question: what is the right way to import ES6 code from code that uses CommonJS syntax?

Madden answered 13/3, 2016 at 13:49 Comment(0)
R
28

To use export default with Babel, you can do 1 of the following:

  1. require("myStuff").default
  2. npm install babel-plugin-add-module-exports --save-dev

Or 3:

//myStuff.js
var thingToExport = {};
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = thingToExport;
Rabblerouser answered 13/3, 2016 at 17:44 Comment(1)
the fastest way to find out all details is using babel-cli to transpile one file and see what the result is. The defineProperty-thing is just needed... - so thanks for pointing all this outSeverini
F
-1

If someone using the gulp + browserify + babelify to bundle js using in client-end.

Try following code [gulpfile.js]:

browserify({
  entries: "./ui/qiyun-ui/javascripts/qiyun-ui.src.js",
  standalone: "qyUI" // To UMD
})
.transform(babelify, {
  presets: ["env"],
  plugins: ["add-module-exports"] // export default {} => module.exports = exports['default'];
})
.bundle()

Don't forget to install this package: https://www.npmjs.com/package/babel-plugin-add-module-exports

Fuge answered 9/1, 2018 at 5:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.