Using dynamic import within a Webpack-exported library
Asked Answered
T

0

11

I am exporting a React component as a library via Webpack. Within that library, I have several React.lazy() calls performing dynamic imports:

library.tsx:

import React from 'react';
const ComponentCheap = React.lazy(() => import('./ComponentCheap/index');
const ComponentExpensive = React.lazy(() => import('./ComponentExpensive/expensive');
export default function LibComponent(props) {
    return (<div>
        <Suspense fallback="Loading...">
            (props.useExpensive ? <ComponentExpensive /> : <ComponentCheap />)
        </Suspense>
    </div>)
}

That library is in turn being React.lazy() loaded in the consuming application:

app.tsx:

import React from 'react';
import ReactDOM from 'react-dom';
const LibComponent = React.lazy(() => import('@mystuff/library'));

ReactDOM.render((
    <Suspense fallback="Loading...">
        <LibComponent />
    </Suspense>
), document.body);

Here is the problem: When webpack generates the library bundle, it correctly splits out ComponentCheap and ComponentExpensive into separate chunks, placed properly in the library file, but generates code to load those chunks as if they were on the root of the application instead:

var ComponentCheap = react__WEBPACK_IMPORTED_MODULE_0___default.a.lazy(function () { return __webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./ComponentCheap/index */ "./src/ComponentCheap/index.tsx")); });
var ComponentExpensive = react__WEBPACK_IMPORTED_MODULE_0___default.a.lazy(function () { return __webpack_require__.e(/*! import() */ 1).then(__webpack_require__.bind(null, /*! ./ComponentExpensive/index */ "./src/ComponentExpensive/index.tsx")); });

And on the root application, that's exactly what happens - the React.lazy() loads are executed and try to fetch http://<domainname>/0.index.js and http://<domainname>/1.index.js, rather than the correct library path as it should be.

Is this currently a bug/deficiency in Webpack, in that libraries simply do not support using dynamic import internally yet, or is there something in the Webpack config that I need to do to enable this? Do I need to signal in the library's Webpack config that it's also exporting chunks alongside the main module? Does the application need to have something set inside its own Webpack config in order to pick up on those chunks?

Toner answered 6/6, 2020 at 23:30 Comment(2)
Did you find any solution for this?Weeping
@Weeping Not really. I did find that you can tell Webpack what directory you intend to serve the module from, but only at the point the module is being compiled, which doesn't help with external libraries.Toner

© 2022 - 2024 — McMap. All rights reserved.