🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 按需加载 为什么要实现按需加载? 我们现在看到,打包完后,所有页面只生成了一个`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`。