zoukankan      html  css  js  c++  java
  • [转] react-router4 实现按需加载

    按需加载的背景

    https://juejin.im/post/58f9717e44d9040069d06cd6?utm_source=tuicool&utm_medium=referral

    React Router 是一个非常出色的路由解决方案,同时也非常容易上手。但是当网站规模越来越大的时候,首先出现的问题是 Javascript 文件变得巨大,这导致首页渲染的时间让人难以忍受。实际上程序应当只加载当前渲染页所需的 JavaScript,也就是大家说的“代码分拆" — 将所有的代码分拆成多个小包,在用户浏览过程中按需加载。

    老的方案

    这里所说的老是指使用react-router低于4的版本。

    在低版本(小于4)的react-router中直接提供了按需加载的方案,示例如下:

    const rootRoute = {
      path: '/',
      indexRoute: {
        getComponent(nextState, cb) {
          require.ensure([], (require) => {
            cb(null, require('components/layer/HomePage'))
          }, 'HomePage')
        },
      },
      getComponent(nextState, cb) {
        require.ensure([], (require) => {
          cb(null, require('components/Main'))
        }, 'Main')
      },
      childRoutes: [
        require('./routes/baidu'),
        require('./routes/404'),
        require('./routes/redirect')
      ]
    }
    
    ReactDOM.render(
      (
        <Router
          history={browserHistory}
          routes={rootRoute}
          />
      ), document.getElementById('app')
    );

    核心代码是router.getComponent,然而在react-router4中,没有router.getComponent了,这样我们该如何实现按需加载呢?

    react-router4的实现方案

    根据官网的介绍:

    One great feature of the web is that we don’t have to make our visitors download the entire app before they can use it.
    You can think of code splitting as incrementally downloading the app. While there are other tools for the job, we’ll use Webpack and the bundle loader in this guide.

    我们要借助bundle-loader来实现按需加载。

    首先,新建一个bundle.js文件:

    import React, { Component } from 'react'
    
    export default class Bundle extends React.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() {
            if (!this.state.mod)
                return false
            return this.props.children(this.state.mod)
        }
    }

    然后,在入口处使用按需加载:

    
    // ...
    
    // bundle模型用来异步加载组件
    import Bundle from './bundle.js';
    
    // 引入单个页面(包括嵌套的子页面)
    // 同步引入
    import Index from './app/index.js';
    // 异步引入
    import ListContainer from 'bundle-loader?lazy&name=app-[name]!./app/list.js';
    
    const List = () => (
        <Bundle load={ListContainer}>
            {(List) => <List />}
        </Bundle>
    )
    
    // ...
    
        <HashRouter>
            <Router basename="/">
                <div>
                    <Route exact path="/" component={Index} />
                    <Route path="/list" component={List} />
                </div>
            </Router>
        </HashRouter>
    
    // ...

    webpack.config.js文件配置

    output: {
        path: path.resolve(__dirname, './output'),
        filename: '[name].[chunkhash:8].bundle.js',
        chunkFilename: '[name]-[id].[chunkhash:8].bundle.js',
    },

    完整代码示例

    bundle.js

    react-molin

  • 相关阅读:
    文档驱动开发模式在 AIMS 中的应用与实践
    软件“美不美”,UI测试一下就知道
    做运维,送你7个常用的服务器资源监控工具
    掌握ROMA Compose,报表清单不秃头
    技术干货丨隐私保护下的迁移算法
    业务爆发式增长,音视频服务如何做好质量监控与优化?
    MyBatis中SQL语句优化小结
    Go语言微服务开发框架:Go chassis
    揭开KPI异常检测顶级AI模型面纱
    激光雷达lidar与点云数据
  • 原文地址:https://www.cnblogs.com/chris-oil/p/7783662.html
Copyright © 2011-2022 走看看