DEV Community

Risa Fujii
Risa Fujii

Posted on • Edited on

How to set up ESLint with StandardJS for a new React Native/TypeScript project

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

  1. ESLint
  2. Peer dependencies of eslint-config-standard
  3. @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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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]
  }
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
  ]
}
Enter fullscreen mode Exit fullscreen mode

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",
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

That's all! Thanks for reading, and I'd like to hear if it worked :)

Top comments (7)

Collapse
 
cseelus profile image
Chrıs Seelus

Nice, works as expected, except for StandardJS stuff (like extra semicolons) not getting detected (VSCode).

Collapse
 
risafj profile image
Risa Fujii • Edited

@cseelus Hi, thank you for the comment! It turns out, you don't need the package eslint-config-prettier if you're turning off prettier anyway.

So what you can do is either:

  1. Uninstall eslint-config-prettier and remove it from .eslintrc.js (if you want to use ESLint's standard js config and turn off prettier entirely), OR
  2. Keep eslint-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!

Collapse
 
cseelus profile image
Chrıs Seelus

@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.

VSCode

Thread Thread
 
risafj profile image
Risa Fujii

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:

  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
risafj profile image
Risa Fujii

@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!

    semi: ['error', 'never'],
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jte0711 profile image
James

nice article! Exactly what I need with my React Native with TypeScript project. thanks!

Collapse
 
risafj profile image
Risa Fujii

Thanks for the comment! Hope it's useful :)