@htmldeveloper

Как сделать ленивую загрузку компонент на React, React Router 4, Webpack 3?

В туториале нового react-router предлагается использовать "bundle-loader", где-то предлагается System.import, где-то до сих пор module.ensure, однако все это устаревшие примеры. Как собирать все это сегодня (React, React Router 4, Webpack 3) ?
  • Вопрос задан
  • 2670 просмотров
Решения вопроса 1
nDiviD
@nDiviD
Делать проекты, которыми можно гордиться
И так, с Webpack 3 все довольно просто, если знать нюансы:
1) Нужно понимать, что то что мы хотим загрузить должно быть в отдельном файле - чанке.
2) Для того что бы создался чанк необходимо все импорты этого компонента грузить "лениво". Это очень важно, в свое время именно это мешало мне разбить существующий проект на чанки.
3) Ну и самое простое: грузим через промис import:
const loadEditor = () => import(/* webpackChunkName: "my-best-editor-chunk" */ 'react-dart-editor');
  loadEditor().then(m => use it);

4) Конфиг webpack:
new webpack.optimize.CommonsChunkPlugin({
  children: true,
  async: true,
  minChunks: 2,
}),
new webpack.optimize.CommonsChunkPlugin('manifest'),


Так же можно импортировать и функции.

Я использую такой компонент:
Chunk.jsx
import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Chunk extends Component {
  state = { LoadedComponent: null };

  componentWillMount() {
    if (this.props.preload) this.load(this.props);
  }

  componentWillReceiveProps(nextProps) {
    const { load, component, show } = nextProps;
    if (
      this.props.load !== load ||
      this.props.component !== component ||
      (this.props.show !== show && show)
    ) {
      this.load(nextProps);
    }
  }

  load(props) {
    this.setState({ LoadedComponent: null });
    props.load().then((mod) => {
      this.setState({
        LoadedComponent: props.component ? mod[props.component] : mod.default,
      });
    });
  }

  renderLoading = () => this.props.showLoading ? (<div>Loading</div>) : null;

  render() {
    const { LoadedComponent } = this.state;
    const  { show, ...props } = this.props;
    delete props.load;
    delete props.component;
    if (!show) return null;
    return LoadedComponent ? <LoadedComponent {...props} /> : this.renderLoading();
  }
}

Chunk.defaultProps = {
  showLoading: false,
  preload    : true,
  show       : true,
};

Chunk.propTypes = {
  load       : PropTypes.func.isRequired,
  show       : PropTypes.bool,
  preload    : PropTypes.bool,
  component  : PropTypes.string,
  showLoading: PropTypes.bool,
};

export default Chunk;



Использовать так:
<Chunk
  load={loadEditor} // была уже выше
  component="EditorAside" // если нужно что-то, что импортируется не по дефоулту
  show={true/false} // отображать ли компотнент
  preload={true/false} // осуществлять ли предзагрузку чанка
  props1="1"
  props2="2"
/>


P.S. Об использовании компонентов в роутере написано хорошо в туториале =)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы