I'm developing a React app with a QR-scanner in it with create-react-app.
I've added the module react-qr-reader which in turn uses the modules webrtc-adapter.
It all works great, until I run yarn test. Then it shows me this error:
I've already ejected the project so I can use transformIgnorePatterns and added node_modules/webrtc-adapter to the array, but that still results in the same error.
Can anyone help me with this?
If you don't want to eject from Create-React-App you can use the CLI in your package.json to override 'transformIgnorePatterns'.
Reference - https://github.com/facebook/create-react-app/issues/2537#issuecomment-390341713
"scripts": {
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!your-module-name)/\"",
},
It's because of de ES6 syntax in a package into node_modules, you need to config the "transformIgnorePatterns" to transform this package.
The issue on Jest: https://github.com/facebook/jest/issues/2081
How to configure: http://facebook.github.io/jest/docs/tutorial-react-native.html#transformignorepatterns-customization
"transformIgnorePatterns": [
"node_modules/(?!(react-qr-reader)/)"
]
if this doesn't work, use the babel.config.js with this configuration (is important the file ".js", this configuration don't work in ".babelrc" file):
module.exports = {
presets: [
[
"#babel/preset-env",
{
"modules": "commonjs",
"debug": false
}
],
/// your presets
],
plugins: [
//... your plugins
]
};
Related
If I use import/export from ES6 then all my Jest tests fail with error:
Unexpected reserved word
I convert my object under test to use old school IIFE syntax and suddenly my tests pass. Or, take an even simpler test case:
var Validation = require('../src/components/validation/validation'); // PASS
//import * as Validation from '../src/components/validation/validation' // FAIL
Same error. Obviously there's a problem with import/export here. It's not practical for me to rewrite my code using ES5 syntax just to make my test framework happy.
I have babel-jest. I tried various suggestions from GitHub issues. It is no go so far.
File package.json
"scripts": {
"start": "webpack-dev-server",
"test": "jest"
},
"jest": {
"testPathDirs": [
"__tests__"
],
"testPathIgnorePatterns": [
"/node_modules/"
],
"testFileExtensions": ["es6", "js"],
"moduleFileExtensions": ["js", "json", "es6"]
},
File babelrc
{
"presets": ["es2015", "react"],
"plugins": ["transform-decorators-legacy"]
}
Is there a fix for this?
From my answer to another question, this can be simpler:
The only requirement is to configure your test environment to Babel, and add the ECMAScript 6 transform plugin:
Step 1:
Add your test environment to .babelrc in the root of your project:
{
"env": {
"test": {
"plugins": ["#babel/plugin-transform-modules-commonjs"]
}
}
}
Step 2:
Install the ECMAScript 6 transform plugin:
npm install --save-dev #babel/plugin-transform-modules-commonjs
And that's it. Jest will enable compilation from ECMAScript modules to CommonJS automatically, without having to inform additional options to your jest property inside package.json.
UPDATE 2020 - native support of ECMAScript modules (ESM)
According to this issue, there is native support of ESM from jest#25.4.0. So you won't have to use babel anymore. At the time of writing this answer (05/2020), to activate that you need to do three simple things:
Make sure you don't transform away import statements by setting transform: {} in config file
Run node#^12.16.0 || >=13.2.0 with --experimental-vm-modules flag
Run your test with jest-environment-node or jest-environment-jsdom-sixteen.
So your Jest configuration file should contain at least this:
export default {
testEnvironment: 'jest-environment-node',
transform: {}
...
};
And to set --experimental-vm-modules flag, you will have to run Jest as follows:
node --experimental-vm-modules node_modules/jest/bin/jest.js
Also note in the Github issue that this approach does not yet support the jest object. So you may need to import it manually:
import {jest} from '#jest/globals'
(I hope this will change in the future)
For an updated configuration, I'm using https://babeljs.io/setup#installation
Select JEST and be happy:
As a reference, the current configuration:
npm install --save-dev babel-jest
In your package.json file, make the following changes:
{
"scripts": {
"test": "jest"
},
"jest": {
"transform": {
"^.+\\.jsx?$": "babel-jest"
}
}
}
Install babel preset:
npm install #babel/preset-env --save-dev
Create a .babelrc file:
{
"presets": ["#babel/preset-env"]
}
Run your tests:
npm run test
In package.json, kindly set like this one: "test": "node --experimental-vm-modules node_modules/.bin/jest"
Should be good!
It's a matter of adding stage-0 to your .babelrc file. Here is an example:
{
"presets": ["es2015", "react", "stage-0"],
"plugins": ["transform-decorators-legacy"]
}
I encountered the same issue.
These are what I did:
yarn add --dev babel-jest #babel/core #babel/preset-env
Make file jest.config.js in rootDir.
module.exports = {
moduleFileExtensions: ["js", "json", "jsx", "ts", "tsx", "json"],
transform: {
'^.+\\.(js|jsx)?$': 'babel-jest'
},
testEnvironment: 'node',
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/$1'
},
testMatch: [
'<rootDir>/**/*.test.(js|jsx|ts|tsx)', '<rootDir>/(tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))'
],
transformIgnorePatterns: ['<rootDir>/node_modules/']
};
Then make file babal.config.js in rootDir.
Go like this:
module.exports = {
"presets": ["#babel/preset-env"]
}
Below is how I setup jest, typescript and ES Modules for my project.
jest.config.js
/**
* #type {import('ts-jest/dist/types').InitialOptionsTsJest}
* To configure ESM support, see: https://kulshekhar.github.io/ts-jest/docs/guides/esm-support
*
**/
export default {
preset: 'ts-jest/presets/default-esm',
testEnvironment: 'node',
extensionsToTreatAsEsm: ['.ts'],
globals: {
'ts-jest': {
useESM: true
}
},
setupFiles: ['<rootDir>/__tests__/setup.ts'],
};
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"outDir": "./dist",
"moduleResolution": "node",
// "strict": true,
"esModuleInterop": true,
"inlineSourceMap": true,
}
}
package.json scripts and devDependencies
"scripts": {
"start": "node ./dist/server.js",
"dev": "tsc-watch --onSuccess \"node ./dist/server.js\"",
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
},
"devDependencies": {
"#jest/globals": "^27.4.4",
"#types/express": "^4.17.13",
"#types/jest": "^27.4.0",
"#types/supertest": "^2.0.11",
"cross-env": "^7.0.3",
"supertest": "^6.2.1",
"ts-jest": "^27.1.3"
}
__tests__/setup.ts
import dotenv from 'dotenv';
dotenv.config({
path: './.env.test'
});
all is explained in the jest docs: jest docs
1.
npm install --save-dev babel-jest #babel/core #babel/preset-env
in file: babel.config.js
module.exports = {
presets: [['#babel/preset-env', {targets: {node: 'current'}}]],
};
In addition to installing babel-jest (which comes with Jest by default now) be sure to install regenerator-runtime.
To add support for React and react-testing-library it may be useful to eject CreateReactApp and take all needed Jest configuration from the package.json. It is ready to use with another bundler, Rollup in my case.
I'm a noob using ReactJS, right now i'm making a Widget using React and i have create different components, i have created the app using npx create-react-app and everithing is working, but now i'm trying to bundle all the components, css and files in a single .js file to be able to install the Widget in a web page.
My code is this:
index.js
App.js
i just saw a couple of posts and blogs that indicates i need to create my own webpack.config.js file and put in something like this:
`
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const glob = require('glob');
module.exports = {
entry: {
"bundle.js": glob.sync("build/static/?(js|css)/main.*.?(js|css)").map(f => path.resolve(__dirname, f)),
},
output: {
filename: "build/static/js/bundle.min.js",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
plugins: [new UglifyJsPlugin()],
}
`
it creates a .js file but when i put the file in a html document is not showing anything
Finally I got it!
By default npx create-react-app create a structure with a lot of configurations, folders and files to make easy start to coding an app with React, one of this configs is setting up webpack to create a "build" directory when we type "npm build" with all the components of our app and allow us to deploy it everywhere, but in my case, I just needed to distribute a .js file with the widget that I am creating, this .js file could be placed inside of a in any HTML page and the widget will work apart, independent of the page, to make this I followed these steps:
First, I need to change in the "package.json" file the "scripts" section, to indicate to webpack will make not only the "build" directory, also a bundle.js with all the CSS, images, components.
"scripts": {
"start": "react-scripts start",
"build": "npm run build:react && npm run build:bundle",
"build:react": "react-scripts build",
"build:bundle": "webpack --config webpack.config.js",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
Notice that I have replaced the "bundle" script, indicating that will execute "build:react" and "build:bundle"
As we see, "build:bundle" will take the configuration of "webpack.config.js", in our initial confuguration we dont have this file, because webpack is automatically configured by "npx create-react-app", so, we need to create this file in the root path of our app and create a configuration to tell webpack that needs to bundle everything, my configuration is this:
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
entry: {
entry: './src/index.js',
},
output: {
filename: "build/static/js/WidgetCL.js",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.m?js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env'],
plugins: ['#babel/plugin-transform-runtime']
}
}
}
],
},
plugins: [new UglifyJsPlugin()],
}
I am telling webpack that it needs to take the "index.js" file created automatically by npx as entry point, also webpack will create a WidgetCL.js as output, the interesting part is in the "module" section, after a few hours or issues, I could configure two "Loaders", one for the .css files and the other one for all the .js components in my widget, using Babel as Loader.
To use Babel I needed to create a file named .babelrc in the root path of my project and configure it in this way:
{
"presets": [
"#babel/react" ,
"#babel/env"
],
"plugins": [
"#babel/plugin-proposal-class-properties"
]
}
After this, I just open a terminal and type "npm run build", then webpack creates the "build" folder and also a "dist" folder with my .js file inside.
create-react-app v3.0.0 is out. It supports TypeScript linting internally. (That's nice!) I think I understand the situation where TSLint is on, and am planning to replace it with ESLint, but it is not right now.
How to disable that linting step in react-scripts start?
/* eslint-disable */ and others are not the ones I'm looking for.
As of react-scripts v4.0.2, you can now opt out of ESLint with an environment variable. You can do this by adding it to your .env file, or by prefixing your scripts in your package.json file.
For example in .env:
DISABLE_ESLINT_PLUGIN=true
Or in your package.json:
{
"scripts": {
"start": "DISABLE_ESLINT_PLUGIN=true react-scripts start",
"build": "DISABLE_ESLINT_PLUGIN=true react-scripts build",
"test": "DISABLE_ESLINT_PLUGIN=true react-scripts test"
}
}
https://github.com/facebook/create-react-app/pull/10170
You could set EXTEND_ESLINT environment variable to true, for example in .env file:
EXTEND_ESLINT=true
Now you can extend eslint configuration in your package.json file:
...
"eslintConfig": {
"extends": "react-app",
"rules": {
"jsx-a11y/anchor-is-valid": "off"
}
},
...
To disable eslint you could add a file .eslintignore with the content:
*
See documentation for details: https://create-react-app.dev/docs/setting-up-your-editor/#experimental-extending-the-eslint-config
You can disable eslint (and override other configurations) using Craco.
It takes 4 changes:
npm install #craco/craco --save
create craco.config.js (in the same folder as is package.json)
populate craco.config.js with:
module.exports = {
eslint: {
enable: false,
},
};
Finally, replace react-script with craco in your package.json scripts, i.e.
"scripts": {
"build": "craco build",
"start": "craco start",
}
This will disable ESLint. Refer to Craco documentation for examples how to extend ESLint configuration.
step 1
create .env file in your project root if its not there and add this line to it
EXTEND_ESLINT=true
Step 2
add .eslintrc.js to your project root with following content
module.exports = {
"extends": ["react-app"],
"rules": {
},
"overrides": [
{
"files": ["**/*.js?(x)"],
"rules": {
// ******** add ignore rules here *********
"react/no-unescaped-entities": "off",
"react/display-name": "off",
"react/prop-types": "off",
}
}
]
}
note that override > rules section: add rules with "off" flag to disable them.
My workaround without ejecting:
Use an environment variable in .eslintrc.js like this:
module.exports = {
"extends": process.env.REACT_APP_DEV_DISABLE_ESLINT ? [] : [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:json/recommended",
"plugin:#typescript-eslint/recommended",
"plugin:jsx-a11y/recommended",
"plugin:react/recommended",
],
"rules": process.env.REACT_APP_DEV_DISABLE_ESLINT ? {} : {
// ...rules for production CI
}
}
Set the variable in start script in package.json:
{
"scripts": {
"eslint:disable": "REACT_APP_DEV_DISABLE_ESLINT=true",
"start": "npm run eslint:disable react-scripts start"
}
}
First ensure EXTEND_ESLINT environment variable is set to true. It can be set in .env file.
For Typescript, further rules should be added in overrides array, as example below:
{
"eslintConfig": {
"extends": ["react-app"],
"overrides": [
{
"files": ["**/*.ts?(x)"],
"rules": {
"eqeqeq": "warn"
}
}
]
}
}
My workaround:
Add a .eslintignore file:
*
and run eslint with --no-ignore. So you are able to setup your own eslint. If you need a ignore file you can define it with --ignore-path instead of using the --no-ignore option.
One way is to eject react-scripts - by running yarn eject / npm run eject - and turn off eslint in webpack config file manually.
Beware though that ejecting should not be done lightly and other options should be considered before ejecting. Please read Don’t eject your Create React App to gain some understanding of what it means and perhaps some reason's why you shouldn't
Please take a look at this fork: create-react-app closer look, especially at eject-tic_tac_toe directory, where you have scripts/start.js - the script where the magic happens after yarn start / npm start - and config/webpack.config.dev.js - where you have webpack's config, used in start.js. This is the part you can be interested in to edit:
// …
module.exports = {
// …
module: {
preLoaders: [
{
test: /\.(js|jsx)$/,
loader: 'eslint',
include: paths.appSrc,
}
]
}
// …
};
I would like to keep console.log in developer builds, but in production builds I want them removed.
babel-plugin-transform-remove-console
I cannot remember if I installed it as --save or --save-dev (and not quite sure the difference). I also do not know how to check how it was installed, but it is in my node_modules directory as babel-plugin-transform-remove-console.
Whether I use npm run dev or npm run build to build my project I still see the console.log statements. I would have expected the npm run build command to remove the console.log files.
My .babelrc file looks like this:
{
"presets" : ["env", "stage-0", "react"],
"env" : {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
The pertinent parts of my package.json look like this:
"scripts": {
"dev": "webpack -d --watch",
"build": "webpack -p"
},
...
"dependencies": {
...
"babel-plugin-transform-remove-console": "^6.9.2",
...
}
Why is the npm run build not removing console.log statements for me?
-p is a flag for Webpack itself. Babel doesn't know anything about it. If you want your Webpack config to toggle behavior based on it, you'd need to do that yourself.
// webpack.config.js
module.exports = function(env) {
return {
// ...
module: {
rules: [{
loader: "babel-loader",
options: {
forceEnv: env.production ? "production" : "development"
}
}],
},
},
};
I cannot remember if I installed it as --save or --save-dev (and not quite sure the difference).
Just look at your package.json file.
-- save will make your package appear in dependencies (this is the default behaviour if no option was provided)
-- save-dev will make your package appear in devDependencies
https://docs.npmjs.com/cli/install
When you use run webpack -p, webpack sets process.env.NODE_ENV = "production", but Babel expects process.env.BABEL_ENV = "production".
Update: edited jest config in package.json to include identity-obj-proxy and added transform-es2015-modules-commonjs to .babelrc
Trying to setup jest and enzyme to run unit tests on a React.js project. This configuration setting works fine as long as I'm not requiring a node_module in the target component. But if the component I want to test imports a node_module that itself imports a scss file it throws this error:
import('../../scss/bulkAction.scss');
^^^^^^
SyntaxError: Unexpected token import
This is my jest config file:
"jest": {
"testPathIgnorePatterns": [
"<rootDir>/(node_modules)"
],
"moduleFileExtensions": [
"js",
"jsx"
],
"moduleDirectories": [
"node_modules"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/app/_tests_/config/fileMock.js",
"\\.(css|scss)$": "identity-obj-proxy"
},
"transform": {
"^.+\\.(js|jsx)$": "babel-jest",
"^.+\\.(css|scss)$": "<rootDir>/app/_tests_/config/scssTransform.js",
"^(?!.*\\.(js|jsx|json)$)": "<rootDir>/app/_tests_/config/fileTransform.js"
}
},
this is my .babelrc file
{
"presets": [
["es2015", {"modules": false}], "react", "stage-0"],
"env": {
"start": {
"presets": [
"react-hmre"
]
},
"test": {
"presets": ["es2015", "react", "stage-0"],
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
I've tried multiple different configurations and have been reading the docs for quite awhile and haven't been able to solve this problem. I'm hoping someone can help!
Note about our file structure:
/WebApps/ProjectName/ProjectFolder/app
/WebApps/ProjectName/ProjectFolder/package.json
/WebApps/ProjectName/ProjectFolder/.babelrc
/WebApps/ProjectName/ProjectFolder/node_modules
I add this just incase the file pathing of the may be part of the problem.
You've missed probably transform-es2015-modules-commonjs babel plugin.
Add this to your .babelrc
// .babelrc
{
"presets": [
["es2015", {"modules": false}]
],
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
Remember to install this plugin before using:
babel-plugin-transform-es2015-modules-commonjs --save-dev
When you run your tests with jest, it set the environment as test by default.
In my project I use also identity-obj-proxy, like:
// jest.config.json
{
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy"
},
}
Also, first install it before using:
npm install --save-dev identity-obj-proxy
I highly recommend reading the page from official jest documentation about integration jest with webpack.
https://facebook.github.io/jest/docs/webpack.html#mocking-css-modules
https://facebook.github.io/jest/docs/webpack.html#using-with-webpack-2