8

我正在使用 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;

页面/默认/主页/index.js

import React from 'react';

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

export default HomePage;

损坏的服务/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 更改为

工作 服务/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 以便我可以将字符串作为道具传递并让 LazyLoad 组件从该字符串道具动态加载组件?

4

1 回答 1

14

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}))
}

完全动态的语句,例如 import(foo),会失败,因为 webpack 至少需要一些文件位置信息。 import() 必须至少包含一些关于模块所在位置的信息,因此捆绑可以限制到特定目录或文件集。

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

于 2017-07-12T23:58:51.490 回答