Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy load component with path stored in a variable or prop #16132

Closed
CodingDive opened this issue Jul 14, 2019 · 9 comments
Closed

Lazy load component with path stored in a variable or prop #16132

CodingDive opened this issue Jul 14, 2019 · 9 comments

Comments

@CodingDive
Copy link

Do you want to request a feature or report a bug?
Report a bug

What is the current behavior?
Error and warning when trying to dynamically lazy load a component from a variable or props.

Warning: Critical dependency: the request of a dependency is an expression

Error: Cannot find module './Button'
(anonymous function)
.../dynamic-lazy-load/src lazy groupOptions: {} namespace object:5

Reproduction
In a Codesandbox it seems to be working https://codesandbox.io/s/angry-rgb-vs0g4 fine. For some reason in a non codesandboxed environment, I was able to reproduce the issue here.

What is the expected behavior?
It should lazily load the component even when the path is passed down via props or stored in a variable without throwing a warning or error. The behavior of following code:

const buttonPath = "./Button";
const LazyLoadedButton = lazy(() => import(buttonPath));

should match the behavior of

const LazyLoadedButton = lazy(() => import('./Button'));

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Latest version of CRA (3.0.1) and latest React (16.8.6)

This issue was first reported in the lerna support CRA pull request seen here.

@CodingDive
Copy link
Author

CodingDive commented Jul 14, 2019

After reading this comment, I looked into Webpack and saw that this is a limitation of dynamic expressions in webpack https://webpack.js.org/api/module-methods/#dynamic-expressions-in-import. I know in advance which files should be bundled but would still need the ability to dynamically import them.

Is there any way to do this in React?

Related links
webpack/webpack#7526
https://github.com/systemjs/systemjs
https://stackoverflow.com/questions/43163909/solution-load-independently-compiled-webpack-2-bundles-dynamically
https://www.martinfowler.com/articles/micro-frontends.html#TheContainer seems to present a viable solution but the code looks really hacky and it would be great to support this out of the box in the react & webpack ecosystem

@threepointone
Copy link
Contributor

This isn't related to React, not much we can do here. Would recommend reaching out to webpack instead.

@eddiecooro
Copy link

@ReasonableDeveloper You may consider using loadable-components instead of React.lazy. take a look at this section in their docs. (link)

@uguremirmustafa
Copy link

A simple solution I come up with is like this:

export const LINKS = [
  {
    component: './tabs/someNameComponent',
    name: 'someName',
    icon: 'mdi mdi-truck',
  },
  {
    component: './tabs/anotherNameComponent',
    name: 'anotherName',
    icon: 'mdi mdi-card',
  },
];

export const SUB_PAGES = LINKS.map(({ name, component }) => {
  return {
    path: name,
    component: lazy(() => import(`${component}`)), // THIS IS THE TRICK
  };
});

@makbari
Copy link

makbari commented Feb 17, 2022

It is crazy and interesting that only ${component} works.
In my case, even re-assignment and string concatenation do not work. thanks for the hint @uguremirmustafa

@gaearon
Copy link
Collaborator

gaearon commented Feb 17, 2022

Note again this has nothing to do with React. Whether (and how) this works depends entirely on your bundler.

@suhaibbaba
Copy link

I have the same issue
if put the path in the variable, I see "Can't find the module"
const filePath =@pages/general/general; const component = React.lazy(() => import(${filePath}));
but if put the path directly, it's working
const component = React.lazy(() => import("@pages/general/general"));

any suggestions?

@julpat
Copy link

julpat commented Dec 1, 2022

A simple solution I come up with is like this:

It's not working for me (NextJS) and I have a suspicion that maybe it's working for you just because it imports ALL modules in the project - just try to break some non-relevant module and you will see a build error.

@matteusbarbosa
Copy link

"The import() must contain at least some information about where the module is located. Bundling..." I just read here too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants