react-route4 按需加载配置心得

本篇文章主要记录笔者项目中使用 react-route + webpack 做路由按需加载的心得,可能只有笔者一个人看,权当日记了。
 
很久很久以前,react-route还是2.X和3.X版本的时候,我们是这样做按需的:
 
const routes = {
        path: '/',
        component: AppCom,
        indexRoute: {
            component: Admin
        },
        childRoutes: [
            {
                path: 'edit/:id',
                getComponent: (nextState, cb) => {
                    require.ensure([], (require) => {
                        cb(null, require('../entry/admin/edit.jsx'))
                    })
                }
            }
        ]
    }
<Router routes={routes} history={hashHistory} />

 

由于笔者公司需要做按需加载的项目并不多,所以在很长一段时间里,笔者对于按需的印象都一直停留在这个阶段。
 
时间到了2018年3月,笔者总算是能用上按需了,这回我们直接上最新版的react-route,版本号4.1.1。
 
新版的react-route相比老版本,改动的程度很大,require.ensure虽然还能用,但是getComponent却已经被处理掉了,笔者根据官方文档摸索了很久,结果官方文档的案例没有一个能看的,直到笔者看到了这篇文章:https://www.jianshu.com/p/547aa7b92d8c
 
这里介绍的,就是这篇文章中提到的使用Bundle来做按需的方式。
 
我们需要引入Bundle.js作为一个加载器,其代码如下:
import React from 'react';

export default class Bundle extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            mod: null
        };
    }

    componentWillMount() {
        this.load(this.props)
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.load !== this.props.load) {
            this.load(nextProps)
        }
    }

    load(props) {
        this.setState({
            mod: null
        });
        props.load().then((mod) => {
            this.setState({
                mod: mod.default ? mod.default : mod
            });
        });
    }

    render() {
        return this.state.mod ? this.props.children(this.state.mod) : null;
    }
}

 

配置路由页部分代码:
import Bundle from './Bundle';
const routeObj = {
    url1:'url1/url1',
    url2:'url2/url2',
    url3:'url3/url3',
}
let components = {};
for(let route in routeObj){
    components[route] = (props) => (
        <Bundle load={() => import(`../entry/${routeObj[route]}`)}>
            {(Component) => <Component {...props}/>}
        </Bundle>
    );
}

 

这里需要注意,import不支持直接使用变量作为参数,webpack官方解释如下:
 
 
也就是说,import后至少要有一部分是真实路径,所以才有了
import(`../entry/${routeObj[route]}`)}

 

路由声明代码:
<Route exact path="/" component={components.url1}/>

 

webpack配置:
output: {
    path: paths.appBuild,
    filename: '[name].bundle.js',
    chunkFilename: '[name].bundle.js'
 }

 

这样就完成了按需的配置,开发者工具中也能看到按需加载的代码块了。
 
在这里,我想吟诗一首:
 
啊~~
我编不下去了
 
posted @ 2018-06-21 19:51  herorest  阅读(229)  评论(0编辑  收藏  举报