If you have worked with legacy apps, you know doing a big bang migration of one framework to another is not easy peasy!

A bit of history:

Once upon a time I had worked on a project to migrate our legacy Angular app to React.js. Basically we had 2 separate applications, one for our mobile website, built using angular, angular-router. And our desktop app, on React. After duplicating our estimates for each piece of work, having to do the same feature on both Angular and React, we decided to stick with one of them and make the whole site responsive. Our choice was to responsify our Desktop app built in React.

In this post I will give you a starting point for you to do this, using the power of webpack and ngReact.

Show me the code!

Let’s start with our legacy angular app. Suppose this is the html page you’re serving:

Note we have the script tags for angular and angular-router and our app angular-app.

Let’s have a look now at the angular app:

There is nothing particularly interesting so far. Just a simple angular application which will render /legacy/templates/home.html for the route /#home. This is the home template:

If we serve what we have so far :

index.html

Now, let’s suppose we want to render a React component in the home page template. For that I’m going to use ngReact, which uses react and react-dom to render your React components.
Before we configure ngReact in our angular app, let’s say we have the following React component which we want to render:

Now, we will bundle our react app using webpack. The most IMPORTANT thing to note here is we need to EXPOSE in the window the React component, so that ngReact can actually see it and use it.

This is the webpack.config:

First, on our entry, note we are explicitly requiring react-dom and ngReact. If we don’t do this, webpack won’t include it in the bundle as these libraries are not used in the React app. Note we don’t do ReactDOM.render ... anywhere.
The second important part is the output where we have asked webpack: Can you expose in the root scope(that’s what libraryTarget: "var" means) a variable called ReactEntry? This will allow you to access DummyComponent from the window: window.ReactEntry.DummyComponent.
Lastly, we use the plugin expose-loader to have the library ngReact on the window as well. Alternatively you could have ngReact on a script tag separately from your webpack bundle, but I prefer to have everything processed by webpack whenever possible.

Now, let’s configure ngReact. First, we need to add an extra dependency called ‘react’ to the angular module:

var myApp = angular.module('myApp', ['ngRoute', 'react']);

Then set the component for ngReact to use like this:

myApp.value('DummyComponent', window.ReactEntry.DummyComponent);

Now we can render DummyComponent in home.html using a custom directive provided by ngReact:

And this is what the final product looks like:

index.html

There is a repo available on github, https://github.com/danielcondemarin/angular-react-hybrid.

Feel free to comment below if you have any questions :)