react-router4實現異步按需加載模塊

前言

按需加載模塊的目的是實現代碼分割,用戶打開首頁時不用下載全部的代碼,打開特定的頁面加載特定的代碼,可以提高用戶體驗

實現

在router4以前,我們是使用getComponent的方式來實現按需加載的,router4中,getComponent方法已經被移除。對於react-router4中實現路由按需加載,網上也有幾種解決方案,比如藉助react-loadable或者bundle-loader,這裏我主要介紹我平時使用最多的一種方式,也是create-react-app所使用的。

1、創建一個異步組件 AsyncComponent
import React from 'react'
/**
 * 異步加載模塊
 * @param loadComponent
 */
export const asyncComponent = loadComponent => (
    class AsyncComponent extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                Component: null
            }
        }

        componentWillMount() {
            if (this.hasLoadedComponent()) {
                return
            }

            loadComponent()
                //  取到module的default作爲組件,因爲我們導出組件的時候使用的是 export default
                //  export default = (const default = Module ; export default )  所以導出的名稱是default
                .then(module => module.default)
                .then((Component) => {
                    this.setState({Component})
                })
                .catch((err) => {
                    console.error(`Cannot load component in <AsyncComponent />`);
                    throw err
                })
        }

        hasLoadedComponent() {
            return this.state.Component !== null
        }

        render() {
            const {Component} = this.state;
            return (Component) ? <Component {...this.props} /> : null
        }
    }
);
2、使用異步組件,AsyncComponent動態導入我們想要的組件
import {asyncComponent as async} from './async';

//import() 返回的是一個promise
export const Welcome = async(()=>import(/* webpackChunkName: "welcome" */'./welcome')); //配置webpackChunkName,打包出來的異步chunk的名稱
export const Rule = async(()=>import(/* webpackChunkName: "rule" */'./rule'));
export const Search = async(()=>import(/* webpackChunkName: "search" */'./search'));
3、引入被AsyncComponent封裝後的異步模塊
import {Welcome, Rule, Search} from './views'
 
 <Router history={hashHistory}>
                    <Switch>
                        <Route path="/" exact component={Welcome}/>
                        <Route path="/welcome" component={Welcome}/>
                        <Route path="/rule" component={Rule}/>
                        <Route path="/search" component={Search}/>
                    </Switch>
</Router>
4、webpack配置部分,配置chunkFilename
output: {
    path: path.resolve(__dirname, "build"),
    filename: 'assets/[name].js',
    chunkFilename: 'assets/[name].[chunkhash:5].chunk.js'
};

結語

代碼分割(code splitting)在單頁應用中非常常見,對於提高單頁應用的性能與體驗具有一定的幫助,在實際項目中,可以使用webpack中的import()、一些loader(例如Bundle Loader)來做代碼拆分與組件按需加載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章