前言
按需加載模塊的目的是實現代碼分割,用戶打開首頁時不用下載全部的代碼,打開特定的頁面加載特定的代碼,可以提高用戶體驗
實現
在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)來做代碼拆分與組件按需加載。