Hosting multiple React applications on the same document
December 02, 2018
Hosting multiple React applications on the same document. Should be easy ...
One simple/naive approach to break up a big single page application is to split it into different single page applications which then are loaded on the same html document.
Unfortunately it is not possible to run several create-react-app applications on the same document., because the JavaScript bundles resulting from a cra project is not without side-effects: The bundled WebPack runtime writes an object on the global scope, which prevents to load several such bundles.
The following steps illustrate the problem and show how to fix it:
The Setup
1npx create-react-app react-app1 --use-npm2npx create-react-app react-app2 --use-npm
Changing the second React app to run on another port in development mode:
1// package.json2scripts: {3 "start":"PORT=3001 react-scripts start"4..}
Change the DOM node on which the second React app is bootstrapped:
1<!-- index.html -->2<div id="app2-root"></div>
1// index.js2ReactDOM.render(<App />, document.getElementById('app2-root'))
Run the first React application:
1cd react-app12npm start
Run the second React application:
1cd react-app22npm start
Load the second React app on the document of the first React app:
1// index.html2<div id="app2-root"></div>34<script src="http://localhost:3001/static/js/bundle.js"></script>5<script src="http://localhost:3001/static/js/1.chunk.js"></script>6<script src="http://localhost:3001/static/js/main.chunk.js"></script>
Unfortunately this does not have the expected result: We only see the second React app bootstrapped on the page.
The Problem
Somehow loading the scripts of the second React app has a side effect and prevents the bootstrapping of the first React app!
It turns out that the WebPack runtime is the problem here. The WebPack runtime
adds an object to the global scope which is used to lazy-load chunks. The
default name for this function is webpackJsonp
.
The Solution
The name of this object can be configured in the WebPack config.
To get access to the WebPack config of a create-react-app project, you need to eject or use another customization mechanism like customize-cra.
Then you can change the Webpack config like this:
1// webpack.config.dev.json2...3output {4 ...5 jsonpFunction: 'jsonpApp2'6}
Once you have changed the jsonpFunction
of your second React app to a unique
value, you must restart the development server (npm start
)
Make sure that the document of the first app still references the correct scripts from the second app. Sometimes WebPack decides to rename the chunks…
And voilà: Both applications are bootstrapped on the same document:
Note: I only showed here how to adjust the WebPack configuration for the development build. The same change is needed for the production WebPack configuration. For production the project also has to solve the challenge of adding the correct script names to the integrating document, since WebPack (i.e in create-react-app) is configured to add a hash of the script content to the script name.