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:
- To check syntax, find problems, and enforce code style
- JavaScript modules (import/export)
- React
- Does your project use TypeScript? y
- Browser
- Use a popular style guide.
- Airbnb: https://github.com/airbnb/javascript
- JSON
- 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.
Top comments (12)
I had to add this to
.eslintrc.js
Any idea why you didn't need this?
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
Thanks for updating the article! You should also add the other line jsx-filename-extension and then it also needs import resolver
Hi Martin,
Add the complete .eslint.rc.json like in: github.com/renatobentorocha/react_...
Thanks by observations :)
Why are these rules set?
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
But... isn't
--typescript
flag available for create-react-app?Please correct eslint initialization. It says
yarn eslint --int
but has to beyarn eslint --init
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.
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"?
Hi JerryGoyal! Thanks by comments!
We need a parser to convert TypeScript into an ESTree-compatible form for ESLint; eslint.org/docs/user-guide/configu...
Airbnb has some ESLint rules, but we can use other like, github.com/google/eslint-config-go..., or none.
Best regards
Great post, thank you so much. Saved me a lot of pain
Hi bandrewfisher, thanks by comment.
I'm very happy to be able to help you.
Best regards