Динамический импорт в реакции не работает при попытке импортировать компонент в другой каталог - PullRequest
0 голосов
/ 18 января 2019

Привет всем, я пробовал динамический импорт в реаги для рендеринга моих компонентов для приложения, созданного с помощью CRA (create-реагировать-приложение), и хотя он работает отлично для некоторых случаев, но для некоторых он возвращает не может загрузить ошибку модуля, например Я загружал компонент (помещенный в каталог под src) динамически в мой index.js, который работает нормально, но когда я пытаюсь отобразить дочерний или вложенный компонент внутри, который также с динамическим подходом импорта, это дает ошибку, не может загрузить модуль. Обратите внимание, что эта ошибка возникает только в том случае, если вложенный компонент размещен вне каталога исходного родительского компонента, достаточно поговорить здесь о коде.

Мои index.js помещены в src.

    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';

    class Dynamic extends Component {
      constructor(props) {
        super(props);
        this.state = { module: null };
      }
      componentDidMount() {
          console.log('in comp mount')
          //alert("in comp mount")
        const { path } = this.props;
        import(`${path}`)
          .then(module => this.setState({ module: module.default }))
     }
      render() {
          console.log('in render')
         // alert("in render")
        const { module: Component } = this.state; // Assigning to new variable names @see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
        return(
          <div>
            {Component && <Component path= '../FooterComp/Footer' />}
          </div>
        )
      }
    }

ReactDOM.render(<Dynamic path='./Components/FirstComponent' />, document.getElementById('root'));

FirstComponent.js помещен в каталог компонентов под src.

import React, { Component } from 'react';
import logo from '../logo.svg';
import '../FirstApp.css';

class App extends Component {

    constructor(props) {
    super(props);
    this.state = { module: null };
  }
  componentDidMount() {
      console.log('in comp mount')
      //alert("in comp mount")
    const { path } = this.props;
    alert(path)
    import(`${path}`)
      .then(module => this.setState({ module: module.default }))
 }

  render() {
      const { module: Component } = this.state;
    return (
      <div className="App">
        <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
        {Component && <Component />}
      </div>
    );
  }
}

export default App;

Footer.js находится в каталоге FooterComp под src.

import React, { Component } from 'react';
import '../App.css';

class Footer extends Component {
    componentDidMount()
    {
        console.log('in componentDidMount of Footer')
    }
  render() {
      console.log('in render of Footer')
    return (
      <div className="App">
        <h1>Edited by Me</h1>
      </div>
    );
  }
}

export default Footer;

Почему это работает, когда я передаю свой первый компонент из моего index.js, но не работает для компонента нижнего колонтитула при попытке импортировать в мой первый компонент?

Сообщение об ошибке: Error: Cannot find module '../FooterComp/Footer'

Также обратите внимание, что если я помещаю компонент нижнего колонтитула в тот же каталог, что и Firstcomponent, и корректирую путь, он работает нормально

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Существует ограничение при использовании динамического импорта с «переменными частями», такими как import(`${path}`).

При создании пакета Webpack

В вашем случае, когда был вызван компонент import(`${path}`) в Dynamic, webpack создал пакет. Этот комплект был для FirstComponent компонента. Внутри этого пакета веб-пакет содержит список компонентов, которые можно динамически импортировать с помощью «переменных частей» в компоненте FirstComponent. Он содержит только файлы, которые находятся в той же папке, где находился компонент FirstComponent. Это потому, что вы использовали import(`${path}`) в FirstComponent.

Все это происходит потому, что webpack при компиляции не знает, какой будет точный путь импорта во время выполнения, так как вы используете динамический импорт с «переменными частями».

Во время запроса приложения React

Когда import(`${path}`) было выполнено в Dynamic Компонент. Пакет для FirstComponent был запрошен. Как только пакет был получен, и он выполнил свой код, а path, который вы указали как компонент props - FirstComponent, не был в списке компонентов, которые можно динамически импортировать с помощью «переменных частей».

То же самое относится и к компоненту Dynamic, если вы попытаетесь динамически импортировать файлы с «переменными частями» для файлов, которые находятся вне папки src, вы получите ту же ошибку.

Так что для решения этой проблемы у вас есть несколько вариантов

1) поместить оба файла в одну папку

т.е.

'src/Components/FirstComponent'

'src/Components/Footer'

И использовать

// In FirstComponent.js
   componentDidMount() {
      const { path } = this.props;
      import(`${path}`)
      .then(module => this.setState({ module: module.default }))   
   }


{Component && <Component path='./Footer' />} // Index.js

2) быть более конкретным, насколько это возможно

т.е.

// In FirstComponent.js
 componentDidMount() {
      const { path } = this.props;
      import(`../FooterComp/${path}`)
      .then(module => this.setState({ module: module.default }))   
 }

и использовать

{Component && <Component path='Footer' />} //  In index.js
0 голосов
/ 18 января 2019

Если FooterComp находится под src, путь должен быть './FooterComp/Footer', а не '../FooterComp/Footer'


Редактировать

index.js

    render() {
          console.log('in render')
         // alert("in render")
        const { module: Component } = this.state; 
        return(
          <div>
            {Component && <Component path='./Components/FirstComponent' />}
          </div>
        )
      }
    }

ReactDOM.render(<Dynamic />, document.getElementById('root'));

FirstComponent.js

render() {
      const { module: Component } = this.state;
    return (
      <div className="App">
        <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
        {Component && <Component path= '../FooterComp/Footer' />}
      </div>
    );
  }
...