简体   繁体   中英

Importing and running a standalone React application inside a web component

I have a standalone React application that uses webpack for bundling with a requirement of being able to run this bundle within a web component. Can anyone suggest how I should approach this?

I'm thinking something like:

//webpack.config.js
output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js',
        library: 'reactUmd',
        libraryTarget: 'umd',
        umdNamedDefine: true
    },

//react-component.js
import '../../packages/react-umd/dist/bundle.js'

class ReactComponent extends HTMLElement {
  connectedCallback() {
    const mountPoint = document.createElement('span');
    this.attachShadow({ mode: 'open' }).appendChild(mountPoint);
    reactUmd.renderSomeComponentTo(mountPoint)
  }
}

customElements.define('react-component', ReactComponent)

But I'm not sure how I can import the compiled bundle and get a reference to React, ReactDOM, the Main component etc, would exporting as UMD provide the references I need?

So you basically want to access the react component outside the minified bundle file.

Here is one approach:

  • You tell webpack to create a library for your file. This will basically create a global variable using which you can access all the exported functions from you js entry file. To do so, add a key called library int your webpack config under output object.

    module.exports = { entry: './main.js', output: { library: 'someLibName' }, ... }

  • After doing this, restart your webpack server and on console, type window.someLibName. This should print all the methods exported by main.js as an object.

  • Next step is to create a function which accepts a DOM element and renders the react component on the element . The function would look something like this:

    export const renderSomeComponentTo = (mountNode) => { return ReactDOM.render(<App />,MOUNT_NODE); }

  • Now you can access the above function from anywhere in the project, using

    const mountNode = document.getElementById('theNodeID'); window.someLibName.renderSomeComponentTo(mountNode);

This way, all the react specific code is abstracted :)

I hope I answered your question. Don't forget to hit star and upvote. Cheers 🍻

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM