Todo App with React Native — Part 2

ESLint, Prettier and more …

Peter Lazar
Jul 23, 2017 · 6 min read

App skeleton

As mentioned in the earlier post we’ll use CRNA to generate an app skeleton for us. Node 6 or above is required.

I have linked to the repo at the end of the post.

npm install -g create-react-native-app
create-react-native-app Todoer
cd Todoer/

This generates a directory structure as shown below:

As you can see, it has expo as dependency. The great thing about this is that I don’t need to worry about RN upgrades, expo takes care of it. There are also scripts for running the app on android and iOS.

ESLint

Alrighty, let’s setup ESLint now. I want to use airbnb’s config as a base and then add/remove stuff as required.

yarn add -D eslint
yarn eslint -- --init

The second command takes you through a wizard of sorts. I’ve decided to use a style guide from airbnb. I’ll also go ahead and add "lint": "eslint ." to the scripts section in package.json, that way I can run yarn lint to run the linter.

After the initialisation script runs, an .eslintrc file is generated. This is the config file that ESLint uses. If you take a look at it, there’s only one line:

{
"extends": "airbnb"
}

What this means is that, the current configuration is extended from eslint-config-airbnb, this field can also accept an array of configurations and the last item takes most precedence.

The first rule I’d like to enable is to enforce no semi colons, why add them to a language which supports automatic semicolon insertion. There is a pitfall with this approach but another eslint rule can enforce that we don’t bite that bullet, and that rule is enabled by default.

So how do we configure various rules with ESLint? It’s fairly simple, add this to .eslintrc:

{
...
"rules": {
"semi":["error", "never"]
},
...
}

Awesome, this rule tells eslint to never have semicolons and throw an error if there’s one.

We’ll go ahead and add eslint-plugin-react-native to enable some RN specific lint rules.

yarn add -D eslint-plugin-react-native

Now we can add this plugin to the configuration and setup some rules provided by the plugin.

{
...
"plugins": ["react-native"],
"rules": {
"react-native/no-unused-styles": 2,
"react-native/split-platform-components": 2,
...
}
...
}

So what’s an ESLint plugin? It gives ESLint access to more rules than the one’s it supports by default. There are a whole lot of plugins that can be used which I will not go into just now.

Prettier

Prettier is a source code formatter. It works at the AST level and basically re-writes your source code so that a consistent style is maintained throughout the source code. There are sensible defaults which you can modify based on your taste.
Prettier also works well with ESLint, hence in this section we’ll go ahead and give ESLint some Prettier power.

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

We’ll add prettier to the the end of extends array since this will disable any rules that conflict with prettier rules from any of the other configurations applied.

We’ll also add prettier to the plugins array so that we can modify the default rules applied by prettier.

Finally we’ll add the following to the rules object to modify the prettier default rules.

"prettier/prettier": ["error", {"singleQuote": true, "semi": false, "trailingComma": "es5"}],

The above rule makes sure that single quotes are enforced, no unnecessary semicolons are present and trailing commas are present at end of objects, arrays etc. The last one makes sure that commits look clean when all we have done is add one more item to an object or array.

As you might have guessed, the earlier added semi rule is now redundant and can be removed.

Now running the linter will also report issues that prettier catches.

ESLint also can fix some of the simpler issues by itself, this can be done by:

yarn lint -- --fix

The above command will modify your source code and fix whatever is possible.

We’ve come down to 7 errors from 17, that’s a good start. Let’s break down what the remaining issues are:

  • react/prefer-stateless-function: This makes sense, since the App component does not have any state associated with it, it only needs to be a stateless component. Fixing this includes disabling one rule "arrow-body-style": "off"
  • react/jsx-filename-extension: This is not a particularly useful rule, so we’ll modify it to ensure that jsx only appears in files with extension .js or .jsx . Add this to the rules object "react/jsx-filename-extension": ["error", { "extensions": [".js", ".jsx"] }]
  • no-use-before-define: This is rule is self explanatory, move up the styles object before it’s used.
  • import/first: This rule description is also pretty straightforward, put all absolute imports first, followed by relative imports.
  • no-undef: Here, according to ESLint, it and expect are not defined. But in RN these are globally available. We can specify to ESLint that these are globals by adding the following to .eslintrc
{
...
"globals": {
"it": true,
"expect": true
},
...
}

Editor Setup

Now that we have ESLint and Prettier working, let’s get them to work with our editor. Fortunately that’s an easy enough step, we just need to install the necessary editor extensions. There’s an ESLint extension maintained by Microsoft and you can install it from the Extensions window. We can also create a json file which can recommend the user to install a set of extensions once they open the project in VSCode

mkdir .vscode
touch .vscode/extensions.json

And add the following to that file

{
"recommendations": [
"dbaeumer.vscode-eslint"
]
}

This makes it convenient for the user to install any plugins relevant to the current project.

We should have ESLint working with VSCode now.

Lint-Staged (Bonus)

What good is automatic fix going to do us if we have to run it each time manually. But fret not, we can setup a pre-commit hook that will run the linter with the --fix flag every time we are about to perform a commit.

This will fix any issues it can and throw errors for which it cannot. This will ensure that all code that is committed has passed through the linter.

yarn add -D lint-staged husky

We’ll go ahead and add some bits to the package.json file:

{
...
"scripts": {
...
"precommit": "lint-staged"
},
"lint-staged": {
"*.js": [
"eslint --fix .",
"git add"
]
},
}

husky will run the precommit script before a commit happens, which calls lint-staged which asks eslint to run on any staged .js file and fix any issues it can. This will throw errors if there are issues that the linter cannot fix and stop the commit operation.

This is what the repo looks at the end of part — 2: Todoer Repo

That’s all for now folks.

Stay tuned for the next post. Please put in feedback and questions in the comments please.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade