Tooling in React Native / Javascript

All the little goodies that make development in javascript less of a PITA.

Brad Dunn
8 min readDec 5, 2017
I wish my desk was like this at home. This seems so calm and quiet.

Javascript is an extremely powerful and flexible language, but it’s no secret that the language has a bit of well-deserved notoriety for being a little — shall we say — fast and loose when it comes to receiving and interpreting feedback when things go wrong. If you are lucky, you might get an error stack giving you some line numbers to a few dependencies in your project, leaving you as a developer to divine where in the actual project codebase the error occurred. Devoid of its own type system, and suffering from weak type checking internal to the language, Javascript has a whole class of problems that crop up during development that other languages do not suffer from. To not lose days of development time debugging a particularly elusive problem, javascript development necessitates several helper libraries and projects to keep everything on the up-and-up, and to keep development sane.

This post intends to give you a brief introduction to a few important tools, as well as some code examples to follow along with. Since we’re a React Native shop, all that follows will be from the React Native development perspective, but with some minor tweaking all that follows would also be relevant to nodejs and web developers. Specifically I will be covering:

  1. ESLint
  2. Flow
  3. Jest Testing Framework

Do you have to use these tools? No.

Are there alternatives to the tools listed above? Phht… of course there are, this is Javascript after all!

Why do you use these tools if they aren’t required? Because they help catch errors early, and keep code consistent!

So without further ado, let’s dig into what these tools do and how they can assist in your development!

Linting your code with ESLint

ESLint is, as their documentation states, “[a] pluggable linting utility for JavaScript and JSX.” Basically, it helps enforce certain best practices and rules in your code by putting little red squigglies under your crappy code in your editor of choice. There are a ton of ways that you can introduce ESLint into your codebase, and there are a lot of pre-made rulesets and plugins for ESLint so you don’t have to write all the rules for your project from scratch.

For React Native development at 4Thought Studios, we rely on the react, react-native, and flowtype eslint plugins. There are other options, like the fantastic AirBnB eslint plugin, but for us at 4Thought, we took the following approach:

We started by first installing our dependencies as dev dependencies:

yarn add --dev eslint babel-eslint eslint-plugin-react eslint-plugin-react-native eslint-plugin-flowtype

We then created an .eslintrc.json file in our project so we could tell ESLint what rules and plugins to use when parsing our files:

{
"plugins": [
"react",
"react-native",
"flowtype"
],
"extends": [
"plugin:flowtype/recommended",
"plugin:react-native/all"
],
"rules": {
"valid-jsdoc": "off"
}
}

The plugins section lists out all of the eslint-plugin-* packages we want ESLint to use, and the extends section tells ESLint to use and extend rules provided by these plugins while determining what error and warning squigglies it should show us when parsing a file.

One optional step that I encourage you to take is to find a plugin that integrates ESLint directly into your code editor of choice. We primarily use Visual Studio Code at 4Thought, so we add in the great ESLint plugin developed and maintained by Microsoft.

Yay! We have linting! Boo… the squigglies are giving me anxiety!

And there you go! ESLint will do the job of trying to save yourself from bad moves, whether it be from inlining styles on components, or using uninitialized variables without realizing it. Use it — you’ll thank me!

Static Type Checking with Flow

Not everyone will agree with me on this point, but adding a static type checker saves tons of time, bugs, and developer headaches. This doesn’t come without cost — the cognitive overhead of learning yet another tool is not free. I believe that the time investment and extra characters written are invaluable when dealing with a non-trivial level of complexity in a large project.

Flow adds a layer of static type checking pre-runtime to your javascript project. Usually a transformer like babel strips out all of this extra type information before your javascript is bundled up in a production build, so its just to keep things a bit more sane during development and doesn’t really offer any protection at runtime. This is no different than other type systems, except for that little annoying fact that other true strongly-typed languages like C# or Java won’t compile until you’ve fixed the type errors. Flow does not have such a restriction.

That being said, it’s a really strong tool to add into your development workflow and can save a lot of headaches. I encourage you to read through the beginning of the documentation at flow.org to see what to expect when writing javascript with flow, but I’ll give you the TL;DR after we get the basics set up.

When you first set up a brand new react native project, whether it be via the react-native CLI tool, or via create-react-native-app, flow’s config file is already set up for you. There’s a file called .flowconfig in the root of your project’s directory that has all the info flow needs in order to function properly. Woohoo!

Just because react native has provided you with a .flowconfig file doesn’t mean that your project is ready to use flow. First, we need to make sure all relevant dependencies are installed and set up.

If you used create-react-native-app to set up your project, the README.md that is generated for you has instructions on how to set up flow. These instructions are relevant to most setups, so I will reiterate them here:

To add a local dependency to the correct Flow version to a Create React Native App project, follow these steps:

1. Find the Flow `[version]` at the bottom of the included .flowconfig

2. Run `yarn add — dev flow-bin@x.y.z`, where `x.y.z` is the .flowconfig version number.

3. Add `”flow”: “flow”` to the `scripts` section of your `package.json`.

4. Add `// @flow` to any files you want to type check (for example, to `App.js`).

Now you can run `yarn flow` to check the files for type errors.

You can optionally use a plugin for your IDE or editor for a better integrated experience.

To learn more about Flow, check out its documentation.

After you’re good to go, and you’ve added the appropriate plugin to your code editor (highly encouraged) you should be up and running! As the above says, anytime you add // @flow to the top of your javascript file, flow’s parser starts watching the file and giving you feedback about any errors involving the type system.

It’s complaining about type related things!
We got it to stop complaining after adding a ‘Props’ type!

Although I can’t really get into the ins-and-outs on how to use Flow in this article, there are plenty of good resources on the subject, as well as the official documentation (which is really good).

Jest-ing

Get it? Testing? Jest-ing? Ayuk yuk yuk

And finally its time to talk about testing. I’m not sure if you are like me, but tests in my project always find a way to get stale. I believe that it has to do with them being a pain to write, and often I find myself re-writing big chunks of the logic of the component or function that I am testing just to verify those things all over again in a test. And finally, running tests gets sllllooooowww after a non-trivial amount of tests get added to the test suite.

Jest makes tests less painful, particularly in the three areas I outlined above. It runs fast because it runs tests purely in headless javascript, and by default it only runs tests for tests or tested files that have been changed since the previous commit. Jest makes writing tests dead simple, so the barrier to entry is much smaller and there is little to no pain in writing new tests. And finally Jest cuts down on the need to rewrite application logic in tests because of it’s concept of snapshots — recording the current state of something at the time of a test run so that you can compare with your own eyes if the change was intended or not. I go into great depth as to why snapshots are cool and worth using in a past article.

So — how do we use it? Well, if you set up a react native project using either the CLI method or create-react-native-app, tests are set up! Just run:

yarn test

Or alternatively if you want tests to automatically re-run as you work:

yarn test --watch

That’s it! you get a nice little readout in your console about whats red and whats green, and you can continue on your merry way!

Wrapping Things Up

I hope that this brief tour of these tools has helped you get set up and on your way to more sane development. Some of these tools are complicated and take some time to become effective with, but I believe that they come with huge payoffs in saved time and reduction of bugs across your project. Best of luck to you in your current/future React Native projects!

Recently at 4Thought Studios we made some personnel changes (Hi Dan! Hey Kwame!) and it became necessary to stop writing documentation and guides for myself, and start providing materials to the broader engineering team. This post started out as a brief writeup to explain to my team why the heck they need to use all of these extra “things” that all have their own config files and their own rules — was it just a bunch of extra work for no reason? NO! It has benefits! I promise!

Further Reading

--

--