博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于Webpack 2的React组件懒加载
阅读量:6695 次
发布时间:2019-06-25

本文共 4486 字,大约阅读时间需要 14 分钟。

从属于笔者的,更多前端思考参阅笔者的。

Chunks是Webpack的基本概念之一,最直观的概念是在多入口配置中,诶个单独的入口会生成单独的Chunk。而在添加额外的插件配置之后,Webpack会输出譬如独立的CSS包体这样独立的块。Webpack内置有如三种类型的Chunk:

  • Entry Chunks:Entry Chunks是我们最常见的Chunks类型,包含了应用所需要的Webpack运行时与即刻加载的模块。

  • Normal Chunks:Normal Chunks并不会包含Webpack运行时,主要指代那些应用运行时动态加载的模块,Webpack会为我们创建类似于JSONP这样合适的加载器来进行动态加载。

  • Initial Chunks:Initial Chunks本质上还是Normal Chunks,不过其会在应用初始化时完成加载,往往这个类型的Chunks由CommonsChunkPlugin生成。

bundle-loader

bundle-loader是Webpack官方出品的之一,bundle-loader可以用来加载异步代码块,基本的用法如下:

// 当请求某个Bundle时,Webpack会为我们自动加载var waitForChunk = require("bundle-loader!./file.js");//我们需要等待Chunk加载完成才能获取到文件详情waitForChunk(function(file) {    // use file like is was required with    // var file = require("./file.js");});// wraps the require in a require.ensure block

我们同样可以自定义Chunk名:

require("bundle-loader?lazy&name=my-chunk!./file.js");

我们可以很方便地利用bundle-loader实现React Router中模块的懒加载,譬如如果我们的路由设置如下:

import HomePage from "./pages/HomePage";import AdminPage from "./pages/admin/AdminPage";import AdminPageSettings from "./pages/admin/AdminPageSettings";export default function routes(fromServer) {  return (    
)}

其中AdminPage可能非常笨重,我们希望只有当用户真实请求到/admin这个地址时才会加载相关组件,此时我们就可以在Webpack配置中添加bundle-loader的支持:

{...module: {  loaders: [{    // use `test` to split a single file    // or `include` to split a whole folder    test: /.*/,    include: [path.resolve(__dirname, 'pages/admin')],    loader: 'bundle?lazy&name=admin'   }]  }...}

该配置会自动帮我们从主文件中移除admin相关的组件代码,然后将其移动到1.admin.js文件中,然后在React Router中,我们同样需要冲定义组件加载函数:

import HomePage from "./pages/HomePage";import AdminPage from "./pages/admin/AdminPage";import AdminPageSettings from "./pages/admin/AdminPageSettings";const isReactComponent = (obj) => Boolean(obj && obj.prototype && Boolean(obj.prototype.isReactComponent));const component = (component) => {  return isReactComponent(component)    ? {component}    : {getComponent: (loc, cb)=> component(         comp=> cb(null, comp.default || comp))}};export default function routes(fromServer) {  return (    
)}

React 懒加载组件封装

有时候我们需要将某个厚重的组件设置为异步加载,这里我们将常见的懒加载操作封装为某个组件及其高阶组件接口,源代码参考:

import React from 'react';/** * @function 支持异步加载的封装组件 */class LazilyLoad extends React.Component {  constructor() {    super(...arguments);    this.state = {      isLoaded: false,    };  }  componentWillMount() {    this.load(this.props);  }  componentDidMount() {    this._isMounted = true;  }  componentWillReceiveProps(next) {    if (next.modules === this.props.modules) return null;    this.load(next);  }  componentWillUnmount() {    this._isMounted = false;  }  load(props) {    this.setState({      isLoaded: false,    });    const {modules} = props;    const keys = Object.keys(modules);    Promise.all(keys.map((key) => modules[key]()))      .then((values) => (keys.reduce((agg, key, index) => {        agg[key] = values[index];        return agg;      }, {})))      .then((result) => {        if (!this._isMounted) return null;        this.setState({modules: result, isLoaded: true});      });  }  render() {    if (!this.state.isLoaded) return null;    return React.Children.only(this.props.children(this.state.modules));  }}LazilyLoad.propTypes = {  children: React.PropTypes.func.isRequired,};export const LazilyLoadFactory = (Component, modules) => {  return (props) => (    
{(mods) =>
}
);};export const importLazy = (promise) => ( promise.then((result) => result.default));export default LazilyLoad;

回调方式懒加载

这里我们使用类似于bundle-loader中的回调方式进行懒加载,不过将其封装为了组件形式。其中的importLazy主要是为了兼容Babel/ES2015,其只是单纯的返回默认属性值,实例代码参考。

render(){    return ...        
importLazy(System.import('../lazy/loaded_late.js')) }}> { ({LoadedLate}) => { return
} }
...}

高阶组件方式懒加载

在入门介绍中我们讲过可以利用external属性来配置引入jQuery,而这里我们也可以使用高阶组件方式进行异步加载:

// @flowimport React, { Component, PropTypes } from 'react';import { LazilyLoadFactory } from '../../../common/utils/load/lazily_load';/** * 组件LoadedJquery */export default class LoadedJQuery extends Component {  /**   * @function 默认渲染函数   */  render() {    return (      
this.props.$(ref).css('background-color', 'red')}> jQuery加载完毕
); }}export default LazilyLoadFactory( LoadedJQuery, { $: () => System.import('jquery'), });

这里我们将加载完毕的jQuery作为组件的Props参数传入到组件中使用,同样我们也可以使用这种方式加载我们自定义的函数或者组件。上述两种的效果如下所示:

转载地址:http://lgvoo.baihongyu.com/

你可能感兴趣的文章
SCCM2012 R2集成WSUS服务器-4:部署软件更新组
查看>>
关于 Virtual SAN/VSAN 的常见问题解答
查看>>
揭秘8大自媒体平台注册方法,通过率百分之九十
查看>>
技术和赚钱真的冲突吗?
查看>>
  SEO的十种赚钱方式
查看>>
Exchange企业实战技巧(26)在Outlook中打开多个邮箱
查看>>
3C趋势价值对云计算发展的驱动作用
查看>>
职场有影帝出没,屌丝们请当心!
查看>>
Xen Desktop测试报告
查看>>
Lync与Exchange 2013 UM集成:Lync Server配置
查看>>
烂泥:利用Diskgen找回分区破坏前的资料
查看>>
通过Python脚本理解系统进程间通信
查看>>
轻操作动作休闲单机游戏《狂斩三国2》评测
查看>>
【VMCloud云平台】SCAP(一)规划
查看>>
Exchange 2016集成ADRMS系列-12:域内outlook 2010客户端测试
查看>>
【VMCloud云平台】拥抱Docker(六)关于DockerFile(1)
查看>>
庆祝教师节,李宁老师课程优惠劵疯抢中、会员卡优惠中,先到先得
查看>>
为Windows Server 2012 R2指定授权服务器
查看>>
Server 2008 R2 AD RMS完整部署:AD部署篇
查看>>
靠能力赚大钱,是最最可笑的谎言
查看>>