react: export {ModuleName} was not found (module has no exports) - reactjs

React CRA sometimes can not find react tsx modules.
React version: 18.2.0
Node version: 19.2.0
I've tried to lower Node version. I've tried change export from export * from './ModuleName to export {ModuleName} from './ModuleName and change import from something like import {ModuleName} from ./ModuleName to import {ModuleName} from ./ModuleName/ModuleName. Sometime it helps, sometimes not.
All components written in next pattern:
type ModuleNameProps = {/* some props *.};
export const ModuleName = ({/* props */}: ModuleNameProps): JSX.Element => { /* Component body */};
export * from './ModuleName';
P.S. Application still works with such errors and other developers on a project don't have such errors
P.P.S. Such errors seem to occur only when path to component contains repetitions. For example: './ComponentName/ComponentName/ComponentName.tsx'

Related

React Native: platform specific import

Got this weird situation. Building for react native and using a native package from Intercom. Importing it works fine when android or ios. But for the web (or node jest) it throws an error.
So have to do some face-pattern "hacking" like this
utilities/Intercom/index.ios.ts
export { default } from '#intercom/intercom-react-native'
utilities/Intercom/index.web.ts
export default function Intercom() {}
some file that uses Intercom
// #ts-ignore
import Intercom from '~/utilities/Intercom' // Cannot find module '~/utilities/Intercom' or its corresponding type declarations.ts(2307)
...
Intercom.logout() // no TS support
Not only does TS complain, but I also loses all types 😭
Is there any other way to do platform specific import and keep the native types?
The error in jest (node) is Cannot read property 'UNREAD_CHANGE_NOTIFICATION' of undefined which is also described in their docs. Problem is that I can't mock it out when using react-native-web that comes with expo.
I think this is what you're looking for https://stackoverflow.com/a/43531355/1868008
In your utilities directory, create a file named Intercom.d.ts and there place the following
import DefaultIos from "./Intercom/index.ios";
import * as ios from "./Intercom/index.ios";
import DefaultWeb from "./Intercom/index.web";
import * as web from "./Intercom/index.web";
declare var _test: typeof ios;
declare var _test: typeof web;
declare var _testDefault: typeof DefaultIos;
declare var _testDefault: typeof DefaultWeb;
export * from "./Intercom/index.ios";
export default DefaultIos;
Not sure what all those are. Maybe something used in typescript internals.
And for the tests, it seems you'll need to mock every method you use in the code you're testing, e.g., in this App component; I'm using the logEvent method, so I return it in the mock object of the library
import React from "react";
import renderer from "react-test-renderer";
import App from "./App";
jest.mock("#intercom/intercom-react-native", () => ({ logEvent: jest.fn() }));
describe("<App />", () => {
it("has 1 child", () => {
const tree = renderer.create(<App />).toJSON();
expect(tree.children.length).toBe(1);
});
});
App.tsx
...
import Intercom from "./utilities/Intercom";
export default function App() {
Intercom.logEvent("test", {});
...
}
For the web implementation, you could import the type to ensure compliance with the library interface
import type { IntercomType } from "#intercom/intercom-react-native";
const webImplementation: IntercomType = {
// here implement all methods
};
export default webImplementation;
https://github.com/diedu89/expo-isomorphic-import-ts

Compiling SVG ReactComponent using Laravel mix

I am trying to import an SVG file as a React component as below.
This normally works on apps created using create-react-app
import { ReactComponent as CloseIcon } from "./assets/icons/close.svg";
const App = () => {
return (
<div><CloseIcon /></div>
);
};
export default App;
I tried doing something similar in laravel, but got this error
I suspect that this has something to do with my laravel-mix configuration (I am fairly new to laravel, excuse my ignorance)
At the moment, my webpack.mix.js laravel-mix looks like this:
mix.ts("resources/js-react/src/index.tsx", "public/js-react")
.react();
On compilation, it gives a warning saying
export 'ReactComponent' (imported as 'CloseIcon') was not found in
'./assets/icons/close.svg' (possible exports: default)
Any form of assistance would be appreciated.

Typescript npm library can't export Redux store please advice

