I am using create-react-app without ejecting. Tests were working all fine until my PRs starting failing with npm ERR! npm ci can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with npm install before continuing.
After fixing that, the site runs fine, but I have this error in my tests when running both locally and on my CI:
● Test suite failed to run
Cannot find module 'react-location' from 'src/_shared/testUtils/renderComponent.js'
...
at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:324:11)
at Object.<anonymous> (src/_shared/testUtils/renderComponent.js:6:1)
That's just an example, it happens everywhere that react-location is used in the app.
After digging into resolver.js, I narrowed it down to this:
Cannot find module 'react-location' from '/Users/[username]/projects/[projectname]/src/_shared/testUtils'
at resolveSync (/Users/[username]/projects/[projectname]/node_modules/resolve/lib/sync.js:111:15)
Couldn't work out what's going on deeper than that.
Since I'm using CRA my jest config is very minimal, it's just this:
"jest": {
"globalSetup": "./src/_shared/testUtils/timezone.js"
}
I have tried:
But still the same error. My package.json after updating to latest versions:
"dependencies": {
"@chakra-ui/react": "^2.2.1",
"@emotion/react": "^11.9.3",
"@emotion/styled": "^11.9.3",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^14.2.1",
"apexcharts": "^3.35.3",
"axios": "^0.27.2",
"base-64": "^1.0.0",
"crypto-js": "^4.1.1",
"date-fns": "^2.28.0",
"env-cmd": "^10.1.0",
"formik": "^2.2.9",
"framer-motion": "^6.3.11",
"react": "^18.2.0",
"react-apexcharts": "^1.4.0",
"react-dom": "^18.2.0",
"react-location": "^3.3.4",
"react-location-devtools": "^3.3.4",
"react-query": "^3.39.1",
"react-scripts": "5.0.1",
"react-spinners": "^0.12.0",
"react-use": "^17.4.0",
"react-world-flags": "^1.5.0",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"@chakra-ui/storybook-addon": "^4.0.1",
"@mdx-js/react": "^1.6.22",
"@storybook/addon-a11y": "^6.5.9",
"@storybook/addon-actions": "^6.5.9",
"@storybook/addon-docs": "^6.5.9",
"@storybook/addon-essentials": "^6.5.9",
"@storybook/addon-links": "^6.5.9",
"@storybook/builder-webpack5": "^6.5.9",
"@storybook/manager-webpack5": "^6.5.9",
"@storybook/node-logger": "^6.5.9",
"@storybook/preset-create-react-app": "^4.1.2",
"@storybook/react": "^6.5.9",
"eslint": "^8.17.0",
"husky": "^8.0.1",
"lint-staged": "^13.0.2",
"msw": "^0.42.1",
"prettier": "2.7.1"
},
"overrides": {
"react-refresh": "0.14.0",
"@mdx-js/react": {
"react": "$react"
}
},
Here is the renderComponent
file:
import { render } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ChakraProvider } from '@chakra-ui/react';
import theme from '_shared/designSystem/theme';
import { Router, ReactLocation, createMemoryHistory } from 'react-location';
import { authenticatedRoutes } from 'routes';
// Renders the component wrapped in Chakra and React Query
export const renderComponent = (component) => {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false, staleTime: 2500 }
}
});
const testNode = render(
<QueryClientProvider client={queryClient}>
<ChakraProvider resetCSS={false} theme={theme}>
{component}
</ChakraProvider>
</QueryClientProvider>
);
return { testNode };
};
// Renders the whole app at a specific route if given
export const renderComponentWithRoute = (component, route) => {
const history = createMemoryHistory({ initialEntries: [route] });
const location = new ReactLocation({ history });
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false, staleTime: 2500 }
}
});
const testNode = render(
<QueryClientProvider client={queryClient}>
<ChakraProvider resetCSS={false} theme={theme}>
<Router location={location} routes={authenticatedRoutes}>
{component}
</Router>
</ChakraProvider>
</QueryClientProvider>
);
return { testNode };
};
The non-scoped variant of the react-location
package isn't published correctly.
When you investigate the package.json
for the installed react-location
package, you find this:
"main": "build/cjs/index.js",
The main
entry points to module location that doesn't exist within the package. That's why there is an error about the module not being found.
I recommend switching to the scoped version.
In your package.json
, use
"@tanstack/react-location": "^3.3.4",
And in your import, use
import { Router, ReactLocation, createMemoryHistory } from '@tanstack/react-location';