June 12, 2017
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.
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
Now execute following command to install prettier.
npm install --save-dev lint-staged husky prettier
# Ignore `node_modules`
echo "/node_modules" >> .gitignore
echo "/package-lock.json >> .gitignore
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 --single-quote 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 "pre-commit" hook is powered by husky. Read up "husky" documentation to learn about "prepush" hook and other features.
git add .
git commit -m "Added support for prettier for JavaScript files"
./node_modules/prettier/bin/prettier.js --single-quote --trailing-comma es5 --write "{app,__{tests,mocks}__}/**/*.{js,es6,jsx,scss,css}"
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}"
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 rubocop in all ruby files.
bundle install
bundle exec rubocop -a "{app}/**/*.rb"
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.
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.
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"
}
}
If this blog was helpful, check out our full blog archive.