10

大家好,我一直在尝试动态导入,以便为使用 CRA(create-react-app)创建的应用程序渲染我的组件,虽然它在某些情况下完美运行,但对于某些情况,它返回无法加载模块错误,例如我加载了组件(放置在 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 下的 Components 目录下。

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 放在 src 下的 FooterComp 目录下。

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 相同的目录中并调整路径它工作正常

4

2 回答 2

11

使用带有可变部分的动态导入时存在限制。

Webpack 文档

不能使用完全动态的导入语句,例如 import(foo)。因为 foo 可能是系统或项目中任何文件的任何路径。

import() 必须至少包含一些关于模块所在位置的信息。捆绑可以限制在特定目录或文件集,这样当您使用动态表达式时 - 可能会在 import() 调用中请求的每个模块都包括在内。例如,import( ./locale/${language}.json) 将导致每个 .json 文件在 ./locale 目录中捆绑到新块中。在运行时,当变量语言被计算出来后,任何像english.json 或 German.json 这样的文件都可以使用。

在您的情况下,在组件中动态导入的构建期间FirstComponent,捆绑仅限于FirstComponent组件所在的目录,即Components目录。

这意味着,webpack 会找到Components目录中的所有文件,然后为它们创建。然后在运行时调用动态导入时,webpack 将提供与传入的值对应的块。

由于你传递path= '../FooterComp/Footer'的没有对应的块,所以 webpack 会抛出错误。

Dynamic这对于组件也是一样的。如果您尝试使用可变部分动态导入文件src夹外的文件,您将收到相同的错误。

所以要解决这个问题,你有几个选择

  1. 将两个文件放在同一个文件夹中

IE

'src/Components/FirstComponent.js'

'src/Components/Footer.js'

并使用

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


{Component && <Component path='./Footer' />} // Index.js
  1. 尽可能具体

IE

// 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
于 2019-01-18T15:32:21.497 回答
0

'./FooterComp/Footer'如果 FooterComp 在 src 下,则路径不应该是'../FooterComp/Footer'


编辑

索引.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>
    );
  }
于 2019-01-18T14:06:14.727 回答