When using create-react-app with react-scripts-ts to use TypeScript, running the tests with the --coverage flag leads to incorrect coverage reports. Is there any way to integrate ts-jest so that the coverage reports will be accurate?
Below is my jest configuration in package.json:
"jest": {
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
],
"mapCoverage": true,
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 100,
"lines": 100,
"statements": 100
}
}
}
}
Edit: This is the error message I am getting:
Out of the box, Create React App only supports overriding these Jest options:
• collectCoverageFrom
• coverageReporters
• coverageThreshold
• snapshotSerializers.
These options in your package.json Jest configuration are not currently supported by Create React App:
• transform
• testRegex
• moduleFileExtensions
• mapCoverage
If you wish to override other Jest options, you need to eject from the default setup. You can do so by running npm run eject but remember that this is a one-way operation. You may also file an issue with Create React App to discuss supporting more options out of the box.
Is there any reason you are using react-scripts-ts/ts-jest instead of regular out-of-the-box Create React App? It has been supporting TypeScript natively for a while now. I'd suggest doing that, as fighting against in the defaults of CRA is generally a pain point.
Related
I am new to Next and React. I have a use case where we have a nextJs application that uses react-native and react-native-web, let's call it A. A is intended to be used either for web and native through different build entry. I have another React app, call it B, that provides a web component to be used by A. Now I can build A and B successfully, but when I start A in web, I got
Module not found: Can't resolve '<B>'.
My IDE can't link this either. When I command click the import, it says nodule not installed even though I did.
I've checked that B's build artifacts do exist in A's node_module, and everything is referenced correctly in package-lock.json. Previously we were using react-native-builder-bob (link) to build B and it was working fine. But react-native-builder-bob is meant for React Native applications and we would like to have better control of the building behavior in the future. My guess is that there is probably some issue with transpiling B that Next is not picking up the dependency.
Here is my .babelrc in B:
{
"presets": [
"#babel/preset-env",
"#babel/preset-typescript",
"#babel/react"
],
"plugins": [
"#babel/plugin-proposal-class-properties"
]
}
.bablerc in A:
{
"env": {
"next": {
"presets": ["next/babel"],
"plugins": [["react-native-web", { "commonjs": true }]]
}
},
"presets": ["module:metro-react-native-babel-preset"]
}
I think I've got the same babel configuration that react-native-builder-bob is using. Is there anything I am missing?
Checked node_module folder that build artifacts exist.
Everything is correctly referenced.
Works fine with bob build
The react-native-builder-bob configuration is:
"react-native-builder-bob": {
"source": "src",
"output": "lib",
"targets": [
"commonjs",
"module",
[
"typescript",
{
"project": "tsconfig.json"
}
]
]
},
How should I change the configs to make it work?
I'm using "vite": "^2.8.6" for React project. What I know is that Vite is using Rollup as module bundler, but I stumbled on a problem where Rollup still bundling my react-dom.development.js and react.development.js. I've used "rollup-plugin-replace" to replace my 'process.env.NODE_ENV' to production, but the problem still occur. Here is the my rollup config:
rollupOptions: {
// https://reactjs.org/docs/optimizing-performance.html#rollup
plugins: [
rollupPluginReplace({
'process.env.NODE_ENV': JSON.stringify('production')
}),
rollupPluginCommonjs(),
terser(),
visualizer()
],
},
When I analyze with rollup-visualizer, you can see that rollup bundled both production and development dependency, which supposedly only bundled one of them right?
The problem with this is that there is extra 1MB of dead code in the bundle, it will be great if I can eliminate it.
This generally means that rollup does not understand that your app is directed towards production code. In my case it was because I had set up library mode.
lib: {
entry: './src/app.ts',
fileName: 'app.ts',
name: 'AppClass',
formats: ['iife'],
}
Removing this block finally generated a build which was sane in size. For more information, see the vite documentation.
If you were also trying to get vite/rollup to build your app as an IIFE, setting rollupOptions worked for me:
rollupOptions: {
output: {
entryFileNames: `[name].js`,
assetFileNames: `app.[ext]`,
format: 'iife',
},
input: ['./src/app.ts'],
},
For an RN app.
I have a project structure like
root git repo
|-jest.config
|-package.json
|-screens/
|--git submodule
|--git submodule
|--.lintstagedrc
one repo at root with package.json and jest.config
and multiple git submodules in screens folder
Each submodule is a npm package which is symlinked in node modules and added in package.json pointing to the git branch.
Now what i wanted to do was add a precommit hook in each submodule and use the root configurations for jest to run when anything is committed in the submodule.
I am using husky and have defined a .lintstagedrc file in the screens folder which would be picked while running husky.
{
"./**/app/**/*.{js,jsx,ts,tsx}": [
"eslint --fix --ext .js,.jsx,.ts,.tsx --plugin tsc --rule 'tsc/config: [2, {configFile: \"../../../tsconfig.json\"}]'",
"jest --config ../../../jest.config.js --bail --forceExit --passWithNoTests --findRelatedTests"
]
}
i am trying to set the jest config using the args however when the commit hook runs it does not pick the config and gives a type error for RN polyfill files
Syntax Error node_modules/#react-native/polyfills/error-guard.js: Missing semicolon. (14:4)
> 14 | type ErrorHandler = (error: mixed, isFatal: boolean) => void;
The same runs correctly if the files are not part of submodule and directly in the root repo(while being at the same path)
when running npx jest --showConfig it is correctly showing the required jest config. but running jest always fails.
How do i get jest to pick the current config and assume the root folder for config is the root repo and not the submodule npm package as i suggest having a package.json defined in submodule might be causing issues
Or that given the submodule is symlinked to node_modules folder at root might be the issue.
Jest config(payments is an example submodule)
module.exports = {
// The preset is a node environment that mimics the environment of a React Native app. Because it doesn't load any DOM or browser APIs, it greatly improves Jest's startup time.
verbose: true,
preset: 'react-native',
// It helps you greatly improve the test speed.It does so by creating a cache of compiled modules so that it doesn't have to compile the node_modules every time we run tests.
cacheDirectory: './cache',
// Defines the files which we want to skip while generating coverage reports.
// coveragePathIgnorePatterns: ['./src'],
// Defines the threshold limit for all the tests to pass.If the coverage is less than the defined limit, the tests would fail.This helped us in keeping code coverage high throughout development.
coverageThreshold: {
global: {
// global thresholds
branches: 23,
functions: 25,
lines: 32,
statements: 32,
},
},
globals: {
'ts-jest': {
diagnostics: false,
},
},
collectCoverageFrom: [
'./src/**/*.js',
'./src/**/*.ts',
'./src/**/*.tsx',
'!**/node_modules/**',
'!**/vendor/**',
],
testPathIgnorePatterns: ['src/.+((?:.ignored)|(?:mock)).(ts|js)x?'],
transform: {
'^.+\\.(ts|tsx|js|jsx)$': 'babel-jest',
},
// All the npm modules which need to be transpiled are added here.These modules are basically ES6/ 7 modules.
transformIgnorePatterns: [
'/node_modules/(?!(jest-)?#?react-native|payments|react-clone-referenced-element|react-navigation|#react-native-community|rn-range-slider|victory|react-native-svg|recoil)',
],
setupFilesAfterEnv: [
'<rootDir>/src/tests/setupTests.js',
'<rootDir>/node_modules/react-native-gesture-handler/jestSetup.js',
'#testing-library/jest-native/extend-expect',
],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
moduleNameMapper: {
'\\.svg': '<rootDir>/src/tests/mocks/svgMock.js',
'^src/(.*)': '<rootDir>/src/$1',
'^config/(.*)': '<rootDir>/config/$1',
'^app/(.*)': '<rootDir>/app/$1',
'^setup/(.*)': '<rootDir>/setup/$1',
'^payments/(.*)': '<rootDir>/src/screens/payments/$1',
},
notify: true,
notifyMode: 'always',
};
I use #testing-library/react-native to test my RN app. When I run yarn test, following error occurs.
#testing-library/react-native should have "jest-preset.js" or "jest-preset.json" file at the root.
I use typescript for my app.
my test script is like this.
test": "jest --config jest.config.json"
jest.config.json file is like this.
{
"preset": "#testing-library/react-native",
"collectCoverageFrom": ["src/**/*.{ts,tsx}"],
"moduleDirectories": ["node_modules", "src"],
"setupFiles": [
"<rootDir>/jestSetup/setup.js",
"./node_modules/react-native-gesture-handler/jestSetup.js"
],
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?(react-native|#?react-navigation|#react-native-community))"
],
"coveragePathIgnorePatterns": ["/node_modules/", "/jestSetup", "/src/config.ts", "/src/app.tsx"]
}
Why am I getting this error?
I'm using expo and after updates from 38 to 39, Jest stopped working. I had same issues — it was complaining about missing preset js files.
Preset below didn't work for me:
"preset": "#testing-library/react-native",
So I have changed jest.config.js like this:
module.exports = {
clearMocks: true,
coverageDirectory: 'coverage',
testEnvironment: 'node',
preset: './node_modules/jest-expo/jest-preset.js',
}
Changed preset file location to expo's one which im using and it did the work
The preset no longer exists in >=7.0.0 "#testing-library/react-native". According to the documentation it seems "react-native" should be used as the preset.
"preset": "react-native",
V7 upgrade documentation reference
For those seeing this in a fully up to date project, the missing file is [./node_modules/]react-native/jest-preset.js and you need to make sure that react-native itself is installed.
This will happen if you don't have react-native install globally.
yarn add react-native (or do it globally)
so in package.json you should see something like:
"react-native": "0.66.3",
trying to setup jest to work with css decorators.
The css file linked to my react component has:
#import './another.css'
Now, when I run jest I get:
SyntaxError: /Users/thiagofacchini/Documents/atomix/src/library/atoms/Label/styles.css: Support for the experimental syntax 'decorators-legacy' isn't currently enabled (2:1):
Then I went to my .babelrc and added:
"env": {
"test": {
"plugins": [
"#babel/plugin-proposal-decorators", { "legacy": true },
]
}
Running jest again I get
[BABEL] /Users/thiagofacchini/Documents/atomix/src/library/protons/Animator/tests/index.test.js: The decorators plugin requires a 'decoratorsBeforeExport' option, whose value must be a boolean. If you want to use the legacy decorators semantics, you can set the 'legacy: true' option.
(While
processing:/Users/thiagofacchini/Documents/atomix/node_modules/#babel/plugin-proposal-decorators/lib/index.js")
Also tried to change my .babelrc to:
"env": {
"test": {
"plugins": [
"#babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true ,"legacy": true },
]
}
}
But get exactly the same error.
My package.json looks like:
"#babel/core": "^7.3.4",
"#babel/plugin-proposal-decorators": "^7.3.0",
"#babel/preset-env": "^7.3.4",
"#babel/preset-flow": "^7.0.0",
"#babel/preset-react": "^7.0.0",
"#logux/eslint-config": "^27.0.0",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.5",
NOTE: The error is just happening on JEST, my development build works fine.
I googled the hell but I simply cannot understand what's going on. Maybe something with versions? I'd appreciate any help.
When you run your app in development build the build process is taken care of by webpack/parcel/whichever tool you're using.
These tools allow you to (via the use of plugins) do thing like import css into javascript and then eventually spit it back out as css at the appropriate time. This is not a native feature of javascript.
Jest runs on node js which doesn't have all of the features of webpack and cannot parse raw css etc.
So when you had the error "SyntaxError: /Users/thiagofacchini/Documents/atomix/src/library/atoms/Label/styles.css: Support for the experimental syntax 'decorators-legacy' isn't currently enabled (2:1):"
this is actually nodejs trying to parse the css as javascript! You can read more about what it though you were doing here https://www.sitepoint.com/javascript-decorators-what-they-are/
So how do you manage css in your jest environment?
in your jest configuration you set it up so that you don't import the css and instead you import a blank module.
first npm install identity-obj-proxy
then add the following to your jest.config.js
moduleNameMapper: {
"\\.css$": "identity-obj-proxy",
"^lodash-es$": "lodash"
},