I use the Notistack library and forked it and then using VSCode to try to add a Redux store in the library that I want to expose to Apps.
I'm not so good with Typescript. I have some trouble hehe.
What I want to do is that when the app is using Notistack to show a snack message. I want to use Redux to update the message in real time, like a file up/download progress showing on the snack. It's here Notistack new Redux store(that i create here) come into play. I want Notistack to expose the Redux store to the app so the app can send redux dispatch into to Notistack Redux Store. and showing dispatched message in the Notistack SnackbarItem.tsx
(hope you understand)
When I compile in VSCode I get this error in my app:
Failed to compile.
./src/redux/root-reducer.js
Attempted import error: 'notistack' does not contain a default export (imported as 'NotisReducer').
My root-reducer in the App look like this:
import { combineReducers } from 'redux';
import NotisReducer from 'notistack';
import snackReducer from './snackbar/snack.reducer';
const rootReducer = combineReducers({
snack: snackReducer,
NotisReducer,
});
export default rootReducer;
As you see I import Notistack's NotisReducer and I think I have implemented that.
(I have used NPM link to add locally forked Notistack library into my app)
Now it looks like this here is Notistack's indext.js file where I expose Redux store as NotisReducer:
What I did in Notistack was I added a to index.d.ts:
I define the type store like this:
import * as React from 'react';
import { SnackbarClassKey } from '#material-ui/core/Snackbar';
import { ClickAwayListenerProps } from '#material-ui/core/ClickAwayListener';
import { TransitionProps } from '#material-ui/core/transitions/transition';
import { StandardProps } from '#material-ui/core';
import store from './Redux/store'; // MY STORE
...
...
export type store = store; // EXPORT IT
I'm not sure if this is correct as I could not set breakpoint in npm linked Notistack. Maybe it's to many problem now that must be fixed first.
In the file
SnackbarProvider.tsx
I did like this, importing the store type from index.d.ts):
import {
SnackbarProviderProps,
SnackbarKey,
SnackbarMessage,
OptionsObject,
RequiredBy,
ProviderContext,
TransitionHandlerProps,
store, // STORE
} from ".";
import createChainedFunction from "./utils/createChainedFunction";
export { store }; // EXPOSING IT
In the file
NotisReducer.js
I import the store to be sent to indext.js above
But as you saw above I get compiler error store is not exported.
Attempted import error: 'notistack' does not contain a default ex (imported as 'NotisReducer').
please advice :))

Storybook: Addon-Docs Cannot read property 'classes' of undefined

I’m using Storybook 5.2.6 for React 16.9.0 with Typescript 3.5.3 and using Material UI themed components.
Having added, and configured, #storybook/addon-docs the Storybook Docs page displays: “Cannot read property 'classes' of undefined” in the PropsTable when a component is wrapped withStyles from #material-ui.
Component:
import React, {FunctionComponent} from 'react';
import { Typography } from '#material-ui/core';
import {
  withStyles,
  WithStyles,
} from '#material-ui/core/styles';
import styles from './index.styles';
export interface IProps extends WithStyles<typeof styles> {
  message?: string;
  testId?: string;
}
const Bar: FunctionComponent<IProps> = (props) => {
  const {
    classes,
    message,
    testId = ‘test-bar',
  } = props;
  if (!message) { return null; }
  return (
    <Typography className={classes.message} data-testid={testId}>
      {message}
    </Typography>
  );
};
export default withStyles(styles)(Bar);
Story
import React from 'react';
import { storiesOf } from '#storybook/react';
import { MuiThemeProvider } from '#material-ui/core/styles';
import Bar from './index';
import theme from '../../../others/global/material-ui-theme';
storiesOf('Bar', module)
  .addDecorator(story => <MuiThemeProvider theme={theme}>{story()}</MuiThemeProvider>)
  .addParameters({ component: Bar, componentSubtitle: 'Displays the Bar with message’ })
  .add('Warning', () => <Bar message="warning" />);
In React devtools and debugging in Chrome devtools I can see the classes do get injected as props so I’m kinda stumped at the moment how to resolve this?
So a work around exists, you export the "unwrapped" component and use that as the component in docs:
As mentioned here:
https://github.com/storybookjs/storybook/issues/8361
and commented here: https://github.com/storybookjs/storybook/issues/8435#issuecomment-547075209
Example:
export const PureBar: FunctionComponent<IProps> = (props) => {
// ...
};
export default withStyles(styles)(PureBar);
Then in the story, update the component parameters to target the "Pure" component:
// import both the pure and wrapped components:
import Bar, { PureBar } from './Bar'
// Add to the story:
storiesOf('Bar', module)
.addParameters({ component: PureBar, componentSubtitle: 'Displays the Bar with message’ })
.add(/* ... */);

Component name with React hooks in DevTools

I've just updated a from a class based to a functional component.
When I look in React's DevTools, I'd usually see my component named Gallery with all the named state variables.
Now though, All I see is a component named _default with a bunch of non-descriptive State: definitions.
From other answers, I've read that React Dev Tools now supports hooks but I've not seen any examples of the component name being wrong.
Is this normal behaviour or is there something I'm doing wrong?
Versions
React 16.9.0
React Developer Tools Chrome extension: 4.1.1
Also getting the same issue in Firefox.
Component code
// The component
import React, { useState, useEffect } from 'react';
const Gallery = ({ images, layout }) => {
const [showLightbox, toggleLightbox] = useState(false);
const [activeImage, setActiveImage] = useState(false);
return (
// Some JSX here
)
};
Render code
// Rendering the component
import React from 'react';
import { render } from 'react-dom';
import Gallery from '../../global/scripts/components/Gallery';
render(
<Gallery images={images} />,
document.getElementById('image-gallery'),
);
Devtools screenshot
Try adding a displayName to your component before export. Check the following link for reference.
DisplayName
Use it like Gallery.displayName = 'Gallery'

Resources