Ответы пользователя по тегу Webpack
  • Как реализовать динамический import для code splitting в Webpack 2?

    nDiviD
    @nDiviD Автор вопроса
    Делать проекты, которыми можно гордиться
    Нашел я решение, опубликовал ответ на подобный вопрос, напишу и сюда. Все довольно просто, если знать нюансы:
    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"
    />
    Ответ написан
    Комментировать
  • Как сделать ленивую загрузку компонент на React, React Router 4, Webpack 3?

    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. Об использовании компонентов в роутере написано хорошо в туториале =)
    Ответ написан
    6 комментариев