基于路由的代码分割

基于路由的代码分割及其异常

官网介绍了基于路由的代码分割:
https://zh-hans.reactjs.org/docs/code-splitting.html#route-based-code-splitting

不过有一个异常, babel-loader的预设@babel/react会导致不生成异步入口点文件:

import('!babel-loader?presets[]=@babel/env&presets[]=@babel/react!.').then(expo => {
    console.log(expo); // 代码是内联打包的, 不生成文件?!
});

解决办法: 使用lazy组件

lazy组件是指lazy()函数返回的组件, 用于延迟加载其它组件, 配合Suspense组件使用.

router.js:

import { lazy } from "react";

const Pages = [ 'Keyframes', 'WhatsJSX', 'useHistory', 'AsyncImport', 'font', 'FunctionComponent' ];
// const ReactPages = Pages.map(page => require(`@/pages/${page}`).default); // 臃肿的index.js

// 页面全部映射为lazy组件, 在Route中配置Suspense子组件, 并设置该Suspense组件的fallback和children属性
// Suspense组件的children属性就是延迟加载的页面组件
// 这些延迟加载的页面组件必须是函数或者类
const ReactPages = Pages.map(page => lazy(() => import(
    /* webpackChunkName: "page" */
    `@/pages/${page}`
)));

export { Pages, ReactPages };

index.js:

import { Pages, ReactPages, } from '@/pages/router';
import { HashRouter as Router, Switch, Route, Link, useHistory, } from 'react-router-dom';

const map_route = ReactPages.map((LazyComponent, index) => (
    <Route key={index} path={'/' + Pages[index]}>
        {
            // 如果Route的children是一个函数, 则可以接受route参数
            route => {
                return (
                    // <Suspense fallback={<h1>加载中...</h1>}>
                    <Suspense fallback={<Loadding />}>
                        {/* LazyComponent是lazy函数返回的组件 */}
                        <LazyComponent></LazyComponent>
                    </Suspense>
                );
            }
        }
    </Route>
));

// 由于App不是一个通用组件, 不需要继承Component类, 直接导出一个React组件即可
export default (
    <Router>
        <div className={css.app}>
            <Header />
            <div>
                <Switch>
                    {map_route}
                    <Route path="/">{Index}</Route>
                </Switch>
            </div>
        </div>
    </Router>
);
posted @ 2020-09-29 16:38  develon  阅读(250)  评论(0编辑  收藏  举报