Re-export default in ES 6 modules - javascript

In ES6, is it possible to shorten the following code. I have an App.js file and an index.js.
index.js
import App from './App';
export default App;
Something like this
index.js
export default App from './App.js'

If you use proposal-export-default-from Babel plugin (which is a part of stage-1 preset), you'll be able to re-export default using the following code:
export default from "./App.js"
For more information see the ECMAScript proposal.
Another way (without this plugin) is:
export { default as App } from "./App.js"
The above is a very common practice when separate files, each with its own export, have all something in common, for example, utils, so if, for example, one would want to import 3 utility functions, instead of having to write multiple imports:
import util_a from 'utils/util_a'
import util_b from 'utils/util_b'
import util_c from 'utils/util_c'
One could import any of the utilities in a single-line:
import { util_a, util_b , util_c } from 'utils'
By creating an index.js file in the /utils folder and import all the defaults of all the utilities there and re-export, so the index file will serve as the "gateway" for all imports related to that folder.

This is a bit of repetition from the previous answers, but to clarify the difference in two options:
1. Default export
(This appears to be what OP wants)
// index.ts
export { default } from './App'
Then, in a different file:
import App from './index'
2. Named export
export { default as App } from './App'
Then, in another file:
import { App } from './index'
Bonus: named → default export
If ./App uses a named export, but you want to re-export it as a default export, you can do that too:
export { App as default } from './App'
Then, in another file:
import App from './index'
These will work with react as vsync's answer states.
Bonus #2: export everything
Say you have a file that exports multiple items:
// App.ts
export const first = 1
export const second = 2
const final = 3
export default final
You can then re-export them directly:
// index.ts
export * from './App'
You can now import these easily:
import final, { first, second } from './index'
Bonus #3: * import
You can import all variables exported by another file as a single variable.
// index.ts
import * as App from './App'
App.first === 1 // true

import App from './App';
export default App;
⬇
Babel 7 (with #babel/preset-react) can transform the below:
export { default as App } from './App.js';
Related discussions:
TC39 proposal:
https://github.com/tc39/proposal-export-default-from#common-concerns

The only working solution is :
import App from './App';
export default App;
If you export your module like this
export { default as App } from './App.js';
Then it's not a default export anymore and you'll get an error if you try to import it as a default import.

import App from './App';
export default (App);
This work for me in default 'create-react-app' application

Related

ES6 Import Scenario

There are multiple way to import modules. What is the difference between import {House} and import House?
There are two way to import in ES6 module, based on the export option.
Named Import
//filename - simple.js
export function Simple() {}
import {Simple} from "./simple.js"
Default Import
//filename - simple.js
export default Class Simple {}
import Simple from "./simple.js"
For more, refer https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
UPDATE
You can also export both from a single file and import them. Important caveat here is there can be only one default export in a module.
//filename - simple.js
export function Simple1() {}
export default function Simple2() { }
import Simple2, { Simple1 } from "./simple.js"
The syntax import {House} is used to import specific, named imports like import {foo, bar} from '/modules/my-module.js';
while the syntax import House is used to import default exports like import myDefault from '/modules/my-module.js';
As one can see that we can mix these two. For example, this is also a valid import
import myDefault, {foo, bar} from '/modules/my-module.js';
to read more checkout Mozilla developer guide.

What does import {} from '.' do?

I was looking at some source code of a library and I saw this import
import {SheetsRegistry, JssProvider, withStyles} from '.'
What does this do? How does it import from '.' ?
The code you shared imports those declarations from index.js in the same directory.
index.js:
// #flow
import withStyles from './withStyles'
export {ThemeProvider, withTheme, createTheming, useTheme} from 'theming'
export {default as createUseStyles} from './createUseStyles'
export {default as JssProvider} from './JssProvider'
export {default as jss} from './jss'
export {SheetsRegistry, createGenerateId} from 'jss'
export {default as JssContext} from './JssContext'
export {default as styled} from './styled'
export {default as jsx, create as createJsx} from './jsx'
export {withStyles}
// Kept for backwards compatibility.
export default withStyles
In this example, index.js is being used to re-export some of the declarations within the src directory. This pattern makes it easier to move the declarations around without having to rewrite many imports.
******The difference between named exports and default exports.******
1-named exports
export function, constant, variable...etc in Constant.js
export const CREATE = 'CREATE';
export const DELETE = 'DELETE';
import like this in index.js
import {CREATE,DELETE} from './Constants';
2-default exports
export it in Constant.js
const update = ()=> 'UPDATE'
export default update();
and import like this in index.js
import UPDATE from './Constants';

JavaScript Import and Export

I want to export App Object direct after importing, Can I merge these two lines?
import App from './app.js';
export default App;
The documentation states:
Exporting defaults: The following syntax does not export a default export from the imported module:
export * from …;
If you need to export the default, write the following instead:
import mod from "mod";
export default mod;

Import from folder ES6

I'm studying JS and I have something like this.
//all inside folder reducers
//reducer1.js
export default reducer1
//reducer2.js
export default reducer2
//index.js
import reducer1 from './reducer1'
import reducer2 from './reducer2'
//then combine reducer
export default index
//outside folder reducers
import reducer from './reducers'
since ./reducers is just a folder and there is 3 file with 3 export default inside, I don't understand how this could work ? How does it know which export default in the folder will be imported ?
Thank you.
With Webpack, when you import a folder, the module loader will import the index.js inside the folder. You are exporting index in index.js, so you are importing it when you do import reducer from './reducers'. Importing a folder is just a shorthand for import reducer from reducers/index. With mean both import statements are equivalent.
To sums up, import reducer from './reducers' is the same as import reducer from reducers/index.

Index.js module imports with webpack

My code is organised as follows:
where,
Resources/ActionLog/Components/Layout.js
import React from 'react';
export default class Layout extends React.Component {
render() {
return (
<p>Test</p>
);
}
}
Resources/ActionLog/Components/index.js
export * from './Layout';
Resources/ActionLog/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Layout from './Components'; // <--- ISSUE HERE.
const app = document.getElementById('app');
ReactDOM.render(
<Layout/>,
app
);
Why does Layout not get imported using this setup??
If i change the line to read,
import Layout from './Components/Layout';
it works fine, but otherwise Layout is always undefined! Even when if i try,
import Layout from './Components/index';
I am using webpack as my module bundler, and have achieved something similar before, I just don't see why/how this is different..
Why does Layout not get imported using this setup??
Layout.js has a default export. However, export * from './Layout.js will only export the named exports (of which there are none). In other words, Components/Layout.js doesn't have any exports at all, so nothing can be imported.
But even if it did have named exports, import Layout from './Components/index'; imports the default export, but Components/index.js doesn't have a default export.
There are a couple of ways this could be solved. The one that makes the most sense is probably to export the default export of Layout.js as named export in Components/index.js. You will presumably have multiple files each exporting a component. I assume Components/index.js should export a map of all these components in which case you have to use named exports.
The changes you have to make:
// in Components/index.js
export {default as Layout} from './Layout';
// in ActionLog/index.js
import {Layout} from './Components'; // use a named import

Categories

Resources