首页 文章

未捕获的错误:使用JavaScript的动态导入时无法找到模块

提问于
浏览
4

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

BROKEN 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;

错误:

enter image description here

但是当我将LazyLoader更改为

WORKING 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;

有用 .

enter image description here

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

.ENV

NODE_PATH=src/

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

1 回答

  • 5

    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-

相关问题