Navigating Webpack Module Federation: Managing React 17 and React 18 Integration
Published: 2023-12-08 17:24:57

_Today's fast-paced tech realm presents challenges with different React versions coexisting in one environment. This article explores integrating React 17 and React 18 within Webpack Module Federation, ensuring a seamless partnership._

The interaction between React 17 (father app) and React 18 (child app) faces inherent challenges due to their distinct virtualized DOMs. Rendering both together can spark version conflicts, demanding a thoughtful strategy for integration.

**Setting Up the Father App (React 17)**

In the father app, we face the challenge of incorporating a child app built with React 18 while maintaining isolation. To address this, we create a designated `<div>` within the father app where the React 18 child will render, avoiding conflicts with the React 17 DOM structure.

```javascript
// Father App (React 17)
const componentCleanup = useCallback(() => {
  unmount()
}, [remotes.name])

useEffect(() => {
  mount({
    idParent: "children_app"
  })

  window.addEventListener('beforeunload', componentCleanup)

  return () => {
    componentCleanup()
    window.removeEventListener('beforeunload', componentCleanup)
  }
}, [componentCleanup])

<div id="children_app" />
```

**Child App (React 18) Integration**

The child app, developed with React 18, employs a mount controller to handle the rendering process within the specified `<div>` of the father app. This ensures the creation of an isolated instance of React 18, mitigating version conflicts.

```javascript
import { createRoot } from 'react-dom/client'

import App from './App/appMain/AppMain'

window.childapp_ready = false
const RootCache = new Map()

function handleRecoverableError(error) {
  console.error('CHILD-APP ERROR:', error)
}

function mount({ idParent }) {
  if (window.childapp_ready) return

  const container = document.getElementById(idParent)

  const root = createRoot(container, {
    onRecoverableError: handleRecoverableError
  })

  root.render(<App />)

  window.childapp_ready = true

  RootCache.set(idParent, root)

  return root
}

function unmount({ idParent }) {
  RootCache.get(idParent)?.unmount()
  window.childapp_ready = false
}

export default { mount, unmount }

```

**Webpack Configuration for Child App**

The webpack configuration for the child app ensures proper sharing and handling of React versions within the Webpack Module Federation setup:

```javascript
module.exports = {
  name: 'childapp',
  path: 'build-child',
  port: 3333,
  openBrowser: false,
  remotes: [],
  exposes: [
    {
      componentName: 'App',
      componentPath: './src/App/appMain/AppMain.tsx'
    },
    {
      componentName: 'Mount',
      componentPath: './src/mountApp.js'
    }
  ],
  shared: {
    react: {
      requiredVersion: '*',
      import: 'react',
      shareKey: 'react',
      shareScope: 'default',
      singleton: false
    },
    'react-dom': {
      requiredVersion: dependencies['react-dom'],
      singleton: true
    }
  }
}
```


**Managing React 18 Isolation**

By leveraging this structured approach, invoking the `mount` function within the father app ensures an encapsulated instance of React 18 is rendered within the designated `<div>`. This segregation prevents interference between the React 17 and React 18 instances, promoting a conflict-free environment.

Now we can see that we have two reacts working in the same page!
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvvl0wq4nigd3pdrq50a.png)

**Closing Thoughts**

Managing the integration of disparate React versions demands meticulous planning and implementation. Utilizing Webpack Module Federation provides a strategic avenue to ensure the coexistence of React 17 and React 18 without version conflicts.

example github project: https://github.com/module-federation/module-federation-examples/tree/master/different-react-versions-isolated

Feel free to connect with me on [LinkedIn](https://www.linkedin.com/in/jeancatarina/) for further discussions and insights into React version integration using Webpack Module Federation.