Bundling a React Component library to be used in non-React application (Part - I)

Hi there! Today we will be looking at something interesting. As we know react is a library and can be used with other libraries. Also, components are reusable entities.

Today we will look at how we can create and export a react component so it can be used in non-react component.

There could be many real life examples to this, where you are building features for someone else who may or may not be using React.

  • Part - I : setting the ground for the component library
  • Part - II : bundling component library using gulp
  • Part - III : Hosting and testing component library on Apache server
  • Part-IV : Consuming component library in a Non-react application

Lets get started!

We will leverage the carousel component we created earlier in one of our articles. We will see how we can build it, export it etc.

Pre-requisites

As our carousel component expects books, we need a way by which books can be passed to the component whenever its called, similar to props.

As we will be calling or integrating the react component in non-react application, we can leverage any one of the following options:
  • Using global/windows object
  • callback method

Using global/windows object and using sessionStorage/localStorage are straightforward. Hence we wont be looking at them.

We will use callback method, where we expose one method to the non-react application to set the required data and eventually call us and render in the specific container.

We also need to refactor our carousel now, shred things which dont need anymore, such as:

  • JavaScript

    • Removing imports
    • We will use IIFE to setup a function which will return the reference to our component renderer
    • There is no need to export the class, component renderer function will take care of DOM rendering for us!
    • We will pass props as usual
    • Also, we are assuming that the application in which react component is expected to render does not use Bootstrap, babel and react etc. We will load these and their pre-compiled dependencies in traditional way through HTML!
    • We will also export HTML just for verification purpose (optional step)

    • This is how my Carousel.js looks like:

      •   class MyCarousel extends React.Component {
            render({ carouselItems } = this.props) {
              return (
                <React.Fragment>
                  {carouselItems.length > 0 ? (
                    <div className="add-column-margin">
                      <div
                        id="myCarousel"
                        className="carousel slide"
                        data-ride="carousel"
                      >
                        <ol className="carousel-indicators">
                          {carouselItems.map((carouselItem, index) => {
                            return (
                              <li
                                key={index}
                                data-target="#myCarousel"
                                data-slide-to={index}
                                className={index === 0 ? "active" : ""}
                              ></li>
                            );
                          })}
                        </ol>
                        <div className="carousel-inner">
                          {carouselItems.map((carouselItem, index) => {
                            return (
                              <div
                                key={index}
                                className={
                                  index === 0 ? "carousel-item active" : "carousel-item"
                                }
                              >
                                <img
                                  className="d-block w-100"
                                  src={carouselItem.coverImage}
                                  alt="First slide"
                                ></img>
                                <div className="carousel-caption d-none d-md-block">
                                  <h5
                                    style={{
                                      color: "white",
                                      backgroundColor: "rgba(0, 0, 0, 0.6)",
                                    }}
                                  >
                                    {carouselItem.title}
                                  </h5>
                                </div>
                              </div>
                            );
                          })}
                        </div>
                        <a
                          className="carousel-control-prev"
                          href="#myCarousel"
                          role="button"
                          data-slide="prev"
                        >
                          <span
                            className="carousel-control-prev-icon"
                            aria-hidden="true"
                          ></span>
                          <span className="sr-only">Previous</span>
                        </a>
                        <a
                          className="carousel-control-next"
                          href="#myCarousel"
                          role="button"
                          data-slide="next"
                        >
                          <span
                            className="carousel-control-next-icon"
                            aria-hidden="true"
                          ></span>
                          <span className="sr-only">Next</span>
                        </a>
                      </div>
                    </div>
                  ) : (
                    <h1>No data to display.</h1>
                  )}
                </React.Fragment>
              );
            }
          }

          const ReactCarouselRenderer = (carouselItems, elementId) => {
            ReactDOM.render(
              <React.StrictMode>
                <MyCarousel carouselItems={carouselItems} />
              </React.StrictMode>,
              document.getElementById(elementId)
            );
          };

          (() => {
            window.getReactCarouselRenderer = () => ReactCarouselRenderer;
          })();

  • HTML (Optional)
    • This step is required if you want to check via console if your carousel is working or not as a part of dry run.

      • Include below CDN references:

        • bootstrap's minified css file

        • Custom CSS file (Carousel.css)

        • jQuery, popper and bootstrap.min.js

        • standalone version of babel

        • react and react-dom

        • Your js/jsx file which has react component (still written in JSX!)
    • Important - While including your carousel component js/jsx file in HTML, make sure you have set the script type to "text/babel". Without this, browser won't understand your JSX code and will throw errors.

    • This is how my HTML looks like:


    •   <!DOCTYPE html>
        <html lang="en">
          <head>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1" />
            <meta name="theme-color" content="#000000" />
            <meta
              name="description"
              content="Web site created using create-react-app"
            />
            <link
              rel="stylesheet"
              href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
            />
            <title>React App</title>
            <link type="stylesheet" href="./Carousel.css" />
          </head>
          <body>
            <div class="row">
              <div class="col-md-6">
                <div id="root"><h3>This is a React Carousel Component Library</h3></div>
              </div>
            </div>

            <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
            <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js"></script>
            <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js"></script>

            <!-- Babel Dependencies -->
            <script
              src="https://unpkg.com/babel-standalone@6/babel.min.js"
              defer
            ></script>

            <!-- React Dependencies -->
            <script
              src="https://unpkg.com/react@16.7.0/umd/react.production.min.js"
              crossorigin
            ></script>
            <script
              src="https://unpkg.com/react-dom@16.7.0/umd/react-dom.production.min.js"
              crossorigin
            ></script>

            <!-- Babel Dependencies -->
            <script
              src="https://unpkg.com/babel-standalone@6/babel.min.js"
              defer
            ></script>
            <script type="text/babel" src="./Carousel.js" defer></script>
          </body>
        </html>



Comments

Popular Posts