使用react-loadable实现组件延迟加载的动态路径导入

Dynamic path import for lazy loading of components using react-loadable

我正在使用 create-react-app 创建应用程序并使用 react-loadable 延迟加载组件。

我想做的是导入loader对象的动态路径或者react-loadble模块的Loadable函数

代码:

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

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

如果我将路径字符串放在路径变量的位置(例如 import('./pages/Home'))并调用它起作用的函数。但是当我像上面的代码一样使用它时,Loader 将加载但它不会继续加载组件了。如果我在导入中使用变量,为什么它不起作用?

找到答案

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

原来你的路径不能太匿名。猜猜它被堆叠到很深,让 Webpack 自信地知道我正在导入什么。

据我所知,捆绑器 (Webpack) 需要能够预先处理文件路径。

我的问题是为什么需要它?光写有什么不好的吗?

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

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

奖励点:看看 new React's lazy API,最近在 16.6 中发布。链接页面也有一些关于代码拆分的好信息。

为了简化配置延迟加载,解决方案如下:

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
)