Index.js module imports with webpack - javascript

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

Related

Importing from "export default as" runs all code

I have a files like this:
components/carousel.js
import hammerjs from 'hammerjs';
import React from 'react';
export default () => <div>...</div>;
components/layout.js
import React from 'react';
export default () => <div>...</div>;
components/index.js
export { default as Carousel } from './carousel';
export { default as Layout } from './layout';
Now in my server side rendered app I import layout like so:
import { Layout } from './components';
I get an error about window not being defined, because it's reading through components/index.js and seeing hammerjs dependency inside the Carousel export, which requires window and isn't available on the server.
Why is it reading the code in the Carousel component when I'm only trying to import the Layout component? How do I avoid this happening?
In short - why is it reading the Carousel component?
You are exporting two defaults in your components/index.js which is not a supported operation. Export the named components individually or one default objet that holds both.
1) From MDN on import/exports - You can have multiple named exports per module but only one default export. link
In your components index file you're exporting both as default - export the named variable. Then import the named variable.
2) The HammerJS dependency shouldn't matter. Your react code will be run through some sort of transpiler that will take the node modules and turn them into something the browser can understand.

How can I use a variable in React JS render method?

I am learning React JS.
Now, I am using a variable in App.js file and want to use this variable in render() method in index.js file but it's showing me this error:
./src/index.js Line 7: 'bioData' is not defined no-undef
Search for the keywords to learn more about each error.
in App.js file I have this code:
import React from 'react';
import logo from './logo.svg';
import './App.css';
import * as serviceWorker from './serviceWorker';
function Person (props) {
return (
<div className="p1">
<h1>{props.name}</h1>
<h3>{props.skill}</h3>
</div>
);
}
var bioData = (
<div>
<Person name="alex" skill="designer" />
<Person name="shibbir" skill="web developer" />
</div>
);
export default Person;
and In index.js file I have following code:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Person from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(bioData, document.querySelector("root"));
serviceWorker.unregister();
can you tell me why it's showing that erro?
The problem is that you haven't imported bioData into index.js (or defined it locally). In modules, top-level declarations are not globals, modules have their own scope (thankfully). So var bioData in App.js doesn't define a global index.js sees.
If you want to use biodata in index.js, export it from App.js:
export var bioData = {/*...*/};
...and import it into index.js, perhaps on the line where you're importing Person:
import Person, { bioData } from './App';
Note that that's a named export/import. You asked in a comment whether you should use export default bioData; in App.js, but you can't, you already have a default export in App.js (Person). You can have only one default export (or none), and then as many named exports as you like (or none).
Side note: var is obsolete. Use let or const.
Side note 2, re this code:
ReactDOM.render(bioData, document.querySelector("root"));
Assuming you're trying to render to an id="root" element, it should be either document.getElementById("root") (more idiomatic) or document.querySelector("#root"), but not document.querySelector("root") (which looks for a <root>...</root> element).

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.

Re-export default in ES 6 modules

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

parentheses around import ES6

I'm learning React Native, just curious about the parentheses in the first line of import
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';
class HelloWorldApp extends Component {
render() {
return (
<Text>Hello world</Text>
);
}
}
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);
Why wrap Component with {} but not React?
React is the default export (there can only be one of these per module). Default exports can be imported like this:
import React from "react";
Component is a named export (there can be many of these). Named exports are imported like this:
import { Component } from "react";
What you're seeing is both of these things imported on the same line.
default exports aren't automatically available everywhere, so they still need importing.
Note that the reason React needs importing at all is because of the way that JSX is transformed into JS - React needs to be available so <Text> can be transformed into React.createElement(Text, ....
I think it's just a matter of shorting the next invocations, since Component is a subclass of React, so that way you use React as default with all it has in it. and Component as a single class you'd use. By the way you use braces in import when you want something specific as a method or class, that is named export. There's a better explanation in here.
Having both named exports and a default export in a module
import React from 'react';
import Navbar from 'react-bootstrap/lib/Navbar';
export default class MyNavbar extends React.Component {
render(){
return (
<Navbar className="navbar-dark" fluid>
...
</Navbar>
);
}
}

Categories

Resources