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 go about setting up Vim React or React-like project. As usual, the wealth of plugins out there didn’t disappoint.
Here’s the setup that I came up with:
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
:
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 the respective repos.
In a Rails environment, I’m mostly used to languages such as 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 enables you to expand your CSS selectors into HTML (or JSX) on the fly.
For example, you could type
and then expand it to
in just two keystrokes.
Let’s install it:
and then add this to your .vimrc
:
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
.
Syntastic has been the go-to solution for syntax checking in Vim for a while, but it has the major flaw 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:
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:
and then configure it by runnning:
This will create an .eslintrc
file, which you should check in to version control so that everybody is using 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 a couple tweaks in my vimrc:
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 that you save a file is surprisingly satisfying: you’ll 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. That’s its 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:
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.
And then you can add that sweet sweet autocommand.
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 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 smoothly, and we now have a consistent and pleasant style across the codebase.
This config is working pretty well for me, but as ever 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!