前言
按需加载模块的目的是实现代码分割,用户打开首页时不用下载全部的代码,打开特定的页面加载特定的代码,可以提高用户体验
实现
在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)来做代码拆分与组件按需加载。