1. 程式人生 > >React第三方元件1(路由管理之Router的使用⑤按需載入-下)

React第三方元件1(路由管理之Router的使用⑤按需載入-下)

微信公眾號首發


本教程總共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)}/>

這兩句修改下!

本文完 

禁止擅自轉載,如需轉載請在公眾號中留言聯絡我們!

感謝童鞋們支援!

如果你有什麼問題,可以在下方留言給我們!