Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to configure React Native (Expo) project to use AirBnB's React rules via ESLint? #1589

Closed
superKalo opened this issue Oct 12, 2017 · 22 comments
Closed

Comments

@superKalo
Copy link

@superKalo superKalo commented Oct 12, 2017

I simply want to set-up the AirBnb's React (Native) rules via ESLint on a React Native (Expo) project.

I found a ton of contradictory articles how to do that and I got really frustrated. Are there any official set-up guidelines?

Which modules exactly do I need to install with npm and how should my .eslintrc config look like?

PS: Could somebody please add a "question" tag to this issue?

@superKalo superKalo changed the title How to configure React Native (Expo) project to use AirBnB's React rules (ESLint)? How to configure React Native (Expo) project to use AirBnB's React rules via ESLint? Oct 12, 2017
@amackintosh
Copy link

@amackintosh amackintosh commented Nov 13, 2017

This is what I do in React and React Native:

Step 1

npm install --save-dev eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y babel-eslint

Step 2
Backup your eslintrc file in case you want to examine it.

Step 3

eslint --init
  1. Select 'Use a popular style guide'
  2. Select Airbnb
  3. Select your options, pick JSON type (.eslintrc is the old filename based on my research, but it's the same thing)
  4. Allow it to update newer versions and/or install packages if it asks

Step 4
Restart your editor

Step 5
Paste this into your .eslintrc.json:
and remove my comments which will cause the JSON to blow up

{
    "env": {
        "node": true, // this is the best starting point
        "browser": true, // for react web
        "es6": true // enables es6 features
    },
    "parser": "babel-eslint", // needed to make babel stuff work properly
    "extends": "airbnb"
}

If there are expo eslint settings, they will fit on top of these.

I collected these settings over time, mostly from researching specific JSX and babel related errors and reading.

I'm posting it because no one else has helped you in the past month, and this works. We can now switch the question from, "what is the correct way?", to the more easy to handle "is this not the correct way?"

@superKalo
Copy link
Author

@superKalo superKalo commented Nov 14, 2017

Thank you, @amackintosh ! <3

@ljharb
Copy link
Collaborator

@ljharb ljharb commented Nov 15, 2017

@amackintosh I've removed your custom rules (since they're not relevant to your answer) and also all the redundant stuff, which included all the "plugins" declarations, sourceType, and parserOptions, all of which the airbnb config specifies already.

@superKalo superKalo closed this Nov 15, 2017
@marsonmao
Copy link

@marsonmao marsonmao commented Nov 30, 2017

@amackintosh I've done the same with you, but I can't identify __DEV__ as a valid global variable. I think this one should be valid since it is listed in the official document [here]. Not sure if anyone got some clues how to fix this issue? I tried adding globals in .eslintrc but don't think it's the correct way.

@ljharb
Copy link
Collaborator

@ljharb ljharb commented Nov 30, 2017

@marsonmao That is indeed the correct way; also that document is for react-native, and not for JS or react overall.

@marsonmao
Copy link

@marsonmao marsonmao commented Dec 1, 2017

@ljharb Thanks. I think you're right since I found the .eslintrc file of react native, and it adds __DEV__ in globals there.

And I know the doc I mentioned is for react-native, but this issue was related so I wrote the question, hope that was proper.

@mostafa-drz
Copy link

@mostafa-drz mostafa-drz commented Jan 18, 2018

(Just a quick note on the solution mentioned here)
The config @amackintosh shared here works very well for me, but I got the error
[eslint] JSX not allowed in files with extension '.js' (react/jsx-filename-extension)
(because I use some helper functions in my components for rendering out of the render function of component), I solved this problem by what mentioned here, so my .eslintrc.json is:
{ "env": { "node": true, "browser": true, "es6": true }, "parser": "babel-eslint", "extends": "airbnb", "rules": { "react/jsx-filename-extension": [ 1, { "extensions": [ ".js", ".jsx" ] } ] } }
and everything is working perfect

@gitsad
Copy link

@gitsad gitsad commented Mar 2, 2018

I have just started a project in the react native with expo and I wonder if it's possible to lint the code on expo reload. On web we have webpack and eslint-loader. I know that I can eject the app and build react with haul or with something else and probably after that inject some eslint plugin to handle lint on hot reload. Is there any way to handle something like this in react native with expo without ejecting ?

@crj92
Copy link

@crj92 crj92 commented Mar 23, 2018

@amackintosh , Hi and thanks for the steps you have provided. I have used the same for CRNA and RN projects, but it is not working for expo projects. At step 1, it installs those package but removes 500+ packages, which in turn starts throwing error on many libraries being not included. Please suggest something.

@mhulse
Copy link

@mhulse mhulse commented Apr 15, 2018

Not sure if this helps anyone else, but due to the local install, I had to add eslint as an npm script to my package.json:

"scripts": {
  "eslint": "eslint"
}

And then:

$ npm run eslint -- --init
@007arunwilson
Copy link

@007arunwilson 007arunwilson commented May 10, 2018

@amackintosh (y)
But for me it worked like
./node_modules/.bin/eslint --init

@aurelienbouteiller
Copy link

@aurelienbouteiller aurelienbouteiller commented May 11, 2018

There is also "npx" which can be useful here.
It allows to only write

npx eslint

when it’s installed in local.
https://github.com/zkat/npx/

@agm1984
Copy link

@agm1984 agm1984 commented May 19, 2018

I can't edit my comment now and of course mind blown that I just helped myself in the future after I forgot all this. 🤣

I just noticed jest is missing from the env declaration. You can add it there to get rid of the red splatter in your test files. Here it is added to what is shown above:

    "env": {
        "node": true,
        "browser": true,
        "es6": true,
        "jest": true
    },
