I've been using named export and default export extensively in my React and I came across these 2 similar syntaxes.
export default from './Button';
export { default } from './Button';
Can somebody tell me what is their difference? It seems like they are doing the same thing with the former VSCode Go To Definition
function not working on the former.
I've been using named export and default export extensively in my React and I came across these 2 similar syntaxes.
export default from './Button';
export { default } from './Button';
Can somebody tell me what is their difference? It seems like they are doing the same thing with the former VSCode Go To Definition
function not working on the former.
7 Answers
Reset to default 2What is the difference
There is a huge difference between the two, one is in standard ES6 and the other is yet a proposal.
// Standard ES6
export { default } from './Button';
This is standard ES6: it is exporting the Default of Button from the current module (without altering the local scope of the current module)
// A Proposal
export default from './Button';
This is a proposal, and that explains why it does not work at vscode Here is the proposal https://github./tc39/proposal-export-default-from (still stage 1)
Basically according to the proposal both should work exactly the same, the proposal is just another more elegant way of writing it - so that it matches how we export default in Standarad ES6.
Look here if you want to see why exactly the author of the proposal made it https://github./tc39/proposal-export-default-from#mon-concerns
Why they both work
JavaScript as it is often used today is no longer a mere interpreted language. It is more like a transpiled langauge, where what we write ( though in JavaScript or something similar) is still not the same that we send for the JS engine.
Now it works for you ( In your Code ) because part of your build system is taking code written with this proposal and transpiling it to standarad ES6. If we were to speak about Babel the most popular JS transpiler, this syntax is enabled with the following plugin https://babeljs.io/docs/en/next/babel-plugin-proposal-export-default-from.html.
Should I keep using the proposal
Preferably no, this is a proposal in state 1, even if Babel - or any other transpiler - makes it work, there is a chance that it never makes it to Standarad JavaScript. And if that happens there will e a time in the future will you will have to re-write that code.
ES6 provides us to import a module and use it in other files. Strictly speaking in React terms, one can use stateless ponents in other ponents by exporting the ponents from their respective modules and using them in other files.
ES6 provides two ways to export a module from a file: named export and default export.
Named Export: (export)
With named exports, one can have multiple named exports per file. Then import the specific exports they want to be surrounded in braces. The name of the imported module has to be the same as the name of the exported module.
// imports
// ex. importing a single named export
import { MyComponent } from "./MyComponent";
// ex. importing multiple named exports
import { MyComponent, MyComponent2 } from "./MyComponent";
// ex. giving a named import a different name by using "as":
import { MyComponent2 as MyNewComponent } from "./MyComponent";
// exports from ./MyComponent.js file
export const MyComponent = () => {}
export const MyComponent2 = () => {}
Import all the named exports onto an object:
import * as MainComponents from "./MyComponent";
// use MainComponents.MyComponent and MainComponents.MyComponent2
here
Default Export: (export default)
One can have only one default export per file. When we import we have to specify a name and import like:
// import
import MyDefaultComponent from "./MyDefaultExport";
// export
const MyComponent = () => {}
export default MyComponent;
For multiple exports from a file, you should go with Named exports
, which you can import using {}
. If there is only one export, ideally you should go with Default export
.
Please refer Javascript Exports for further understanding. Please note default
is a keyword.
Here is a nice article to make clear de differences between them, but the biggest difference is that you could only have one Default Export
per file, as:
export Button from './Button';
And in cases where you need to have multiple items exported you should go with the Named Export
, as:
export { ButtonAccept, ButtonCancel, ButtonInfo } from './Button';
For the documentation, you can refer to link shared by sSD and Alberto and also answer of Clue. I have created an example for understanding it better and to help you as well.
Here is the link: https://codesandbox.io/s/summer-surf-o78v1
Code if the link expires:
App Structure is:
src
├── index.js
├── button
│ ├── index.js
│ ├── Button.js
src/index.js
import React from "react";
import ReactDOM from "react-dom";
import Button, { FillButton } from "./button";
import "./styles.css";
function App() {
return (
<div className="App">
<Button />
<FillButton />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
src/button/Button.js
import React from "react";
export const FillButton = () => {
return <button style={{ background: "aquamarine" }}>Awesome bossom</button>;
};
const Button = () => {
return <button>Awesome</button>;
};
export default Button;
src/button/index.js
export { default, FillButton } from "./Button";
Hope this helps!
Suppose a function called abc()
is exported from ./Button
Can somebody tell me what is their difference?
- The difference is that your first
export
re-exports functionabc
as unnamed export so that it can be imported as anyAssignedbyImporterName
:
import AssignedbyImporterName from ...
and used as AssignedbyImporterName
:
AssignedbyImporterName(); // call function abc()
- Your second
export
re-exportsabc
as named export under umbrella of an additional unnamed object which acts as a namespace so that it can be imported as anyAssignedbyImporterNamespace
:
import AssignedbyImporterNamespace from ...
and used:
AssignedbyImporterNamespace.abc(); // call function abc()
If your need is to export multiple objects go with named exports(without default keyword).
It's easiest to just look at what the three different ES6 import/export styles pile down to in CommonJS.
// Three different export styles
export foo;
export default foo;
export = foo;
// The three matching import styles
import {foo} from 'blah';
import foo from 'blah';
import * as foo from 'blah';
Roughly piles to:
exports.foo = foo;
exports['default'] = foo;
module.exports = foo;
var foo = require('blah').foo;
var foo = require('blah')['default'];
var foo = require('blah');