Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 504
alexmngn Avatar asked Oct 06 '17 08:10

alexmngn


People also ask

How to export components in a module in ES6?

Modules in ES6 work only in strict mode. This means variables or functions declared in a module will not be accessible globally. The export keyword can be used to export components in a module. Exports in a module can be classified as follows − Named exports are distinguished by their names. There can be several named exports in a module.

Is it possible to use ES6 modules in the browser?

But the time when it can only be used in conjunction with compilers like Babel is over. Meanwhile Node.js also supports the so-called ES6 modules, and in the browser we can use them if we want to. On both use cases, we will have a look at the end of this article.

How do I import everything that is imported by a module?

You can import everything that’s imported by a module like this: You import the default member by giving it a name of your choice. In the following example Logger is the name given to the imported default member: And here’s how you would import non-default members on top of the default one:

Why is mycomponent1 returning undefined when import mycomponent2?

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.


2 Answers

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'

like image 182
Danny Mcwaves Avatar answered Sep 20 '22 15:09

Danny Mcwaves


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.

like image 31
Raghudevan Shankar Avatar answered Sep 18 '22 15:09

Raghudevan Shankar