Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

export default vs module.exports differences

This works:

import {bar} from './foo';
bar();

// foo.js
module.exports = {
 bar() {}
}

And this works:

import foo from './foo';
foo.bar();

// foo.js
export default {
 bar() {}
}

So why doesn't this work?

import {bar} from './foo';
bar();

// foo.js
export default {
 bar() {}
}

It throws TypeError: (0 , _foo.bar) is not a function.

like image 952
Tim Scott Avatar asked Jan 15 '17 20:01

Tim Scott


People also ask

What is difference between export and export default?

Exports without a default tag are Named exports. Exports with the default tag are Default exports. Using one over the other can have effects on your code readability, file structure, and component organization. Named and Default exports are not React-centric ideas.

Why you should not use export default?

Refactoring. Default exports make large-scale refactoring impossible since each importing site can name default import differently (including typos). On the contrary, named exports make such refactoring trivial.

Why would you create a default export in a module?

Default Exports: Default exports are useful to export only a single object, function, variable. During the import, we can use any name to import.


2 Answers

When you have

export default {
  bar() {}
}

The actual object exported is of the following form:

exports: {
  default: {
    bar() {}
  }
}

When you do a simple import (e.g., import foo from './foo';) you are actually getting the default object inside the import (i.e., exports.default). This will become apparent when you run babel to compile to ES5.

When you try to import a specific function (e.g., import { bar } from './foo';), as per your case, you are actually trying to get exports.bar instead of exports.default.bar. Hence why the bar function is undefined.

When you have just multiple exports:

export function foo() {};
export function bar() {};

You will end up having this object:

exports: {
  foo() {},
  bar() {}
}

And thus import { bar } from './foo'; will work. This is the similar case with module.exports you are essentially storing an exports object as above. Hence you can import the bar function.

I hope this is clear enough.

like image 131
Nelson Yeung Avatar answered Sep 30 '22 02:09

Nelson Yeung


curly bracket imports {} are only for named exports. for default export you are not expected to use them during import. if you want still use {} for your 3rd case this should work.

import {default as bar } from './foo';
bar();

// foo.js
export default {
  bar() {}
}
like image 33
pref Avatar answered Sep 28 '22 02:09

pref