DEV Community

How To Set Up ESLint, TypeScript, Prettier with Create React App

Ben Weiser on April 05, 2019

Note: CRA 3.0 will include TS linting with ESLint out of the box, https://github.com/facebook/create-react-app/issues/6475 I recently learned that...
Collapse
 
jaffparker profile image
Jaff Parker

Hey, how did you deal with the instance of ESLint that's built into CRA?

I've tried what you've done here previously, but CRA was detecting a "conflicting" version of ESLint and crashing. In fact, not so long ago, the CRA team mentioned it explicitly, that there's no way to set up a custom ESLint config yet. Has that been fixed or have you found a different approach?

Collapse
 
seefer profile image
Darren Evans • Edited

I always had problems when a Eslint + Prettier tutorial tells you to add the eslint package along with the prettier stuff in a Create React App (CRA) project. Doing this lately tends to install Eslint 7 and all kinds of errors crop up due to a version conflict with the eslint used internally by the CRA scripts (version 6.6.0 I believe). This is why Ben's tutorial works, it simply gets the Prettier and Prettier packages up and running to work with the version of eslint that CRA and the CRA scripts use out of the box.

I suspect if one really wants the latest Eslint installed, you'd have to run the eject script and then dive in to the CRA config files to change out the eslint versions.

Collapse
 
jaffparker profile image
Jaff Parker

I read things more carefully and realized I misunderstood what exactly CRA was complaining about. It didn't like the fact that I installed a different version of ESLint, but once I swapped it for CRA's version, it was fine.

However, I noticed that you don't install ESLint in this article at all? How are you calling it in your scripts then? Is it installed globally?

Collapse
 
benweiser profile image
Ben Weiser

You get ESLint for free when you install CRA so there's no need to install it in your package.json. I have experienced the same warning you're describing here when attempting to install my own version of ESLint. I uninstalled ESLint in my package.json and everything seems to be running as expected. I'm not sure regarding the restriction of ESLint configs, I have always been able to successfully set up lint configs though in the past opted for TSLint

Thread Thread
 
benweiser profile image
Ben Weiser

It's worth nothing that this configuration was tested with the following versions of react/react-dom and react scripts

    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-scripts": "2.1.8"
Thread Thread
 
jaffparker profile image
Jaff Parker

It could work to just keep using ESLint installed through CRA, but the VSCode ESLint extension doesn't seem to pick it up, of it's not listed among your dependencies. Plus, I don't think it's a good practice to reference a dependency in your code that you don't install manually... But can work for sure.

Thread Thread
 
benweiser profile image
Ben Weiser

I agree, there should be some concern over this if a dependency higher up in the tree you don't have control over happens to change than dependent libraries downline could potentially cause issues. This is also the case when using any libraries that depend on Jest as well which also comes prepackaged with CRA. Given that these libraries are the new standard for TS linting with ESLint with full community support my hope is that there will be reasonable support for the latest versions of ESLint. I will mention up above as well this will be solved with CRA 3.0 that will include these libraries OOTB.

Collapse
 
ackvf profile image
Vítězslav Ackermann Ferko

Thanks to your guide I was able to fix the CRA's own eslint that was failing on as with Parsing error: Unexpected token, expected "," by adding theses lines to package.json.

{
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^1.6.0",
    "@typescript-eslint/parser": "^1.6.0",
    "eslint-config-react": "^1.1.7"
  },
  "eslintConfig": {
    "parser": "@typescript-eslint/parser",
    "plugins": ["react", "@typescript-eslint"],
    "extends": ["react-app"],
    "rules": {
      // custom rules here
    }
  }
}
Collapse
 
ackvf profile image
Vítězslav Ackermann Ferko

Why are you using your own eslint related files instead of the eslintConfig that is already present in package.json? Did you remove the config from package.json or do you keep it there, having two eslint configurations? Is your solution still using CRA's internal mechanisms or is it something completely custom?

Collapse
 
benweiser profile image
Ben Weiser • Edited

I'm not using an eslintConfig in my package.json. Using the .eslintrc.json is the only place I have added any configurations. This is just my preference, eslintConfig in package.json is also a valid approach. It just depends on how you like to structure your project

Collapse
 
gruckion profile image
Stephen Rayner • Edited

Before running "npm start" ensure you "npm installl typescript --save-dev".

Eslint doesn't work for me. The lint command fails with.

> eslint './src/**/*.{ts,tsx}'


