I'm trying to write a library with TypeScript and Parcel. Everything's fine until i try to import it in another app.
In the library is a index.ts file which gathers the components and exports them:
import Component1 from "./components/Component1";
import Component2 from './components/Component2';
export {
Component1,
Component2,
};
After building i get index.js, index.css and index.d.ts.
In the index.d.ts file the export has been converted to export default:
export default Component1;
export default Component2;
I linked my library with yarn to my consumer app. When i want to import { Component1 } from 'myLibrary'; i get the following error: Module '"myLibrary"' has no exported member 'Component1'. Did you mean to use 'import Component1 from "myLibrary"' instead?. Now when i try to import default (like it is in the index.d.ts) import Component1 from 'myLibrary'; the error changes to: Attempted import error: 'myLibrary' does not contain a default export (imported as 'Component1').
Why does the export conversion happen and how can i circumvent this?
EDIT:
The Library gets built and bundled by parcel, the consumer gets handled by react-scripts.
After Mr.Manhattans suggestion:
index.ts:
export {Component1} from "./components/Component1";
export {Component2} from './components/Component2';
generated index.d.ts:
export {Component1} from "./components/Component1";
export {Component2} from './components/Component2';
consumer:
function App() => {
render(
<>
<Component1 />
<Component2 />
</>
)
};
Error:
./src/App.tsx
[1] Attempted import error: 'Component2' is not exported from 'myLibrary'.
you can direcly export:
export Component1 from "./components/Component1";
export Component2 from './components/Component2';
You're trying to re-export a named export that doesn't exist. Try re-exporting the default instead:
export { default as Component1 } from './components/Component1';
export { default as Component2 } from './components/Component2';
Related
I understood the point that chaining of components can be done by having functional component in every files and importing the components at every parent level.
eg A imports B imports C
Lets say we have these 3 files App.js, Home.js and HomeContainer.js
where App imports Home imports Homecontainer
App.js
import './App.css';
import HomeContainer from './containers/HomeContainer';
function App() {
return (
<div className="App">
<HomeContainer/>
</div>
);
}
export default App;
HomeContainer.js
import Home from "../components/Home";
function HomeContainer(props) {
return (
<div>
<Home/>
</div>
)
}
export default HomeContainer
Home.js
import React from 'react';
function Home(props) {
return (
<div>
<h1>Home</h1>
</div>
)
}
export default Home;
Up until now everything was okay but lets say instead of creating a function component for HomeContainer I exported Home component directly, I see even then it is working.
HomeContainer.js becomes
import Home from "../components/Home";
export default Home
I want to know how exactly this is working, because APP.js is rendering the HomeContainer component but HomeContainer component is not rendering anything like <Home/> but still Home component gets rendered in the APP.js.
I expected App to render first functional component HomeContainer which in turn renders Home component. But even when we don't create a functional component and directly export it, its getting rendered in App.js as Home component when our HomeComponent is not even rendering it using the command <Home/>
How exactly export default in HomeComponent.js is rendering the component Home in parent App.js
When using export default, it doesn't matter what name you give to the imported module.
You are just pointing an identifier to whatever the default export is at the specified path.
Default export
In this example, it does not need to be Home, it can be SomeOtherIdentifier and it will still work.
App.js
import './App.css';
import SomeOtherIdentifier from './containers/HomeContainer';
function App() {
return (
<div className="App">
<SomeOtherIdentifier/>
</div>
);
}
export default App;
HomeContainer.js
import Home from "../components/Home";
export default Home
Named export
On the other hand, if you were to use a named export, you would need to import the module with the same name.
App.js
import './App.css';
import { HomeContainer } from './containers/HomeContainer';
function App() {
return (
<div className="App">
<HomeContainer/>
</div>
);
}
export default App;
HomeContainer.js
import Home from "../components/Home";
export { HomeContainer }
Or you could use the as keyword to alias the imported module to another name.
App.js
import './App.css';
import { HomeContainer as SomeOtherIdentifier } from './containers/HomeContainer';
function App() {
return (
<div className="App">
<SomeOtherIdentifier/>
</div>
);
}
export default App;
HomeContainer.js
import Home from "../components/Home";
export { HomeContainer }
The HomeComponent.js is rendering the Home because you told it to do so! You're importing and exporting Home in it.
Think of the second HomeComponent.js as a middleman. It imports and exports another component (module). It's a common thing in JS projects.
See these for complete details:
https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export
https://javascript.info/import-export
Currently, I have a common package where the components are exported as Named export like so in the src/index.js
export ComponentA from './ComponentA'
export ComponentB from './ComponentB'
In a different project where this is a dependent package I am importing it as
import { ComponentA, ComponentB } from 'my-package';
instead, I need to import it like
import ComponentA from 'my-package/ComponentA'
This is so that I can use react.lazy() and use it as
const LazyComponentA = React.lazy(()=> import('my-package/ComponentA'))
This is under the assumption that if I lazyload the component like this it would only download ComponentA and not the others from 'my-package' Package.
Thanks in advance
In my-package/ComponentA add index.js file with your imports:
// my-package/ComponentA/index.js
import { ComponentA } from "./some-path";
export default ComponentA;
I have a file called index.js that I'm importing other modules into, and exporting them using named exports:
import { Card, Icon } from 'some-library';
import ButtonComponent from './Button';
export const Button = ButtonComponent;
My question is - how can I export those named imports from some-library in the same file without changing their names?
If you want to import a named export and re-export it with that same name, do this:
export { Card, Icon } from 'some-library';
If you want to import a default export and re-export it with some specific name, do this:
export { default as ButtonComponent } from './Button';
I'm creating a project in React and I'm not sure if the approach to import/export is right.
I'm exporting my components with an index.js file inside my Components folder like this:
export {default as Card} from './Card/Card'
export {default as CardList} from './CardList/CardList'
Each component is a const and I'm exporting it as:
export default Card and export default CardList
I'm using export default two times
in the index.js
in each component file
Is this the best practice to use an index file to export the components?
Thanks!
You can keep exporting your components as default, and in your index.js you can export them like:
export Card from './Card/Card';
export CardList from './CardList/CardList';
then when using these, you can do:
import {Card, CardList} from 'components';
Your point of contact (index.js) Feels less verbose
I was working with create-react-app and came across this issue where I get an error:
Home does not contain an export named Home.
Here's how I set up my App.js file:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { Home } from './layouts/Home'
class App extends Component {
render() {
return (
<div className="App">
Hello
<Home />
</div>
)
}
}
export default App;
Now in my layouts folder I have the Home.js file, which is setup like following:
import React, { Component } from 'react';
class Home extends Component {
render() {
return (
<p className="App-intro">
Hello Man
</p>
)
}
}
export default Home;
As you can see, I am exporting the Home component. But I get an error in my console saying this:
What is going on?
The error is telling you that you are importing incorrectly. Here's the code you have to add:
import { Home } from './layouts/Home';
This is incorrect because you're exporting as the default export, not as a named export. Check this line:
export default Home;
You're exporting as default, not as a name. Thus, import Home like this:
import Home from './layouts/Home';
Notice there are no curly brackets. Further reading on import and export.
Use
import Home from './layouts/Home'
rather than
import { Home } from './layouts/Home'
Remove {} from Home
This is a case where you mixed up default exports and named exports.
When dealing with the named exports, if you try to import them you should use curly braces as below,
import { Home } from './layouts/Home'; // if the Home is a named export
In your case the Home was exported as a default one. This is the one that will get imported from the module, when you don’t specify a certain name of a certain piece of code. When you import, and omit the curly braces, it will look for the default export in the module you’re importing from. So your import should be,
import Home from './layouts/Home'; // if the Home is a default export
Some references to look :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
https://medium.com/#trekinbami/a-not-so-in-depth-explanation-of-es6-modules-import-and-export-13a80300f2f0
I just ran into this error message (after upgrading to nextjs 9 some transpiled imports started giving this error). I managed to fix them using syntax like this:
import * as Home from './layouts/Home';
We also can use
import { Home } from './layouts/Home';
using export keyword before class keyword.
export class Home extends React.Component{
render(){
........
}
}
For default
import Home from './layouts/Home';
Default export class
export default class Home extends React.Component{
render(){
........
}
}
Both case don't need to write
export default Home;
after class.
put export { Home }; at the end of the Home.js file
Crazy as it may sound, i spent almost an hour to resolve a similar issue, restarted the localhost and it picked up by itself. Ridiculous but something restart fixes everything.
For me component in question was logout.
I imported like :
import {Logout} from './components';
with this define dint he Logout component
export default Logout
You can use two ways to resolve this problem, first way that i think it as best way is replace importing segment of your code with bellow one:
import Home from './layouts/Home'
or export your component without default which is called named export like this
import React, { Component } from 'react';
class Home extends Component{
render(){
return(
<p className="App-intro">
Hello Man
</p>
)
}
}
export {Home};
This is the solution:
Go to your file Home.js
Make sure you export your file like this in the end of the file:
export default Home;