DEV Community

Renato Rocha
Renato Rocha

Posted on • Updated on

How to setup a React.JS Project with TypeScript, ESLint and Prettier

During the software development proccess is important keeping the code well organized and readable, following a development quality standard that will facilitate future maintenance. However, performing this formatting manually or even having to standardize old code can be tedious.

Thus, this article aims to present the configuration of a React.js project with typescript using eslint and prettir to standardize the source code.

Project creation

  • yarn create react-app todo_list

At the root of the project:

Typescript dependencies

  • yarn add typescript @types/node @types/react @types/react-dom @types/jest -D

ESlint and prettier installation

  • The eslint package will inform us when some code is not following the development pattern.
  • The prettier package will aplly the pattern.

  • yarn add eslint prettier eslint-config-prettier eslint-plugin-prettier -D

After installations, run: yarn eslint --init and following the steps:

  1. To check syntax, find problems, and enforce code style
  2. JavaScript modules (import/export)
  3. React
  4. Does your project use TypeScript? y
  5. Browser
  6. Use a popular style guide.
  7. Airbnb: https://github.com/airbnb/javascript
  8. JSON
  9. Y

As I'm using yarn as package manager, then, I will removing package-lock.json and run: yarn on the project root to update the yarn cache.

So when we installing ESLint it came with a parser called espree that creating a data structure following the rules of standard JavaScript. Thus, we need a parser typescript-eslint that creating a data structure for typescript, that is a javascript superset. The packages for this parser was installed following the dependencies steps (@typescript-eslint/parser @typescript-eslint/eslint-plugin).

Configuring the project

editor config

At the root of the project, create the .editorconfig file with the content:

root = true

[*]
end_of_line = lf
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

eslint config

At the root of the project, change the content of .eslintrc.json file to:

{
  "env": {
    "browser": true,
    "es6": true
  },
  "globals": {
    "Atomics": "readonly",
    "SharedArrayBuffer": "readonly"
  },
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 2018,
    "sourceType": "module"
  },
  "plugins": ["react", "@typescript-eslint", "prettier"],
  "extends": [
    "plugin:react/recommended",
    "airbnb",
    "plugin:prettier/recommended",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "rules": {
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "js": "never",
        "jsx": "never",
        "ts": "never",
        "tsx": "never"
      }
    ],
    "prettier/prettier": "error",
    "@typescript-eslint/explicit-function-return-type": "off",
    "@typescript-eslint/no-unused-vars": "off",
    "react/jsx-filename-extension": [
      1,
      { "extensions": [".js", ".jsx", ".ts", ".tsx"] }
    ]
  },
  "settings": {
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx"]
      }
    }
  }
}

prettier config

At the root of the project, create the .prettierrc file with the content:

{
  "singleQuote": true,
  "trailingComma": "es5"
}

Loading svg logo in App.tsx

The import svg logo in App.tsx will initialing fail. To fix that create custom.d.ts whit the content:

declare module '*.svg' {
  import React = require('react');
  export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
}

and now reference this file in tsconfig.json like this:

"include": ["src", "custom.d.ts"]

Editing the vscode config (settings.json)

"eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
],
"[javascriptreact]": {
    "editor.codeActionsOnSave": {
      "source.fixAll.eslint": true,
    }
},
"editor.formatOnSave": true,
  "[typescript]": {
    "editor.formatOnSave": false,
    "editor.codeActionsOnSave": {
      "source.fixAll.eslint": true,
    }
},
  "[typescriptreact]": {
    "editor.formatOnSave": false,
    "editor.codeActionsOnSave": {
      "source.fixAll.eslint": true,
    }
}

Finally, rename any file to be a TypeScript file (index.js to index.tsx and App.js to App.tsx) and restart your server.

Source code

Discussion (12)

Collapse
martincernyawin profile image
Martin Cerny • Edited on

I had to add this to .eslintrc.js

    "import/extensions": [
       "error",
       "ignorePackages",
       {
         "js": "never",
         "jsx": "never",
         "ts": "never",
         "tsx": "never"
       }
    ],
    "react/jsx-filename-extension": [1, { "extensions": [".js", ".ts", "tsx"] }],
Enter fullscreen mode Exit fullscreen mode

Any idea why you didn't need this?

Collapse
renatobentorocha profile image
Renato Rocha Author

I Martin Cerny, thanks by observation.

I had added this line also. This can be saw in shared source code at the end of post, but i forgot to add in example.

I will add this line.

Best regards

Collapse
martincernyawin profile image
Martin Cerny

Thanks for updating the article! You should also add the other line jsx-filename-extension and then it also needs import resolver

Thread Thread
renatobentorocha profile image
Renato Rocha Author

Hi Martin,

Add the complete .eslint.rc.json like in: github.com/renatobentorocha/react_...

Thanks by observations :)

Collapse
gerbosan profile image
Carlos A. • Edited on

But... isn't --typescript flag available for create-react-app?

Please correct eslint initialization. It says yarn eslint --int but has to be yarn eslint --init

Collapse
renatobentorocha profile image
Renato Rocha Author

Hi Carlos, thanks a lot by the comment.

When we use the create-react-app with the flag "--template typescript",
what happens is that, some packages for typescript will be installed and also
will be created a tsconfig.js file. But, all other configurations will not be created.

Another thing that happens, is that, all the packages that we need only in development
environment, will be setting as production on package.json file. That is,
create-react-app template do not separe production and development packages.

I will correct "yarn eslint --int".

Thanks for all observations.

Collapse
insuusvenerati profile image
Sean

Why are these rules set?

"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-unused-vars": "off"
Collapse
renatobentorocha profile image
Renato Rocha Author

Hi Sean!

"@typescript-eslint/explicit-function-return-type": "off", -> disable the requirement of a return type in functions.
"@typescript-eslint/no-unused-vars": "off" -> disable alert about unused vars.

Best regards

Collapse
brettfishy profile image
Brett Fisher

Great post, thank you so much. Saved me a lot of pain

Collapse
renatobentorocha profile image
Renato Rocha Author

Hi bandrewfisher, thanks by comment.

I'm very happy to be able to help you.

Best regards

Collapse
gorvgoyl profile image
Gourav

Thanks, this is an extensive guide! I have few doubts.. any specific reason to choose "@typescript-eslint/parser" over "babel-eslint"? and why should we include "airbnb" in eslint "extends"?

Collapse
renatobentorocha profile image
Renato Rocha Author

Hi JerryGoyal! Thanks by comments!

Best regards