Search error: Cannot find module when using dynamic import for JavaScript
I am using Create-React-App and I want to use dynamic import () supported by webpack 2.0 to import a module based on a variable string.
I looked at the official proposal ( https://github.com/tc39/proposal-dynamic-import ) and it looks like something like this can be done:
import(`./language-packs/${navigator.language}.js`)
But it breaks when I try something like this.
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;
Mistake:
But when I change the LazyLoader to
WORK service /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.
Absolute paths are something built into the create-response-app using environment variables.
.env
NODE_PATH=src/
I need to load modules dynamically in a way to build a proof of concept for a multi-tenant lease. How can I fix the broken LazyLoad so that I can pass a string as a prop and have the LazyLoad component dynamically load the component from that prop string?
source to share
Only a partially dynamic statement is allowed for import ().
In your AppRoutes.js application, you can 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 like import (foo) will fail because webpack requires at least some file location information. Import () must contain at least some information about where the module is located, so linking can be limited to a specific directory or set of files.
source to share