## 按需加載
為什么要實現按需加載?
我們現在看到,打包完后,所有頁面只生成了一個`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`。