React Router 是一个很是出色的路由解决方案,同时也很是容易上手。可是当网站规模愈来愈大的时候,首先出现的问题是 Javascript 文件变得巨大,这致使首页渲染的时间让人难以忍受。实际上程序应当只加载当前渲染页所需的 JavaScript,也就是你们说的“代码分拆" — 将全部的代码分拆成多个小包,在用户浏览过程当中按需加载。javascript
这里所说的总是指使用react-router低于4的版本。java
在低版本(小于4)的react-router中直接提供了按需加载的方案,示例以下:react
const rootRoute = {
path: '/',
indexRoute: {
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('components/layer/HomePage'))
}, 'HomePage')
},
},
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('components/Main'))
}, 'Main')
},
childRoutes: [
require('./routes/baidu'),
require('./routes/404'),
require('./routes/redirect')
]
}
ReactDOM.render(
(
<Router history={browserHistory} routes={rootRoute} /> ), document.getElementById('app') );复制代码
核心代码是router.getComponent
,然而在react-router4中,没有router.getComponent
了,这样咱们该如何实现按需加载呢?webpack
根据官网的介绍:git
One great feature of the web is that we don’t have to make our visitors download the entire app before they can use it.
You can think of code splitting as incrementally downloading the app. While there are other tools for the job, we’ll use Webpack and the bundle loader in this guide.github
咱们要借助bundle-loader来实现按需加载。web
首先,新建一个bundle.js
文件:react-router
import React, { Component } from 'react'
export default class Bundle extends React.Component {
state = {
// short for "module" but that's a keyword in js, so "mod"
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((mod) => {
this.setState({
// handle both es imports and cjs
mod: mod.default ? mod.default : mod
})
})
}
render() {
if (!this.state.mod)
return false
return this.props.children(this.state.mod)
}
}复制代码
而后,在入口处使用按需加载:app
// ...
// bundle模型用来异步加载组件
import Bundle from './bundle.js';
// 引入单个页面(包括嵌套的子页面)
// 同步引入
import Index from './app/index.js';
// 异步引入
import ListContainer from 'bundle-loader?lazy&name=app-[name]!./app/list.js';
const List = () => (
<Bundle load={ListContainer}> {(List) => <List />} </Bundle>
)
// ...
<HashRouter>
<Router basename="/"> <div> <Route exact path="/" component={Index} /> <Route path="/list" component={List} /> </div> </Router> </HashRouter> // ...复制代码
webpack.config.js
文件配置异步
output: {
path: path.resolve(__dirname, './output'),
filename: '[name].[chunkhash:8].bundle.js',
chunkFilename: '[name]-[id].[chunkhash:8].bundle.js',
},复制代码