• Web Developer
  • Posts
  • The Differences Between "export default xx" and "export {xx as default}"

The Differences Between "export default xx" and "export {xx as default}"

A comprehensive guide to understanding the differences between export default and named exports in JavaScript

The Basics of JavaScript Modules

Modules are self-contained pieces of code that can be imported and used in other modules. They help developers keep code organized, maintainable, and easy to understand.

To work with modules, you need to understand the import and export syntax. Here’s a quick recap:

  • import: Used to import named exports or default exports from other modules.

  • export: Used to export values, functions, or classes from a module, making them available for other modules to import.

There are two types of exports:

  • Named exports: You can have multiple named exports in a module. They are explicitly imported using their names.

  • Default exports: Each module can have only one default export. They are imported without specifying a name.

The Behavior of export { xxx as default }

In JavaScript, imports are live bindings, or references, rather than values. This means that when you import a variable from another module, you’re importing a reference to that variable, not a copy of its value.

Consider the following example:

// math.js
let value = 1;

setTimeout(() => {
  value = 888;
}, 500);

export { value as default };
// app.js
import value from './math.js';

setTimeout(() => {
  console.log(value); // ?
}, 1000);

In this case, guess what value is printed?

The answer is 888 not 1. This is because export exports references.

The Behavior of export default xxx

The export default syntax is used to export a default value from a module. However, when you use export default value, the current value is exported, not a live reference.

// math.js
let value = 1;

setTimeout(() => {
  value = 888;
}, 500);

export default value;
// app.js
import value from './math.js';

setTimeout(() => {
  console.log(value); // 1
}, 1000);

In this case, when the value variable in math.js changes, the value variable in app.js does not change. This is because value holds the current value at import time, not a live reference.

Export Reference Data Types

As you can see, we exported primitive data types earlier, but what if we exported reference data types?

// math.js
const value = {
  current: 1,
};

setTimeout(() => {
  value.current = 888;
}, 500);

export default value;
// OR
// export { value as default };
// app.js
import value from './math.js';

setTimeout(() => {
  console.log(value.current);
}, 1000);

As you can see, there is no difference between export default xxx and export { xxx as default } when dealing with reference data types. It can be understood that they are always reference types in JavaScript, and they will not be deeply copied when exported.

Best Practices and Recommendations

While both export default xxx and export { xxx as default } can be used to export default values, but their behavior differs in certain scenarios. Here are some recommendations to help you choose the right syntax:

  • Use export default xxx when you want to export a value, such as a string, or number, and you don't need live bindings.

  • Use export { xxx as default } when you need live binding, especially when the exported value may change over time (not recommended).

  • For reference data types, either syntax can be used, since they always export a reference.

  • A related suggestion: For code readability and maintainability, it is recommended to use named exports instead of default exports, here is why.

Conclusion

The differences between export default xxx and export { xxx as default } in JavaScript may appear subtle, but they can have an impact on your code's behavior. Hope this article is helpful to you.

If you find my content helpful, please consider subscribing. Thanks for your support!

Reply

or to participate.