@calendee
Copy link

@calendee calendee commented Aug 29, 2018

@gitsad Did you ever find a solution to this? I'd like the Metro Bundler to automatically run eslint on each reload.

@xavierartot
Copy link

@xavierartot xavierartot commented Sep 3, 2018

I have a config for react-native:

  parser: 'babel-eslint',
  parserOptions: {
    "ecmaVersion": 6,
    allowImportExportEverywhere: false,
    ecmaFeatures: {
      jsx: true,
    },
  },
  plugins: ['react', 'react-redux', ],
  extends: ['airbnb',
  // "eslint:recommended"
  'plugin:react/recommended', 'plugin:react-redux/recommended', ],
  rules: {
    'no-debugger': 0,
    'import/no-named-as-default': 0,
    'react/jsx-indent': [2, 2], // error & 2 spaces
    'react/jsx-indent-props': [2, 2],
    'react/prefer-stateless-function': 0,
    'react/jsx-filename-extension': 0,
    'react/no-unused-state': 1,
    'jsx-a11y/anchor-is-valid': 1,
    'no-unused-vars': 1,
    quotes: [2, 'single'],
    'react/jsx-quotes': 1,
    'class-methods-use-this': 0,
    'no-console': 0,
    'no-return-assign': 1,
    semi: ['error', 'never'],
    'react/jsx-key': 2,
    'react/jsx-closing-tag-location': 2,
    'react/no-access-state-in-setstate': 2,
    'react/button-has-type': 2,
    'react/jsx-sort-props': 2,

    // configure when I have time
    'react/display-name': 1,
    'react/forbid-prop-types': 1,
    'react/jsx-boolean-value': 1,
    'react/jsx-closing-bracket-location': 1,
    'react/jsx-curly-spacing': 1,
    'react/jsx-handler-names': 1,
    'react/jsx-max-props-per-line': 1,
    'react/jsx-no-bind': 1,
    'react/jsx-no-duplicate-props': 1,
    'react/jsx-no-literals': 1,
    'react/jsx-no-undef': 1,
    'react/jsx-pascal-case': 1,
    'react/jsx-sort-prop-types': 1,
    'react/jsx-sort-props': 1,
    'react/jsx-uses-react': 1,
    'react/jsx-uses-vars': 1,
    'react/no-danger': 1,
    'react/no-did-mount-set-state': 1,
    'react/no-did-update-set-state': 1,
    'react/no-direct-mutation-state': 1,
    'react/no-multi-comp': 1,
    'react/no-set-state': 1,
    'react/no-unknown-property': 1,
    'react/prefer-es6-class': 1,
    'react/prop-types': 1,
    'react/react-in-jsx-scope': 1,
    'react/require-extension': 1,
    'react/self-closing-comp': 1,
    'react/sort-comp': 1,
    'react/wrap-multilines': 1,
  },
}

walterwing added a commit to walterwing/react-native-sample-app that referenced this issue Dec 29, 2018
@Asday
Copy link

@Asday Asday commented Apr 19, 2019

@gitsad @calendee did either of you figure out how to get it working? No combination of "eslint" and "metro" yields anything useful from google...

@16oh4
Copy link

@16oh4 16oh4 commented Apr 7, 2020

@gitsad @calendee did either of you figure out how to get it working? No combination of "eslint" and "metro" yields anything useful from google...

I am looking to do the same thing!! I have researched for hours and no luck.

@Asday
Copy link

@Asday Asday commented Apr 7, 2020

@16oh4 I'm neck deep in a home move right now, do you wanna give me a poke in a week? I can show you roughly what I did, then.

@calendee
Copy link

@calendee calendee commented Apr 7, 2020

@gitsad @calendee did either of you figure out how to get it working? No combination of "eslint" and "metro" yields anything useful from google...

Nope. I think I gave up. Sorry.

@pcy8282

This comment was marked as spam.

@tibbus
Copy link

@tibbus tibbus commented Apr 24, 2020

@Asday do you have eslint working inside metro?

@Asday
Copy link

@Asday Asday commented Apr 24, 2020

I do not. I have two terminal windows - one for metro (grumble grumble grumble), and one for jest, which I have running everything else.

An abbreviated version of my package.json:

{
  "scripts": {
    "jest:watch": "jest --watch --changedSince=origin/master"
  },
  "devDependencies": {
    "eslint": "5.16.0",
    "eslint-config-airbnb": "17.1.0",
    "eslint-plugin-import": "2.17.2",
    "eslint-plugin-jsx-a11y": "6.2.1",
    "eslint-plugin-react": "7.12.4",
    "eslint-plugin-simple-import-sort": "3.1.0",
    "jest-expo": "33.0.1",
    "jest-matcher-utils": "24.7.0",
    "jest-runner-eslint": "0.7.5"
  },
  "jest": {
    "projects": [
      {
        "displayName": "test",
        "preset": "jest-expo",
        "transform": {
          "^.+\\.(bmp|gif|jpg|jpeg|mp4|png|psd|svg|webp|ttf|otf|m4v|mov|mp4|mpeg|mpg|webm|aac|aiff|caf|m4a|mp3|wav|html|pdf|obj)$": "jest-expo/src/preset/assetFileTransformer.js",
          "^.+\\.(jsx?|tsx?)$": "babel-jest"
        },
        "transformIgnorePatterns": [
          "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|sentry-expo|native-base|redux-persist-expo-securestore)"
        ]
      },
      {
        "runner": "jest-runner-eslint",
        "displayName": "lint",
        "testMatch": [
          "**/*.js",
          "**/*.jsx"
        ]
      }
    ]
  }
}

Then I can run npm run jest:watch, and it'll behave relatively nicely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet