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:
- Updating all my packages to their latests versions in a branch
- Updating to the latest version of node
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-locationpackage isn't published correctly.When you investigate the
package.jsonfor the installedreact-locationpackage, you find this:The
mainentry 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, useAnd in your import, use