Single SPA (micro-frontend) - React Query v3.34.15
I was getting this error while trying to integrate a sigle-spa react parcel into the root application.
I used craco-plugin-single-spa-application
for the building of a CRA app as a way to adapt it for a parcel. In the entry config I was pointing to my single-spa-react
config.
// craco.config.js
const singleSpaApplicationPlugin = require('craco-plugin-single-spa-application')
module.exports = {
plugins: [
{
plugin: singleSpaApplicationPlugin,
options: {
orgName: 'uh-platform',
projectName: 'hosting',
entry: 'src/config/single-spa-index.cf.js',
orgPackagesAsExternal: false,
reactPackagesAsExternal: true,
externals: [],
minimize: false
}
}
]
}
In the single-spa-index.cf.js
file I had the following configs.
import React from 'react'
import ReactDOM from 'react-dom'
import singleSpaReact from 'single-spa-react'
import App from '../App'
const lifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: App,
errorBoundary() {
return <div>Ocorreu um erro desconhecido!</div>
}
})
export const { bootstrap, mount, unmount } = lifecycles
After reading a bunch of forums and the react-query documentation, the only thing that I figured out I needed to change was pass in the QueryClientProvider
the prop contextSharing
as true. After had did this change, ran the building and access the route that opens my parcel. I got the same error.
import React from 'react'
import ReactDOM from 'react-dom'
import { QueryClient, QueryClientProvider } from 'react-query'
import { ReactQueryDevtools } from 'react-query/devtools'
import App from './App'
const queryClient = new QueryClient()
const isDevelopmentEnv = process.env.NODE_ENV === 'development'
if (isDevelopmentEnv) {
import('./config/msw/worker').then(({ worker }) => worker.start())
}
ReactDOM.render(
<React.StrictMode>
<QueryClientProvider contextSharing={true} client={queryClient}>
<App />
{isDevelopmentEnv && <ReactQueryDevtools initialIsOpen={false} />}
</QueryClientProvider>
</React.StrictMode>,
document.getElementById('root')
)
But, how do I solved that. Well, it was was simple. I couldn't even imagine why it was working locally. But not after building and integration.
The problem was because I put the React Query Provider inside the index o the application and in my single-spa-index.cf.js
I was importing import App from '../App'
which really wasn't wrapped by the provider. Once I also was importing App in the application index, where It was wrapped making It works locally.
So after figure that out, my code was like that:
CODE AFTER SOLUTION
// craco.config.js
const singleSpaApplicationPlugin = require('craco-plugin-single-spa-application')
module.exports = {
plugins: [
{
plugin: singleSpaApplicationPlugin,
options: {
orgName: 'uh-platform',
projectName: 'hosting',
entry: 'src/config/single-spa-index.cf.js',
orgPackagesAsExternal: false,
reactPackagesAsExternal: true,
externals: [],
minimize: false
}
}
]
}
// src/config/single-spa-index.cf.js
import React from 'react'
import ReactDOM from 'react-dom'
import singleSpaReact from 'single-spa-react'
import App from '../App'
const lifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: App,
errorBoundary() {
return <div>Ocorreu um erro desconhecido!</div>
}
})
export const { bootstrap, mount, unmount } = lifecycles
// App.tsx
import { QueryClient, QueryClientProvider } from 'react-query'
import { ReactQueryDevtools } from 'react-query/devtools'
import { config } from 'config/react-query'
import Routes from 'routes'
import GlobalStyles from 'styles/global'
import * as S from './styles/shared'
const queryClient = new QueryClient(config)
const isDevelopmentEnv = process.env.NODE_ENV === 'development'
if (isDevelopmentEnv) {
import('./config/msw/worker').then(({ worker }) => worker.start())
}
function App() {
return (
<QueryClientProvider contextSharing={true} client={queryClient}>
<S.PanelWrapper>
<Routes />
<GlobalStyles />
</S.PanelWrapper>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
)
}
export default App
// index.tsx
import { StrictMode } from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(
<StrictMode>
<App />
</StrictMode>,
document.getElementById('root')
)
Well, it was long but I hope it helps someone that's undergoing for the same problem as mine.