Uncaught Error: Cannot Find Module When Using Dynamic Import for JavaScript

Uncaught Error: Cannot Find Module When Using Dynamic Import for JavaScript

我正在使用 Create-React-App 并希望使用 webpack 2.0 支持的动态 import() 来导入基于变量字符串的模块。

我看了官方的提议(https://github.com/tc39/proposal-dynamic-import),似乎可以这样做:

import(`./language-packs/${navigator.language}.js`)

但是当我尝试类似的东西时它就坏了。

AppRoutes.js

import LazyLoad from 'services/LazyLoad';

export class AppRoutes extends React.Component {
  render() {
    return (
      <Switch>
        <Route
          exact path="/"
          render={(matchProps) => (
            <LazyLoad
              absoluteModulePath='pages/default/HomePage'
              getComponent={() => import('pages/default/HomePage')}
              {...matchProps}
            />
          )}
        />
      </Switch>
    );
  }
}

export default AppRoutes;

pages/default/HomePage/index.js

import React from 'react';

export const HomePage = () => {
  return (
    <div>
      I'm the default HomePage
    </div>
  );
}

export default HomePage;

损坏 services/LazyLoad/index.js

import React from 'react';

export class LazyLoad extends React.Component {
  ...

  componentDidMount() {
    import(this.props.absoluteModulePath)  // Critical dependency: the request of a dependency is an expression
      .then(module => module.default)
      .then(AsyncModule => this.setState({AsyncModule}))
  }

  ...
}

export default LazyLoad;

错误:

但是当我将 LazyLoader 更改为

正在工作 services/LazyLoad/index.js

import React from 'react';

export class LazyLoad extends React.Component {
  ...

  componentDidMount() {
    this.props.getComponent()
      .then(module => module.default)
      .then(AsyncModule => this.setState({AsyncModule}))
  }

  ...
}

export default LazyLoad;

有效。

绝对路径是在环境变量的帮助下内置到 create-react-app 中的东西。

.env

NODE_PATH=src/

我需要以这种方式动态加载模块来构建多租户的概念证明。如何修复损坏的 LazyLoad,以便我可以将字符串作为 prop 传递,并让 LazyLoad 组件从该字符串 prop 动态加载组件?

import() 只允许部分动态语句。

在您的 AppRoutes.js 中,您可以这样做:

...
<LazyLoad
    modulePath='HomePage'
    getComponent={() => import('pages/default/HomePage')}
    {...matchProps}
/>

然后在您的 LazyLoad 组件中执行:

componentDidMount() {
  import(`pages/default/${this.props.modulePath}/index.js`)
    .then(module => module.default)
    .then(AsyncModule => this.setState({AsyncModule}))
}

Fully dynamic statements, such as import(foo), will fail because webpack requires at least some file location information.The import() must contain at least some information about where the module is located, so bundling can be limited to a specific directory or set of files.

https://webpack.js.org/api/module-methods/#import-