Why react js cannot find my exported modules? - javascript

When I run my react app, the console said
Failed to compile.
./src/components/login/index.js
Attempted import error: 'Login' is not exported from './login'.
Here is the folder structure:
├── index.js
├── login.js
└── register.js
index.js file:
export { Login } from "./login";
export { Register } from "./register";
login.js file:
import React from "react";
import ReactDOM from 'react-dom';
import loginImg from "../../login.svg";
class Login extends React.Component {
constructor(props){
super(props);
}
render() {
return(
// correct code
)
}
}
export default Login;
At first, I thought it was due to typo or sth like that, but I checked the spelling and syntax and still confused by the error. Really want to get some help!

The problem is your Login component has default export. And you imported it as named export.
Your import statement must be
import Login from './login'
import { default as Login } from './login'
Or you should export your Login component as
export { Login }

You used export default but your index.js does not import the default export. Change to:
export { default as Login } from "./login";
export { default as Register } from "./register"

When you export anything as default then you have to import it as
import Login from "./login";
not
import { Login } from "./login";

if you are exporting multiple functions or components you can import like
import { Login } from "./login";
But in your case you are exporting a single component itself. So you can import like
import Login from "./login";
since Login is the only thing that is being exported from login.js.

i think you should remove {} over your component.
replace this:
import {Login} from "./login"
with this:
import Login from "./login"

If it happens when you use Jest to run tests, maybe this helps you:
In my case was because I started the command "npm run test" and later created a new JS file in a new folder (data/heroes.js), and it was not finding that new file, showing this error:
Cannot find module '../data/heroes' from 'src/base/08-imp-exp.js'
But VsCode editor detected imports and exports correctly, so I restarted the terminal instance that was running the tests, and it worked !
Restart the tests terminal !

Related

export components from index file

i have shared components folder when i created some components and i want to export all of them to index.js file and then export all of them from that file. thats how it looks from one of the components file:
export default ToggleSwitch;
now in the index file i try to export them again, it looks like this:
export { default as ToggleSwitch } from './ToggleSwitch';
export { default as Input } from './TextField';
export { default as Button } from './Button';
when i try to import one of the components if i import like this:
import Button from '../../shared/components';
i get this error saying that '../../shared/components' does not contain a default export
and when i try to import it like this,
import { Button } from '../../shared/components';
i get error saying Button is not exported from '../../shared/components'.
what am i doing wrong here?
Have you tried importing as import { Button } from 'shared/components';?
For reference, the current codebase I work with has a similar structure for stores (flux stores) and this pattern works.
An example from the codebase: import { ClickStore } from 'stores';.

Jest testing component getting "TypeError: (0 , _reactRouter.withRouter) is not a function"

This is a whopper.
For some reason, jest and babel won't import and transpile react-router 4's withRouter.
I recently updated from react-router 3 to react-router 4. My single page app compiles via webpack just fine, and I can navigate my local dev version just fine in the browser.
However, tests that involve components that are wrapped with the withRouter HOC fail.
Specifically, if the component being tested has a descendant component that uses the withRouter HOC, you can't even import withRouter. A console log shows that withRouter is imported as "undefined"
The folder has the following files.
app/
├── src/
├── LoginContainer.jsx
├── LoginForm/
├── index.js
└── LoginForm.jsx
LoginContainer (A react container component)
import React from 'react';
import PropTypes from 'prop-types';
import LoginForm from './LoginForm';
export default class LoginContainer extends React.Component {
constructor(props) {
super(props);
this.state = { currentForm: props.form };
this.changeForm = this.changeForm.bind(this);
}
changeForm(form) {
// handle when someone changes something.
}
render() {
return (
<section>
<LoginForm {...this.props} changeForm={this.changeForm} data-form={this.state.currentForm} />
</section>
);
}
}
LoginForm/index.js (basically a HOC that wraps LoginForm.jsx)
import LoginForm from './LoginForm';
import { withRouter } from 'react-router';
// NO MATTER WHAT I DO...
// withRouter is undefined.
// If I do import * as bob from 'react-router'
// bob then equals { default: {} }
// bob is blank!
export default withRouter(LoginForm);
For some reason, I can't import withRouter when testing. All other modules import just fine, only withRouter is causing issues.
react-router 4.2.0 and react-router-dom 4.2.2 are both installed as dependencies
Other components that use things like Link or Route pass tests just fine
UPDATE
I think it has to do with jest + babel. If I switch the import statement to a require statement, it works!
import LoginForm from './LoginForm';
// THIS WORKS! But I don't want to deviate from ES6 just for a test.
const withRouter = require('react-router/index.js').withRouter;
export default withRouter(LoginForm);

Using single entry file for react native app

I am attempting to use a single entry file for android and iOS in a React Native app.
I have followed a few tutorials and have ended up with the following:
index.js
import React, { Component } from 'react';
import { Text } from 'react-native';
export default class Main extends Component {
render() {
return (
<Text>Hello world! from both IOS and Android</Text>
);
}
}
index.ios.js
import React from 'react';
import { AppRegistry } from 'react-native';
import {Main} from './index';
AppRegistry.registerComponent('Main', () => Main);
I end up with the following error:
Element type is invalid: expected a string(for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.
If I remove the curly braces from Main in the import statement it says '...but got: object' so I feel like it's something to do with my exporting/importing but nothing seems to work. Any help would be appreciated.
You are exporting your Main component as:
export default class Main extends Component {
but importing as:
import {Main} from './index';
The default export should be imported as:
import Main from './index';
If you use default export, you must import like this. If this doesn't work, there must be another problem in your code.
React Native tries to import based on platform. For example, if you have index.ios.js and index.android.js in the same folder, React Native will bundle index.ios.js only if it is bundling for ios. It is possible that when you import from ./index, React Native is revolving the path with index.ios.js instead of index.js because you are bundling for ios.
If you are curious enough, you can try to console.log the content of the imported module, e.g. console.log(Main) to see what is actually getting imported.

export npm component as custom react component

I have a file call common.js where I want to collect component that I installed via npm.
I do this
import 'dropdown-group/style.css' // this is ok
export 'dropdown-group'
it doesn't work? I tried this too
import 'dropdown-group/style.css'
import dropdown_group from 'dropdown-group'
export dropdown_group
You need to first import the component and then export it.
import DropdownGroup from 'dropdown-group';
export DropdownGroup;
I am not sure what is importable from your component, whether it has default export for DropdownGroup or as object {DropdownGroup}. Please check this with your installed plugin.

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

Categories

Resources