alexmngn
alexmngn

Reputation: 9597

ES6 modules import is undefined

I'm trying to figure out an issue I have with ES6 modules import.

This is a very simplified version of what I'm attempting to do. My current file structure is much more complicated with nested folders.

I have 2 ReactJS components:

/buttons
  /MyComponent1.js
  /index.js
/texts
  /MyComponent2.js
  /index.js

/index.js

My files look something like this:

I'm importing the MyComponent2 from the root index.js file which is the entry-point of my package.

MyComponent1.js

import MyComponent2 from '../../';

export default () => (
  <div><MyComponent2 /></div>
);

MyComponent2.js

export default () => (
  <div>Hello world</div>
);

My buttons/index.js and texts/index.js files export all components in their own folder:

buttons/index.js

export { default as MyComponent1 } from './MyComponent1'; 

texts/index.js

export { default as MyComponent2 } from './MyComponent2';

And my root index.js export all my folders to make them publicly available. It's my entry-point:

export * from './buttons';
export * from './texts';

So when I import MyComponent2 in MyComponent1 from the root index.js file, it's undefined. When I import it from ./MyComponent2.js, it's defined. When I import the entire package in another project and import MyComponent2 from the root index.js file, it's defined.

It's mind-blowing and I don't understand why I can't import MyComponent2 from the root index.js file.

I need to do that because I have a set of hundred of components nested in different folder and I want to make them all available from this entry-point file.

Can someone tell me what is happening and how to make this possible?

Thanks

Upvotes: 11

Views: 12844

Answers (3)

Eliav Louski
Eliav Louski

Reputation: 5264

In my case, I had an old js file that the IDE imported instead of the updated ts file. so if your module file is module.js make sure there isn't a compiled old module.js in the same directory

Upvotes: -1

Raghudevan Shankar
Raghudevan Shankar

Reputation: 1093

Okay, took me a while to figure out what is happening. Please take a look at the sandbox i've setup - https://codesandbox.io/s/nk0qmo096j

I've tried to keep the folder/module structure similar to what you've described. Please look through how the folder/modules are structured before you continue reading.

When you run the code in the sandbox, take a look at the console. You'll see something like this -

enter image description here

So let me try to explain why what you're trying to do is not working

  1. buttons/MyComponent is the first file to be "exported" (since its at the bottom of the dependency chain; Project/index -> components/index -> buttons/index -> buttons/MyComponent)

Note that components/index has not been exported yet, so it will return undefined

  1. Then buttons/index is exported, followed by texts/index

  2. Then buttons/MyComponent is rendered; just before it is rendered i manually require components/index and it is now defined so returns some defined value

In essence, when your MyComponent1 is trying to import MyComponent2 via the index file, the index file has not been exported yet so it returns undefined. To work around this, you have to require MyComponent2 from within MyComponent1's render method.

Upvotes: 9

Danny Mcwaves
Danny Mcwaves

Reputation: 179

you can import all the components from the respective component files and then assign them to a variable in the root component and then export all of them as objects.

import MyComponent1 from './buttons/index'

import MyComponent2 from './texts/index'

export {MyComponent1, MyComponent2}

to import this components in another file or project. you could import only one them using object destructuring.

import {MyComponent1} from 'index.js'

import {MyComponent2} from 'index.js'

Upvotes: 2

Related Questions