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,
}
]
}
// …
};
Related
I have React project created without cra. I need to add code coverage for cypress e2e tests.
In app created with cra I do the following instructions for add code coverage. And add this line of code in package.json
"start": "react-scripts -r #cypress/instrument-cra start",
This work's well with cra.
But in app without cra I can't add react-scripts or #cypress/instrument-cra for get code coverage information.
How to realize this?
My current configuration ->
babel.config.json
{
"presets": [
"#babel/preset-env",
[
"#babel/preset-react",
{
"runtime": "automatic"
}
],
"#babel/preset-typescript"
],
"plugins": [
"istanbul",
"transform-class-properties",
[
"#babel/plugin-transform-runtime",
{
"useESModules": true,
"regenerator": false
}
]
],
"env": {
"development": {
"plugins": ["istanbul", "transform-class-properties"]
},
"test": {
"presets": [
["#babel/preset-env", {
"targets": "current node"
}]
]
}
}
}
e2e.ts
// Import commands.js using ES2015 syntax:
import "#cypress/code-coverage/support";
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
Cypress.on('uncaught:exception', () => {
/**
* Returning false here prevents Cypress from
* failing the test when one of requests fails
*/
return false
});
package.json
"scripts": {
"start": "webpack-cli serve --port 9007 --env currentEnv=local",
"build": "webpack --mode production",
"serve": "serve dist -p xxxx",
"clean": "rm -rf dist",
"test": "cross-env BABEL_ENV=test jest",
"cy:open": "cypress open",
"cy:run": "cypress run",
"pretest:e2e:run": "npm run build",
"test:e2e:run": "start-server-and-test start http://localhost:9000 cy:run",
"test:e2e:dev": "start-server-and-test start http://localhost:9000 cy:open",
"watch-tests": "cross-env BABEL_ENV=test jest --watch",
"check:coverage": "nyc report --reporter=text-summary --check-coverage",
"prepare": "husky install"
},
// ...
"nyc": {
"all": true,
"excludeAfterRemap": true,
"check-coverage": true,
"extension": [
".tsx"
],
"include": [
"src/views/**/*.tsx"
]
}
cypress.config.ts
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here,
require("#cypress/code-coverage/task")(on, config);
// include any other plugin code...
// It's IMPORTANT to return the config object
// with any changed environment variables
return config;
},
video: false,
baseUrl: "http://localhost:3000/",
},
});
Currently, in browser after each test does finished I get the following error
Could not find any coverage information in your application by looking at the window coverage object. Did you forget to instrument your application? See code-coverage#instrument-your-application [#cypress/code-coverage]
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.
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
]
};
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".