Setting up Vim for React development

September 12, 2017 | Victor Mours | 5-minute read

We’ve recently introduced Preact to our Rails stack at Drivy, and the results have been rather satisfying so far. As a Vim lover, I was curious to see how to setup Vim for working on a React (or React-like) project, and as usual, the wealth of plugins out there didn’t disappoint.

Here’s the setup that I came up with:

Syntax Highlighting

Let’s start with the basics, and get some syntax highlighting for javascript and JSX by adding these to the plugins section of your .vimrc:

Plug 'pangloss/vim-javascript'
Plug 'mxw/vim-jsx'

I’m assuming here that you’re using vim-plug as your plugin manager, if you’re unsure about how to install these with another plugin manager, check out the readme from either repo.

Emmet for easier JSX

In a Rails environment, I’m mostly used to languages like Slim or Haml which simplify writing html, so going back to writing closing tags in JSX felt a little tedious. Fortunately, you can get rid of some of the grunt work with Emmet-vim, which allows you to expand css selectors into html (or JSX) on the fly.

For example, you can type

%h2#tagline.hero-text

and expand it to

<h2 id="tagline" className="hero-text"></h2>

in two keystrokes.

Let’s install it:

Plug 'mattn/emmet-vim'

And then add this to your .vimrc:

let g:user_emmet_leader_key='<Tab>'
let g:user_emmet_settings = {
  \  'javascript.jsx' : {
    \      'extends' : 'jsx',
    \  },
  \}

Give it a try: in insert mode, type p.description, and then hit Tab-, (without leaving insert mode). It will expand as <p className="description"></p>. Note that this is using the JSX className syntax, thanks to the tweak on user_emmet_settings.

Syntax checking

Syntastic has been the go-to syntax checking Vim plugin for a while, but it has the downside of being synchronous. That means that you can’t do anything - not even move your cursor - while it is running. For large files, this gets annoying rather quickly. The good news is that vim now has support for async tasks, and you can switch to Ale, which is short for Asynchronous Lint Engine. You will never be interrupted by your linter again, hurray!

Arguably, this isn’t specific to React, but since you’ll need syntax checking for JSX, it’s a good opportunity to improve your overall setup.

Installing Ale is nothing unexpected:

Plug 'w0rp/ale'

Of course, Ale is only the glue between vim and the actual syntax checker that runs under the hood, which in this case would be eslint.

Here’s how to install eslint:

$ yarn add --dev eslint babel-eslint eslint-plugin-react

And then configure it by runnning:

$ eslint --init

This will create a .eslintrc file, which you should check into version control so that everybody uses the same style guide. You may want to have a chat with the other people working on your project to make sure everybody agrees on which rules you’ll enforce.

Ale works out of the box with eslint, so there’s no further setup needed. However, I found Ale more pleasant to use with these couple tweaks in my vimrc.

let g:ale_sign_error = '●' " Less aggressive than the default '>>'
let g:ale_sign_warning = '.'
let g:ale_lint_on_enter = 0 " Less distracting when opening a new file

Autoformatting

Ok, this is the best part. You may know about Prettier, an “opinionated code formatter”, which will reformat your javascript code from scratch, much like gofmt does for Go.

Having Prettier run each time you save a file is surprisingly satisfying: you basically never have to think about formatting again. After using it for a couple hours, I even realized my way of writing was a bit different: I was just typing unformatted code and trusting Prettier to make it look good. This is the killer feature: you get to focus on what your code does, not how it’s written.

Once again, this will be useful for all your JS projects, not just React ones, so let’s get the setup going:

First, let’s install prettier:

$ yarn add --dev prettier eslint-config-prettier eslint-plugin-prettier

Now, you should be able to run eslint --fix src/App.js, and src/App.js will be reformatted automatically.

Good, now let’s make that happen in vim each time you save a file. A naive way of doing this would just be to set an autocommand to run eslint, but that would have the downside of being synchronous. Rather than digging into vim’s async job api, the easiest way of doing this is to use asyncrun, a plugin to easily run shell commands in the background.

Plug 'skywind3000/asyncrun.vim'

And then we can add that sweet sweet autocommand.

autocmd BufWritePost *.js AsyncRun -post=checktime ./node_modules/.bin/eslint --fix %

The -post=checktime option reloads the buffer from the file after the command is done running.

However, this does bring an issue: each time you’ll tweak a file, the whole thing will be reformatted, which might make your git diff a bit unreadable. Here at Drivy, we’ve decided to bite the bullet and run prettier on our whole JS codebase, so that the styling would be up to date on the whole app. It was a big commit, but everything went fine, and we now have a consistent and pleasant style accross the codebase.

Closing thoughts

This config is working pretty well for me, but as always with Vim, it’s always possible to go deeper and find other improvements. If you do or if you have any questions, feel free to ping me on twitter.

Happy coding with Vim and (p)React!

View openings 👍  Like this post? Join Drivy's engineering team!