title: React application with external plugins
body: <p>I'm building a React application bundled using Parcel or Webpack.<br>
  The application should be able to embed external React components<br>
  developed by third-parties and hosted elsewhere as modern javascript modules:</p>
  
  <pre><code>// https://example.com/scripts/hello-plugin.js
  import React from 'react';
  
  export default class HelloPlugin extends React.Component {
      render() {
          return "Hello from external plugin!";
      }
  }
  </code></pre>
  
  <p>Host application loads these components using asynchronous import like this, for example:</p>
  
  <pre><code>// createAsyncComponent.tsx
  import * as React from 'react';
  import { asyncComponent } from 'react-async-component';
  
  export default function createAsyncComponent(url: string) {
      return asyncComponent({
          resolve: () =&gt; import(url).then(component =&gt; component.default),
          LoadingComponent: () =&gt; &lt;div&gt;Loading {url}....&lt;/div&gt;,
          ErrorComponent: ({ error }) =&gt; &lt;div&gt;Couldn't load {url}: {error.message}&lt;/div&gt;,
      })
  }
  </code></pre>
  
  <p>But looks like bundlers don't allow importing arbitrary urls as external javascript modules. </p>
  
  <p>Webpack emits build warnings: "the request of a dependency is an expression" and the import doesn't work. Parcel doesn't report any errors, but fails when import(url) occurs at runtime.</p>
  
  <p>Webpack author recommends using scriptjs or little-loader for loading external scripts.<br>
  There is <a href="https://gist.github.com/revolunet/cfc6fe0c5992897b29388373a8e51be7" rel="noreferrer">a working sample</a> that loads an UMD component from arbitrary URL like this:</p>
  
  <pre><code>public componentDidMount() {
      // expose dependencies as globals
      window["React"] = React;
      window["PropTypes"] = PropTypes;
  
      // async load of remote UMD component
      $script(this.props.url, () =&gt; {
          const target = window[this.props.name];
          if (target) {
              this.setState({
                  Component: target,
                  error: null,
              })
          } else {
              this.setState({
                  Component: null,
                  error: `Cannot load component at ${this.props.url}`,
              })
          }
      });
  }
  </code></pre>
  
  <p>Also, I saw a <a href="https://stackoverflow.com/questions/44778265/dynamically-loading-react-components">similar question</a> answered a year ago where the suggested approach also involves passing variables via a window object.</p>
  
  <p>But I'd like to avoid using globals given that most modern browsers support modules out of the box.</p>
  
  <p>I'm wondering if it's possible. Perhaps, any way to instruct the bundler that my import(url) is not a request for the code-split chunk of a host application, but a request for loading an external Javascript module.</p>