## 按需加载
为什么要实现按需加载?
我们现在看到,打包完后,所有页面只生成了一个`build.js`,当我们首屏加载的时候,就会很慢。因为他也下载了别的页面的`js`了哦。
如果每个页面都打包了自己单独的`js`,在进入自己页面的时候才加载对应的`js`,那首屏加载就会快很多哦。
在 `react-router 2.0`时代, 按需加载需要用到的最关键的一个函数,就是`require.ensure()`,它是按需加载能够实现的核心。
在4.0版本,官方放弃了这种处理按需加载的方式,选择了一个更加简洁的处理方式。
[传送门](https://reacttraining.com/react-router/web/guides/code-splitting)
根据官方示例,我们开搞:
1. `npm install bundle-loader --save-dev`
2. 新建`Bundle.js`
~~~
cd src/router
touch Bundle.js
~~~
`src/router/Bundle.js`
~~~
import React, { Component } from 'react'
export default class Bundle extends Component {
state = {
// "module" 是 js 的关键字,所以用"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({
mod: mod.default ? mod.default : mod
})
})
}
render() {
return this.props.children(this.state.mod)
}
}
~~~
3. 改造路由器
`src/router/router.js`
~~~
import React from 'react'
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom'
import Bundle from './Bundle'
import Home from 'bundle-loader?lazy&name=home!pages/Home/Home'
import Page from 'bundle-loader?lazy&name=page!pages/Page/Page'
import Counter from 'bundle-loader?lazy&name=counter!pages/Counter/Counter'
import UserInfo from 'bundle-loader?lazy&name=userInfo!pages/UserInfo/UserInfo'
const Loading = function () {
return <div>Loading...</div>
}
const createComponent = (component) => (props) => (
<Bundle load={component}>
{
(Component) => Component ? <Component {...props} /> : <Loading />
}
</Bundle>
)
export default () => (
<Router>
<div>
<ul>
<li><Link to="/">首页</Link></li>
<li><Link to="/page">Page</Link></li>
<li><Link to="/counter">Counter</Link></li>
<li><Link to="/userinfo">UserInfo</Link></li>
</ul>
<Switch>
<Route exact path="/" component={createComponent(Home)}/>
<Route path="/page" component={createComponent(Page)}/>
<Route path="/counter" component={createComponent(Counter)}/>
<Route path="/userinfo" component={createComponent(UserInfo)}/>
</Switch>
</div>
</Router>
)
~~~
打开`F12`,看到`document`的`<head></head>`,每次进入新页面都会加载对应的`js`,这很酷!
但是有个问题,名字都是`0.bundle.js`,根本分不清是哪个页面的`js`,所以我们修改下`webpack.dev.config.js`,加个`chunkFilename`。