Recently we started using prettier and rubocop to automatically format our code on git commit. Here is how we got started with setting up both prettier and rubocop in our Ruby on Rails applications.

Generate package.json

If you don’t already have a package.json file then execute the following command to create a package.json file with value {}.

echo "{}" > package.json

Install prettier

Now execute following command to install prettier.

npm install --save-dev lint-staged husky prettier

# Ignore `node_modules`
echo "/node_modules" >> .gitignore

Add scripts & ignore node_modules

Now open package.json and replace the whole file with following content.

{
  "scripts": {
    "precommit": "lint-staged"
  },
  "lint-staged": {
    "app/**/*.{js,es6,jsx}": [
      "./node_modules/prettier/bin/prettier.js --trailing-comma es5 --write",
      "git add"
    ]
  },
  "devDependencies": {
    "husky": "^0.13.4",
    "lint-staged": "^3.6.0",
    "prettier": "^1.4.2"
  }
}

Note that if you send pull request with your changes and circleCI or such tools run npm install then downgrade husky to ^0.13.4 and that will solve the problem.

In Ruby on Rails applications third party vendor files are stored in vendor folder and we do not want to format JavaScript code in those files. Hence we have applied the rule to run prettier only on files residing in app directory.

Here at BigBinary we store all JavaScript files using ES6 features with extension .es6. Hence we are running such files through prettier. Customize this to match with your application requirements.

Note that “precommit” hook is powered by husky. Read up “husky” documentation to learn about “prepush” hook and other features.

Commit the change

git add .
git commit -m "Added support for prettier for JavaScript files"

Execute prettier on current code

./node_modules/prettier/bin/prettier.js --single-quote --trailing-comma es5 --write "{app,__{tests,mocks}__}/**/*.{js,es6,jsx,scss,css}"

We want more

We were thrilled to see prettier format our JavaScript code. We wanted more of it at more places. We found that prettier can also format CSS files. We changed our code to also format CSS code. It was an easy change. All we had to do was change one line.

Before : "app/**/*.{js,es6,jsx}"

After : "app/**/*.{js,es6,jsx,scss,css}"

Inspired by prettier we welcomed rubocop

Now that JavaScript and CSS files are covered we started looking at other places where we can get this productivity gain.

Since we write a lot of Ruby code we turned our attention to rubocop.

It turned out that “rubocop” already had a feature to automatically format the code.

Open package.json and change lint-staged section to following

"app/**/*.{js,es6,jsx,scss,css}": [
  "./node_modules/prettier/bin/prettier.js --single-quote --trailing-comma es5 --write",
  "git add"
],
"{app,test}/**/*.rb": [
  "bundle exec rubocop -a",
  "git add"
]

Open Gemfile and add following line.

group :development do
  gem "rubocop"
end

The behavior of rubocop can be controlled by .rubocop.yml file. If you want to get started with the rubocop file that Rails uses then just execute following command at the root of your Rails application.

wget https://raw.githubusercontent.com/rails/rails/master/.rubocop.yml

Open the downloaded file and change the TargetRubyVersion value to match with the ruby version the project is using. ` value to match with the ruby version the project is using.

Execute rubcop in all ruby files.

bundle install
bundle exec rubocop -a "{app}/**/*.rb"

Code is changed on git commit and not on git add

We notice that some people were a bit confused when git add did not format the code.

Code is formatted when git commit is done.

npm install is important

It’s important to note that users need to do npm install for all this to work. Otherwise prettier or rubocop won’t be activated and they will silently fail.

Full package.json file

After all the changes are done then package.json should be like as shown below.

{
  "scripts": {
    "precommit": "lint-staged"
  },
  "lint-staged": {
    "app/**/*.{js,es6,jsx,scss,css}": [
      "./node_modules/prettier/bin/prettier.js --trailing-comma es5 --write",
      "git add"
    ],
    "{app,test}/**/*.rb": [
      "bundle exec rubocop -a",
      "git add"
    ]
  },
  "devDependencies": {
    "husky": "^0.13.4",
    "lint-staged": "^3.6.0",
    "prettier": "^1.4.2"
  }
}