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' }
这样就完成了按需的配置,开发者工具中也能看到按需加载的代码块了。
在这里,我想吟诗一首:
啊~~
我编不下去了