微信公众号首发
本教程总共6篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章!
1、React第三方组件1(路由管理之Router的使用①简单使用)---2018.01.22
2、React第三方组件1(路由管理之Router的使用②多层级跳转及重定向)---2018.01.23
3、React第三方组件1(路由管理之Router的使用③传参)---2018.01.24
4、React第三方组件1(路由管理之Router的使用④按需加载-上)---2018.01.25
5、React第三方组件1(路由管理之Router的使用⑤按需加载-下)---2018.01.26
开发环境:Windows 8,node v8.9.1,npm 5.5.1,WebStorm 2017.2.2
如果我们的路由比较多,比如单页面应用,可能路由有几十个!那么首次加载把整个js都拉取回来,其实有点浪费,也影响速度,所有我们要实现按需加载,就是拆分js包,请求哪个路由就获取哪个路由的js小包!
那么怎么拆分呢!这就是我们今天要讲的!
上节课我们已经做了些准备,这节课我们要在demo页面下,把demo1,demo2,拆分开来!
我们开始拆分行动!
1、先来安装依赖
npm i -D bundle-loader
2、新建Bundle.jsx
在app -> component -> common 目录下
import React, { Component } from 'react' class Bundle extends 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() { return this.state.mod ? this.props.children(this.state.mod) : null } } export default Bundle
我们修改下 webpack.dev.conf.js
{ test: /\.bundle\.jsx$/, use: { loader: 'bundle-loader', options: { name: '[name]' } } }
响应的 也要修改下 webpack.prod.conf.js 文件
这里的test正则表达式是要命中带用budle.jsx的文件
那么我们要修改下 demo1 下的Index.jsx文件改成 Index.bundle.jsx
然后修改 demo 下的Index.jsx文件 ,完整代码 如下
import React from 'react'; import {HashRouter, Route, NavLink,Redirect} from 'react-router-dom' import Bundle from '../common/Bundle' import Dome1 from './demo1/Index.bundle' import Dome2 from '../demo/demo2/Index' import '../../public/css/demo.pcss' const Index = () => <HashRouter> <div className="content"> <div className="nav"> <NavLink to="/Dome1" activeClassName="selected" exact>demo1</NavLink> <NavLink to="/Dome2" activeClassName="selected">demo2</NavLink> </div> <Route exact path="/" render={() => (<Redirect to="/Dome1"/>)}/> <Route path="/Dome1" component={ () => <Bundle load={Dome1}> {(Dome1) => <Dome1/>} </Bundle> } /> <Route path="/Dome2" component={Dome2} /> </div> </HashRouter> ; export default Index;
我们执行下
npm run dev
看下浏览器效果
已经成功拆分开了,但是名字起的不好,拆开后是 Index.bundle-0.js
我们需要改下名称,后面等的0 是 id的意思这个配置是在这里:
我们改下名字
再看浏览器
已经改过来了!
我们下面拆分demo2
同样的要修改 demo2 下面 Index.jsx 文件名
Demo2.bundle.jsx
然后修改 demo 下Index.jsx文件,完整代码
import React from 'react'; import {HashRouter, Route, NavLink,Redirect} from 'react-router-dom' import Bundle from '../common/Bundle' import Dome1 from './demo1/Demo1.bundle' import Dome2 from './demo2/Demo2.bundle' import '../../public/css/demo.pcss' const Index = () => <HashRouter> <div className="content"> <div className="nav"> <NavLink to="/Dome1" activeClassName="selected" exact>demo1</NavLink> <NavLink to="/Dome2" activeClassName="selected">demo2</NavLink> </div> <Route exact path="/" render={() => (<Redirect to="/Dome1"/>)}/> <Route path="/Dome1" component={ () => <Bundle load={Dome1}> {(Dome1) => <Dome1/>} </Bundle> } /> <Route path="/Dome2" component={ (props) => <Bundle load={Dome2}> {(Dome2) => <Dome2 {...props}/>} </Bundle> } /> </div> </HashRouter> ; export default Index;
然后看下浏览器效果
我们看到 点击 demo演示
默认跳转到 demo1,并且能看到 发生了两个js请求,Demo1.bundle.js,
demo2.bundle.js,
这不是我们想要的啊,我们希望是,
demo1 就请求 Demo1.bundle.js,
demo2 就请求 Demo2.bundle.js,
那怎么办呢?
拆分完,正真按需加载其实就是懒加载,我们只需要在webpack中配置下就可以了。
options: { lazy: true, name: '[name]' }
同样的我们也要修改下
webpack.pro.conf.js文件
我们再重新执行
npm run dev
看下效果
完美实现了 按需加载
demo1 就请求 Demo1.bundle.js,
demo2 就请求 Demo2.bundle.js,
我们回过头来,优化下代码!
修改 Bundle.jsx
const BundleFun = (Component,props) => <Bundle load={Component}> {(Component) => <Component {...props}/>} </Bundle> ; export { Bundle, BundleFun }
就该这块!
然后修改 demo 下的 Index.jsx
<Route path="/Dome1" component={() => BundleFun(Dome1)}/> <Route path="/Dome2" component={(props) => BundleFun(Dome2, props)}/>
这两句修改下!
本文完
禁止擅自转载,如需转载请在公众号中留言联系我们!
感谢童鞋们支持!
如果你有什么问题,可以在下方留言给我们!