If you have a situation like below, this walkthrough is for you!
✔ You have a React Native project
✔ It uses TypeScript
✔ You want to set up ESLint
✔ You want to use Standard JS
NOTE: If you don't know about Standard JS, check out their rules here. Notable rules include using two spaces for indentation and not using semicolons at the end of lines.
This tutorial walks you through installing and configuring ESLint, and setting up Github Actions so ESLint runs every time you push your code.
Step-by-step commit list:
Add ESLint #1
- StandardJS
- Remove prettier (not compatible)
- Modify tsconfig
- Github actions to run ESLint and TypeScript checks
Steps
1. Install ESLint, and its plugins for React and React Native
Simply run below!
yarn add -D eslint eslint-plugin-react eslint-plugin-react
Docs: https://github.com/intellicode/eslint-plugin-react-native#installation
2. Install ESLint plugins for Standard and TypeScript
Now run this:
yarn add -D eslint@7 eslint-plugin-promise@4 eslint-plugin-import@2 eslint-plugin-node@11 @typescript-eslint/eslint-plugin@4 eslint-config-standard-with-typescript
Why do we need so many dependencies? Good question, the docs mention why.
Docs: https://github.com/standard/eslint-config-standard-with-typescript#usage
This long list of dependencies includes:
- ESLint
- Peer dependencies of eslint-config-standard
- @typescript-eslint/eslint-plugin; ESLint rules for TypeScript.
3. Disable Prettier's rules that conflict with ESLint
If you tried configuring and running ESLint at this point, you will probably find that some of its rules conflict with Prettier (which comes pre-installed in React Native projects). We can use a package called eslint-config-prettier to turn off conflicting Prettier rules (I found this solution in this helpful Github comment).
Install as below:
yarn add -D eslint-config-prettier
We will configure ESLint to use this package in step 5. Ok, we're finally done installing the necessary packages!
4. Configure .eslintignore
Create a file called .eslintignore
in your project root. This file is like .gitignore
for ESLint - you should list anything that you don't want checked by ESLint. As an example, here is my .eslintignore
:
node_modules/
babel.config.js
metro.config.js
5. Configure .eslintrc.js
There are a few file extensions that you can use for ESLint config, like .js
and .json
. We will go with .js
here.
Find or create a file called .eslintrc.js
in your project root. Then, configure as below (minus the comments):
module.exports = {
root: true,
extends: [
'@react-native-community/eslint-config', // Default RN config
'standard-with-typescript', // Installed in step 2
'eslint-config-prettier' // Installed in step 3
],
parser: '@typescript-eslint/parser', // Installed in step 2
plugins: [
'@typescript-eslint', // Installed in step 2
'react', // Installed in step 1
'react-native' // Installed in step 1
],
'parserOptions': {
'ecmaFeatures': {
'jsx': true
},
'project': './tsconfig.json' // Required for Standard plugin
},
'env': {
'react-native/react-native': true
},
'rules': {
'prettier/prettier': 'off', // Turn off prettier
// These are the rules that I use
'react-native/no-unused-styles': 'warn',
'react-native/no-inline-styles': 'error',
'react-native/no-raw-text': ['warn', {
skip: ['CustomText']
}],
'react-native/no-single-element-style-arrays': 'warn',
'object-curly-spacing': 'error',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/strict-boolean-expressions': 'off',
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/require-array-sort-compare': ['error', {
ignoreStringArrays: true
}],
'react/jsx-curly-spacing': ['error', {
when: 'always',
allowMultiline: true,
children: true
}],
'eol-last': ['error', 'always'],
'no-multiple-empty-lines': 'error',
semi: ['error', 'never'],
// Indent with 2 spaces
indent: ['error', 2],
// Indent JSX with 2 spaces
'react/jsx-indent': ['error', 2],
// Indent props with 2 spaces
'react/jsx-indent-props': ['error', 2]
}
}
}
As for specific ESLint rules, it depends on personal preference so I'll leave it up to you. If you want to see my config as a reference, you can find it here:
https://github.com/risafj/StorybookExampleReactNativeTS/blob/main/.eslintrc.js
6. Edit tsconfig.json
If you tried running ESLint at this point, you will probably get an error like this:
/Users/risa/projects/project-name/.eslintrc.js
0:0 error Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: .eslintrc.js.
The file must be included in at least one of the projects provided
You can find a discussion about this error in this Github issue. Basically, you have to include the files you want to lint in tsconfig.json
. Create a file like this if it doesn't exist yet, or add the lines below if it does.
// tsconfig.json
{
"compilerOptions": {
// Various options...
},
// Add the "include" array below
// Inside the array, specify files you want ESLint to check
"include": [
"./**/*",
"./*",
".eslintrc.js"
]
}
7. Add npm scripts
At this point, you're ready to run ESLint! But before that, let's add some npm scripts to your package.json
to save you a few keystrokes.
// package.json
{
"scripts": {
// Add the two scripts below
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"lint:fix": "eslint . --fix --ext .js,.jsx,.ts,.tsx",
}
}
Now, you can run ESLint with yarn lint
or yarn lint:fix
(for auto-correcting errors).
8. [Optional] Run ESLint in Github Actions
You can configure Github Actions to run ESLint every time you push your code. This is convenient because it's easy to forget to run lint locally. Setup is simple - just copy the configuration below.
# .github/workflows/lint.yml
name: Lint
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install modules
run: yarn
- name: Run ESLint
run: yarn lint
That's all! Thanks for reading, and I'd like to hear if it worked :)
Top comments (7)
Nice, works as expected, except for StandardJS stuff (like extra semicolons) not getting detected (VSCode).
@cseelus Hi, thank you for the comment! It turns out, you don't need the package
eslint-config-prettier
if you're turning offprettier
anyway.So what you can do is either:
eslint-config-prettier
and remove it from.eslintrc.js
(if you want to use ESLint's standard js config and turn off prettier entirely), OReslint-config-prettier
, and remove the line'prettier/prettier': 'off'
from.eslintrc.js
(if you want to use prettier)I've opted for option 1.
I'd forgotten to update the article accordingly - I will do this.Sorry for any confusion!
@risafj Thanks for your reply. I tried both approches, and they didn't work, so I checked out your referenced repo (github.com/risafj/StorybookExample...), to see if the problem was with my project.
With or without both changes from your comment, same as before:
Linting errors are shown, but StandardJS stuff (like extra semicolons, double quotes, …) is not getting linted (VSCode, NeoVim) unfortunately.
Sorry for the late response - I checked, and semicolons are linted in my environment 😞 So I don't know what the issue could be. I use VSCode and lint on save with the config below:
@Chrıs Seelus
Hi, it's been a few months but I realized that now you need to add the below in your ESLint rules to disable semicolons!
nice article! Exactly what I need with my React Native with TypeScript project. thanks!
Thanks for the comment! Hope it's useful :)