Search code examples
javascriptreactjssystemjs

SystemJS, using importmap with module, that needs react


I have created a javascript library with webpack, that outputs a systemjs module. This module has a dependency on react, which I specified as an external. The resulting javascript file starts like this:

System.register(["react"], function(__WEBPACK_DYNAMIC_EXPORT__) {
var __WEBPACK_EXTERNAL_MODULE_react__;
return { ....

Additionally I have an app, that uses SystemJS during runtime to load that module. In order to provide the react dependency, I have defined an importmap:

{
   "imports": {
      "react": "https://unpkg.com/react@16.11.0/umd/react.production.min.js"
   }
}

And the part, where I import the module, looks like this:

const modulePromise = System.import(MODULE_URL);
modulePromise.then(module => {
  console.log('module loaded successfully!');
});

The problem now is, that the console.log is never called, because I get a TypeError, that says, that "Component is not a property of undefined", which tells me, that somehow react has not correctly been passed to my module.

To be precise, in the browser network tab I see, that my module and the react import is indeed loaded, but somehow it is not correctly processed.

Has anyone an idea, what i might be doing wrong?


Solution

  • OK, so eventually I solved this myself, although a bit different.

    First, I did not use the unpkg link anymore, but I actually include React as a library in my main app.

    And I changed my importmap to:

    <script type="systemjs-importmap">
       {
         "imports": {
           "react": "app:react",
           "react-dom": "app:react-dom"
         }
       }
    </script>
    

    Also in the main app I use System.set(...) from SystemJs to tell SystemJS where to find the 'app:react' and 'app:react-dom' dependencies:

    import * as React from 'react';
    import * as ReactDOM from 'react-dom';
    import 'systemjs/dist/system.min';
    
    ...
    
    System.set('app:react', { default: React, __useDefault: true });
    System.set('app:react-dom', { default: ReactDOM, __useDefault: true });
    

    And now, if I load my module with that external react dependency through SystemJS, it works.