I am breaking my project into different repos. I have 3 different repos: base, utils and my project.
Base contains: CustomText
Utils contains: Wrapper & StyleHelper
My project contains: the app I'm working with.
The error occurs when I import Wrapper in my project like so:
import { Wrapper } from 'utils';
in Wrapper.js I import a CustomText Component
import { CustomText } from 'base';
in CustomText.js I import a StyleHelper
import { StyleHelper } from 'utils';
The error I get refers to the StyleHelper. The error says "cannot read 'create' of undefined" - create is a method on the StyleHelper component. So when I import Wrapper in my project StyleHelper is undefined. When I don't import Wrapper in my project StyleHelper is defined and no error occurs.
If they are not in separate repos the app works. Also, if I remove the CustomText import in Wrapper it works.
How do I get these to work if I want to break up the project into different repos? I'd assume some sort of circular dependency, but why is this happening? If it is some sort of circular dependency, what's the best practice to avoid this when breaking up a large project into many repos?
Related
I am working with a React project where each component's files are contained in their own directory. I have a component.jsx file and an index.js file that re-exports the component's default export. This works as expected. I would like to simplify my import statements by re-exporting all components up directory level from the main components folder. See below for an example of my current project foloder structure.
src
--components
----Alert
------Alert.jsx
------index.js
----LoginCard
------LoginCard.jsx
------index.js
--index.js
Alert/Alert.jsx
export default function Alert(props) {
// omitted for brevity - the component itself works fine
return <Alert />
}
Alert/index.js
export { default } from './Alert';
At this point, imports work as expected in the LoginCard component.
LoginCard.jsx
import { UserContext } from '#contexts';
import Alert from '#components/Alert';
export default function LoginCard(props) {
// omitted for brevity. Again, component works as expected
return <LoginCard />
In order to achieve my desired end result of simplifying import calls, I created components/index.js:
components/index.js
export { default as Alert } from './Alert';
Which I then attempt to import as:
LoginCard.jsx
import { Alert } from '#components'
When attempting to import from component/index.js as import { Alert} from '#components' I receive an exception that states "cannot read default property of undefined". What makes this strange is that I import/export my pages and contexts in exactly the same manner and they work as expected. I originally thought that this implied an issue with my components directory alias, but the alias is working as I can import just fine from #components/Alert, just not from #components
Have a missed something simple, or am I hitting a bug? Thanks.
I think the issue here is that you are attempting to push all the exports up the tree towards the root directory. This makes sense when importing somewhere outside that root directory. The issue lies in the fact that you are attempting to import from the root while inside the directory structure. In other words, all the exports from within the directory need to be processed before anything can be exported from the root.
The snag here is that you are attempting to import Alert from the root export from LoginCard... which while being processed hasn't finished its exports, so the root export isn't ready yet.
In other words, #components/Alert is ready, #components is not.
Just use a relative import of Alert (and any other import) from within the same components directory.
import { UserContext } from '#contexts';
import Alert from '#components/Alert';
// or
import Alert from '../Alert';
export default function LoginCard(props) {
// omitted for brevity. Again, component works as expected
return <LoginCard />
I am trying to use jquery.infinitedrag to create a component in react. My code is here:
//Grid.js
import React from 'react'
import './jquery/jquery.min.js'
import './jquery/jquery-ui.min.js'
import './jquery/jquery-ui.min.css'
import './jquery/jquery.infinitedrag.js'
export default class Grid extends React.Component{
componentDidMount() {
$.infinitedrag("wall")
}
render() {
return(
<div id="wall"/>
)
}
}
This is supposed to work by making a div (identified by id) when react renders and then filling in an infinite grid later once the component mounts. The problem is, for some reason, jquery.infinitedrag is getting confused. Here is the error:
Failed to compile.
./src/jquery/jquery.infinitedrag.js
Line 108:4: Expected an assignment or function call and instead saw an expression no-unused-expressions
Line 277:4: 'jQuery' is not defined no-undef
My file structure looks like this:
src
-jquery
-jquery.min.js
-jquery-ui.min.js
-jquery-ui.min.css
-jquery.infinitedrag.min.js
-Grid.js
-misc other components and stuff
I am fairly new to javascript, so this is probably something dumb.
npm install jquery OR npm update to remove the second error.
For context, let me try to explain a little more.
In my project I have a folder, as example, for components.
Inside that folder I have my components files, and an index.js file where I import all the components and export than in the same line as follows:
export { default as Button } from './button'
export { default as Loader } from './loader'
export { default as ImageBackground } from './image-background'
So than I can import these components in Screen Component like that:
import { Button, Loader, ImageBackground } from 'src/components'
If I edit the components file, save and reload the project, everything works fine.
The problem is that when I edit any of these components with the Hot Module Replacement (Hot Reloading) actived, when it is triggered after an edit, it throws the following error:
Unhandled JS Exception: Requiring module "src/components/index.js", which threw an exception: TypeError: Cannot redefine property: Button
Has anyone have any idea why this is happening?
Thanks in advance!
Obs: When I import the component direct without using the index.js or if inside the index.js, I first import the component, than I assign the component to a variable and than I export this variable, it works fine.
my problem was solved when I changed render = () => (...) to render(){ return (...)} in react component
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
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 -
So let me try to explain why what you're trying to do is not working
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
Then buttons/index is exported, followed by texts/index
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.
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'
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
I have two module with the exact same name that belongs to two different apps, these two module are functionally quite similar except for the styling. I am creating a master component and try to import these two different module based on what app I am currently in.
I wonder if there is a way to conditionally import the module that I don't have to hard code a name space for the module, like module_app1 and module_app2 but instead to do
if (cond) {
import module from 'path1';
} else {
import module from 'path2';
}
I use 'as'. Example:
import Actions from '../actions';
import { Actions as Navigator } from 'react-native-router-flux';