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 {}.
1echo "{}" > package.json
Install prettier
Now execute following command to install prettier.
1npm install --save-dev lint-staged husky prettier 2 3# Ignore `node_modules` 4echo "/node_modules" >> .gitignore 5echo "/package-lock.json >> .gitignore
Add scripts & ignore node_modules
Now open package.json and replace the whole file with following content.
1{ 2 "scripts": { 3 "precommit": "lint-staged" 4 }, 5 "lint-staged": { 6 "app/**/*.{js,es6,jsx}": [ 7 "./node_modules/prettier/bin/prettier.js --trailing-comma --single-quote es5 --write", 8 "git add" 9 ] 10 }, 11 "devDependencies": { 12 "husky": "^0.13.4", 13 "lint-staged": "^3.6.0", 14 "prettier": "^1.4.2" 15 } 16}
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.
Commit the change
1git add . 2git commit -m "Added support for prettier for JavaScript files"
Execute prettier on current code
1./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
1"app/**/*.{js,es6,jsx,scss,css}": [ 2 "./node_modules/prettier/bin/prettier.js --single-quote --trailing-comma es5 --write", 3 "git add" 4], 5"{app,test}/**/*.rb": [ 6 "bundle exec rubocop -a", 7 "git add" 8]
Open Gemfile and add following line.
1group :development do 2 gem "rubocop" 3end
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.
1wget 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.
1bundle install 2bundle 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.
1{ 2 "scripts": { 3 "precommit": "lint-staged" 4 }, 5 "lint-staged": { 6 "app/**/*.{js,es6,jsx,scss,css}": [ 7 "./node_modules/prettier/bin/prettier.js --trailing-comma es5 --write", 8 "git add" 9 ], 10 "{app,test}/**/*.rb": [ 11 "bundle exec rubocop -a", 12 "git add" 13 ] 14 }, 15 "devDependencies": { 16 "husky": "^0.13.4", 17 "lint-staged": "^3.6.0", 18 "prettier": "^1.4.2" 19 } 20}