尝试在另一个目录中导入组件时,动态导入反应不起作用
Dynamic import in react not working when trying to import a component in another directory
大家好,我一直在尝试使用动态导入来响应,以便为使用 CRA (create-react-app) 创建的应用程序呈现我的组件,虽然它在某些情况下工作得很好,但在某些情况下它 returns无法加载模块错误,例如我在我的 index.js
中动态加载了一个组件(放置在 src 下的一个目录中),这工作正常但是当我尝试在其中渲染一个子组件或嵌套组件时,它也使用动态导入方法它给出错误无法加载模块。请注意,仅当嵌套组件放置在原始父组件的目录之外时才会出现此错误,这里就是代码。
我的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'
另请注意,如果我将 Footer 组件放在与 Firstcomponent 相同的目录中并调整路径,它就可以正常工作
如果 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>
);
}
使用可变部分的动态导入时存在限制。
It is not possible to use a fully dynamic import statement, such as import(foo). Because foo could potentially be any path to any file in your system or project.
The import() must contain at least some information about where the module is located. Bundling can be limited to a specific directory or set of files so that when you are using a dynamic expression - every module that could potentially be requested on an import() call is included.For example, import(./locale/${language}.json
) will cause every .json file in the ./locale directory to be bundled into the new chunk. At run time, when the variable language has been computed, any file like english.json or german.json will be available for consumption.
在您的情况下,在 FirstComponent
组件中动态导入的构建期间,捆绑仅限于 FirstComponent
组件所在的目录,即 Components
目录。
意思是,webpack 会找到 Components
目录中的所有文件,然后为它们创建 chunks。然后在运行时调用动态导入时,webpack 将提供与传入的值对应的块。
因为你传递的 path= '../FooterComp/Footer'
没有相应的块所以 webpack 会抛出错误。
Dynamic
组件也是如此。如果您尝试为 src
文件夹外的文件动态导入可变部分,您将得到同样的错误。
所以要解决这个问题,您有几个选择
- 将两个文件放在同一个文件夹中
即
'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
- 越具体越好
即
// 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
大家好,我一直在尝试使用动态导入来响应,以便为使用 CRA (create-react-app) 创建的应用程序呈现我的组件,虽然它在某些情况下工作得很好,但在某些情况下它 returns无法加载模块错误,例如我在我的 index.js
中动态加载了一个组件(放置在 src 下的一个目录中),这工作正常但是当我尝试在其中渲染一个子组件或嵌套组件时,它也使用动态导入方法它给出错误无法加载模块。请注意,仅当嵌套组件放置在原始父组件的目录之外时才会出现此错误,这里就是代码。
我的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'
另请注意,如果我将 Footer 组件放在与 Firstcomponent 相同的目录中并调整路径,它就可以正常工作
如果 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>
);
}
使用可变部分的动态导入时存在限制。
It is not possible to use a fully dynamic import statement, such as import(foo). Because foo could potentially be any path to any file in your system or project.
The import() must contain at least some information about where the module is located. Bundling can be limited to a specific directory or set of files so that when you are using a dynamic expression - every module that could potentially be requested on an import() call is included.For example, import(
./locale/${language}.json
) will cause every .json file in the ./locale directory to be bundled into the new chunk. At run time, when the variable language has been computed, any file like english.json or german.json will be available for consumption.
在您的情况下,在 FirstComponent
组件中动态导入的构建期间,捆绑仅限于 FirstComponent
组件所在的目录,即 Components
目录。
意思是,webpack 会找到 Components
目录中的所有文件,然后为它们创建 chunks。然后在运行时调用动态导入时,webpack 将提供与传入的值对应的块。
因为你传递的 path= '../FooterComp/Footer'
没有相应的块所以 webpack 会抛出错误。
Dynamic
组件也是如此。如果您尝试为 src
文件夹外的文件动态导入可变部分,您将得到同样的错误。
所以要解决这个问题,您有几个选择
- 将两个文件放在同一个文件夹中
即
'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
- 越具体越好
即
// 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