4

I am creating an app using create-react-app and lazy loading the component using react-loadable.

What I want to do is import dynamic paths for the loader object or the Loadable function of react-loadble module.

Code:

const LoadableComponent = path =>
 Loadable({
  loader: () => import(`${path}`),
  loading: Loader,
 })

const Home = LoadableComponent('./../../pages/Home')
const User = LoadableComponent('./../../pages/User')

If I put the path string in the place of the path variable (Ex. import('./pages/Home')) and call the function it works. But when I use it like the code above Loader will load but it will not continue to load the component anymore. Why doesn't it work if I use the variable in import?

3 Answers 3

4

Found the answer here

"For Webpack to handle an import, it needs to be able to at least guess roughly what an import() is meant to be referencing."

Turns out your path cannot be too anonymous. Guess it is stacked to deep for Webpack to confidently know what I am importing.

Sign up to request clarification or add additional context in comments.

Comments

1

As far as I know, the bundler (Webpack) needs to be able to process the file path upfront.

My question would be why is it required? Is there anything so bad about just writing?

const Home = Loadable({
  loader: () => import('./pages/Home'),
  loading: Loader,
})

const User = Loadable({
  loader: () => import('./pages/User'),
  loading: Loader,
})

Bonus point: Take a look at new React's lazy API, recently release in 16.6. The linked page also has some good information on code splitting.

1 Comment

Sorry. I just don't think it will be very efficient to do with multiple pages. Also I was planning to use it to multiple files but I guess it would be impossible to do unless they aren't stacked too deep for webpack to locate. Also my react is 16.5 so .lazy isn't included yet.
0

To simplify config lazy loading,the solution likes below:

import React, {Component, lazy, Suspense} from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from "react-router-dom";
let routers={
    '/about': import('./pages/about'),
    '/contact':  import('./pages/contact'),
}

class Content() extends Component{
   render(){
     return (<Switch>
        {Object.keys(this.props.routers).map((path, idx) => {
            let Child = lazy(()=>this.props.routers[path])
            return (
                <Route path={path} key={idx}>
                    <Suspense fallback={<div>Loading...</div>}>
                        <Child></Child>
                    </Suspense>
                </Route>)
        })}
    </Switch>
   }
}

ReactDOM.render(
    (
    <BrowserRouter>
        <div>
            <ul>
                <li><Link to="/about"> About</Link></li>
                <li><Link to="/contact">Contact</Link></li>
            </ul>
            <Content routers={config.routers}></Content>
        </div>
    </BrowserRouter>
    ),
    document.getElementById('root') as HTMLElement
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.