最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Uncaught Error: Cannot Find Module When Using Dynamic Import for JavaScript - Stack Overflow

programmeradmin3浏览0评论

I'm using Create-React-App and am looking to use the dynamic import() supported by webpack 2.0 to import a module based on a variable string.

I've looked at the official proposal () and it seems possible to do something like this:

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

But it breaks when I try something similar.

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;

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;

Error:

But when I change the LazyLoader to

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;

it works.

The absolute paths is something built into create-react-app with the help of environment variables.

.env

NODE_PATH=src/

I require dynamically loading modules this way to build a proof of concept for multi-tenancy. How can I fix the broken LazyLoad such that I can pass a string as a prop and have the LazyLoad component dynamically load the component from that string prop?

I'm using Create-React-App and am looking to use the dynamic import() supported by webpack 2.0 to import a module based on a variable string.

I've looked at the official proposal (https://github.com/tc39/proposal-dynamic-import) and it seems possible to do something like this:

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

But it breaks when I try something similar.

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;

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;

Error:

But when I change the LazyLoader to

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;

it works.

The absolute paths is something built into create-react-app with the help of environment variables.

.env

NODE_PATH=src/

I require dynamically loading modules this way to build a proof of concept for multi-tenancy. How can I fix the broken LazyLoad such that I can pass a string as a prop and have the LazyLoad component dynamically load the component from that string prop?

Share Improve this question asked May 24, 2017 at 18:50 Kyle TruongKyle Truong 2,7419 gold badges36 silver badges55 bronze badges 5
  • Have you tried using './pages/default/HomePage' as a path string instead of pages/default/HomePage? – Michael Lyons Commented May 24, 2017 at 19:14
  • Just tried it now with ./pages and ../pages and ../../pages and it gives me the same error. – Kyle Truong Commented May 24, 2017 at 19:27
  • Hmmm, maybe without the period, /pages..., otherwise I don't know. For bundle splitting I use require.ensure within React-Router's getComponent. Don't have experience with lazy-loading via import, sorry. – Michael Lyons Commented May 24, 2017 at 19:53
  • 1 Have you found that require.ensure works with interpolated strings or expressions rather than plain strings? – Kyle Truong Commented May 25, 2017 at 13:44
  • Yes I just tried it with a string literal that evaluates correctly. Where are you trying to source this string from? A build environment variable? On client side based on an API call? There's a good example of this here: Github – Michael Lyons Commented May 25, 2017 at 18:37
Add a comment  | 

1 Answer 1

Reset to default 18

Only partially dynamic statement are allowed for import().

In your AppRoutes.js you could do this:

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

then in your LazyLoad Component you do:

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-

发布评论

评论列表(0)

  1. 暂无评论