Oops! Something went wrong! :(

ESLint: 5.16.0.
No files matching the pattern "'./src/**/*.{ts,tsx}'" were found.
Please check for typing mistakes in the pattern.
Enter fullscreen mode Exit fullscreen mode

Both my .eslintignore and .eslintrc.json are identical copy and paste. I used "npx create-react-app eslint-integration-typescript-example"


{
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended",
        "prettier/@typescript-eslint",
        "plugin:prettier/recommended"
    ],
    "plugins": [
        "react",
        "@typescript-eslint",
        "prettier"
    ],
    "env": {
        "browser": true,
        "jasmine": true,
        "jest": true
    },
    "rules": {
        "prettier/prettier": [
            "error",
            {
                "singleQuote": true
            }
        ]
    },
    "settings": {
        "react": {
            "pragma": "React",
            "version": "detect"
        }
    },
    "parser": "@typescript-eslint/parser"
}
Enter fullscreen mode Exit fullscreen mode
{
  "name": "tslint-integration-example",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-scripts": "3.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "lint": "eslint './src/**/*.{ts,tsx}'"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@types/react": "^16.8.18",
    "@typescript-eslint/eslint-plugin": "^1.9.0",
    "@typescript-eslint/parser": "^1.9.0",
    "eslint-config-prettier": "^4.3.0",
    "eslint-config-react": "^1.1.7",
    "eslint-plugin-prettier": "^3.1.0",
    "prettier": "^1.17.1",
    "typescript": "^3.4.5"
  }
}
Enter fullscreen mode Exit fullscreen mode
src/registerServiceWorker.js
src/**/__tests__/**
Enter fullscreen mode Exit fullscreen mode
$ create-react-app --version
3.0.1
Enter fullscreen mode Exit fullscreen mode

I can see that the file does have linting suggestions in the UI. But "npm run lint" doesn't work

Would really appreciate some guidance. This is the third guide I've tried to follow, each time with a fresh "CRA"

  1. dev.to/robertcoopercode/using-esli...
  2. javascriptplayground.com/typescrip...

It works fine with standard javascript and I managed to get that to work as shown in this repo github.com/gruckion/eslint-integra... EDIT < doesn't work here either

The currently broken repo is here, github.com/gruckion/eslint-integra....

Collapse
 
gruckion profile image
Stephen Rayner

If you are having the same issue I was the cause is;

"lint": "eslint './src/**/*.{ts,tsx}'",
Enter fullscreen mode Exit fullscreen mode

In order to get this to work, I had to remove the single quotes.

I am not sure why the single quote approach doesn't work for me. I read over the documentation and found it is called "glob" notation and it depends on the console your using (I am using git bash).

Placing your glob in double quotes will use nodes glob format. If you want to test it and don't want to globally install eslint use;

npx eslint './src/**/*.{ts,tsx}'

This works fine for me. with and without double or single quotes.

eslint.org/docs/user-guide/command...

If anyone has any idea why I can't run the script from my package.json with single quotes I would love to know.

Collapse
 
simorocksthebest profile image
simorocksTheBest

It's an oddity of the operating system, I bet you were working with a windows 10 machine.

I got the exact same error, this is what I did.

lint: "eslint \"./src/*/.{ts,tsx}\""

stackoverflow.com/questions/481043...

Thread Thread
 
oh_jeez_rick profile image
Gavin Chan

thank you. It works in Win10 Pro now.

Collapse
 
kushalmahajan profile image
Kushal V. Mahajan

I can't get the prettier to run for some rules. One of them is "jsx-max-props-per-line".

This is how I specified -

"rules": {
        "prettier/prettier": [
            "error",
            {
                "singleQuote": true,
                "jsx-max-props-per-line": [
                    1,
                    {
                        "maximum": "1",
                        "when": "always"
                    }
                ]
            }
        ],
        "react/jsx-max-props-per-line": [
            1,
            {
                "maximum": "1",
                "when": "always"
            }
        ]
    },

Tried almost every permutation and combination. Please note that I only have eslint plugin on vscode enabled. No other linters are present in editor. Can someone please help!

Collapse
 
malipramod profile image
Pramod Mali • Edited

This is due to 'printWidth' property in the .prettierrc configuration file. By default, it's 120. For me, 80 works great and shows props in a new line.

module.exports = {
semi: true,
trailingComma: "all",
singleQuote: true,
printWidth: 80,
tabWidth: 4
}

prettier.io/docs/en/options.html#p...

Collapse
 
pietrojs profile image
pietro the wizard

I have the same problem. Have you found a solution?

Collapse
 
bmmpt profile image
Bruno Mendonca • Edited

Hey Ben,

Thanks for putting this post together.

Something didn't really work for me or I expected something it was not supposed to offer.

I have a similar configuration to what you are suggesting and if I run npx eslint src/App.tsx, I get:

6:9 error 'chaire' is assigned a value but never used @typescript-eslint/no-unused-vars

Notice that it is an "error". When I run npm start, react-script kicks in and as the app is starting I get (in my command line window):

Compiled with warnings.

./src/App.tsx
Line 6: 'chaire' is assigned a value but never used @typescript-eslint/no-unused-vars

Note that it is a warning and therefore isn't respecting my eslint configuration. And I really want it to be an error!!! :)

Here's my lint config:

module.exports = {
"extends": [
"react-app",
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"prettier/@typescript-eslint",
"plugin:prettier/recommended"
],
"plugins": [
"react",
"@typescript-eslint",
"prettier"
],
"env": {
"browser": true,
"jasmine": true,
"jest": true
},
"rules": {
"prettier/prettier": [
"error", {
"singleQuote": true,
"tabWidth": 4
}
],
"@typescript-eslint/no-unused-vars": ["error", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": false
}]
},
"settings": {
"react": {
"pragma": "React",
"version": "detect"
}
},
"parser": "@typescript-eslint/parser"
}

Regards,
Bruno

Collapse
 
bmmpt profile image
Bruno Mendonca

I copied the project to another folder, node_modules and all (no changes). Turns out now I get an error when react-scripts start runs:

TypeScript error in C:/BitB/auth-ui/src/App.tsx(6,11):
'chaire' is declared but its value is never read. TS6133

Looks like a typescript error and not a lint error, but I'll take it :)

However, I tried with a less problematic rule "semi": "error" and in my code import './App.css' without semicolon.

npx eslint src/App.tsx shows:

25:2 error Missing semicolon semi

But react-scripts start doesn't care about it.

Any help would be appreciated.

Collapse
 
murbanowicz profile image
Marek

Hi!
I believe there is an error with lint:fix command.
It is not the fix :) It should look like this:

"lint:fix": "eslint --fix './src/**/*.{ts,tsx}'"