Code Convention Tooling for Better Collaboratation

If you have worked at any size of company before or now, you have had the difficulty about inconsistent code styles to work with. I have worked at a company which has front-end code based on Rails platform. At that time, it was really diffult to have code convention tools for front-end. So, whenever someone has pull request to get review, other engineers need to make a comment on each code convention issue. Obviously, there were some struggling about those comments since it doesn’t affect on the performance at all, it just style preference, and it cannot be agreed from all of the engineering team sometimes. In that situation, some engineers ignore the comment and merge their pull request without applying it, and it can be a critical communication issue.

Fortunately, the architect team decided to move on to node.js platform for front-end, and we could introduce code convention tools for entire JavaScript code. Then, integrated with CI tool, jenkins, to run lint testing whenever there is new pull request created.

I would like to share how to set up the linter tool for JavaScript code base application, and how to integrate with Travis CI for your personal projects on Github.

Setup Repository

As for now, Eslint is the most popular tool for linting the JavaScript code, so I will introduce it to validate the JavaScript code convention. Let’s set up a repository for this example.

Create a repository at Github

Once you created the repository, let’s clone it on your local machine.

1
2
$ git clone git@github.com:minsooshin/codeConventionTooling.git
$ cd codeConventionTooling

Install Packages

For this example, we will need some modules to run our application.

1
2
3
4
5
6
7
$ yarn init # or npm init
$ yarn add --dev babel-core
$ yarn add --dev babel-plugin-transform-object-rest-spread
$ yarn add --dev babel-preset-es2015
$ yarn add --dev eslint
$ yarn add --dev eslint-friendly-formatter
$ yarn add --dev eslint-watch

I add one by one to show which packages are needed, you can do this with one line command. Once you installed the packages, your package.json file will look like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"name": "codeConventionTooling",
"version": "0.0.1",
"description": "code convention tooling example",
"main": "index.js",
"repository": "git@github.com:minsooshin/codeConventionTooling.git",
"author": "Mason Shin <js.mason.shin@gmail.com>",
"license": "MIT",
"devDependencies": {
"babel-core": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"eslint": "^3.19.0",
"eslint-config-airbnb-base": "^11.2.0",
"eslint-friendly-formatter": "^3.0.0",
"eslint-plugin-import": "^2.2.0",
"eslint-watch": "^3.1.0"
}
}

Set babel configuration

To use ES6 syntax, let’s create .babelrc file under the project root directory. Then, add these lines.

1
2
3
4
{
"presets": ["es2015"],
"plugins": ["transform-object-rest-spread"]
}

Initiate Eslint

Now, we can setup our eslint configuration with installed package. Run this command on your terminal.

1
$ ./node_modules/.bin/eslint --init

It will propmt this question to you.

1
2
3
4
? How would you like to configure ESLint?
❯ Answer questions about your style
Use a popular style guide
Inspect your JavaScript file(s)

Select Use a popular style guide, then next question will be this.

1
2
3
4
? Which style guide do you want to follow? (Use arrow keys)
❯ Google
Airbnb
Standard

I use Airbnb most of cases. So, I will select Airbnb, then next.

1
? Do you use React? (y/N)

If you are creating React app, then type y, but I will type N in this example since I am not creating React app. Then, you will see the last question.

1
2
3
4
? What format do you want your config file to be in? (Use arrow keys)
❯ JavaScript
YAML
JSON

I am using JavaScript format for the eslintrc, so it will generate .eslintrc.js file for me.

NPM Scripts

As you know, we need to set up the npm scripts to execute our expected behaviors in the package.json. Open the package.json file, and add "scripts" property above the "devDependencies".

1
2
3
"scripts": {
"eslint": "./node_modules/.bin/eslint src --ext .js"
},

Once you have this in your package.json file, you can validate your JavaScript files under src directory with yarn run eslint command. If you are using npm, then use npm instead of yarn.

Example Code

I will create an JavaScript file which exports simple funciton returns the input array has duplicates or not.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/containsDuplicate.js
/**
* @param {number[]} nums
* @return {boolean}
*/
export default function containsDuplicate (nums) {
const seen = new Set()
for (let i = 0; i < nums.length; i++) {
if (seen.has(nums[i])) {
return true
} else {
seen.add(nums[i])
}
}
return false
}

Once you saved this file, let’s execute the command for validate code.

1
$ yarn run eslint

You will get this result from the command.

1
2
3
4
5
6
7
8
9
10
11
12
13
yarn run v0.24.4
$ ./node_modules/.bin/eslint src --ext .js
/Users/mshin/Workspace/github/codeConventionTooling/src/containsDuplicate.js
5:42 error Unexpected space before function parentheses space-before-function-paren
6:25 error Missing semicolon semi
7:36 error Unary operator '++' used no-plusplus
9:18 error Missing semicolon semi
10:12 error Unnecessary 'else' after 'return' no-else-return
11:24 error Missing semicolon semi
14:15 error Missing semicolon semi
✖ 7 problems (7 errors, 0 warnings)

Each error has the error name on it, so you can find out what the error is for from the Eslint website.

If you don’t want to have the rule which is Airbnb based, you can disable it by adding the rule disabling in the .eslintrc.js file. For example, I usually don’t use semicolon(;) at the end of the line, so I will add this in my .eslintrc.js. The reason why I don’t use semicolon in my code is when I compile the production package, it can be automatically add semicolons.

1
2
3
'rules': {
'semi': [2, 'never'] // this is equivalent to 'semi': ['error', 'never']
}

Let’s try again our command for validate code. Now, we will get this.

1
2
3
4
5
6
7
8
9
yarn run v0.24.4
$ ./node_modules/.bin/eslint src --ext .js
/Users/mshin/Workspace/github/codeConventionTooling/src/containsDuplicate.js
5:42 error Unexpected space before function parentheses space-before-function-paren
7:36 error Unary operator '++' used no-plusplus
10:12 error Unnecessary 'else' after 'return' no-else-return
✖ 3 problems (3 errors, 0 warnings)

So, all the semicolon issues are gone. Woohoo!! Let’s take a look at the no-plusplus issue. That ++ unary operator is used in the for loop, and it is quite common usage, so I wouldn’t like to change my code due to this error. I will add this line to .eslintrc.js based on the instruction of no-plusplus rule page.

1
"no-plusplus": [2, { "allowForLoopAfterthoughts": true }]

If you want to keep the default rule and only ignore on a file, then you can disable the rule on specific error.

1
2
3
/* eslint-disable no-plusplus */
for (let i = 0; i < nums.length; i++) {
/* eslint-enable */

Let’s fix other two errors in the code, not updating rules.

Finally, we get this result from our validation.

1
2
3
yarn run v0.24.4
$ ./node_modules/.bin/eslint src --ext .js
✨ Done in 0.68s.

And the final our containsDuplicate.js file looks like this:

1
2
3
4
5
6
7
8
9
10
export default function containsDuplicate(nums) {
const seen = new Set()
for (let i = 0; i < nums.length; i++) {
if (seen.has(nums[i])) {
return true
}
seen.add(nums[i])
}
return false
}

How easy it is!!! Let’s commit changes to move on to Travis CI integration.

Travis CI

Github supports integration with Travis CI only for the public repositories. So, your repository should be public to use Travis CI for free. Before the integration, please sign up the Travis CI with your Github here.

Once you log in Travis CI, you will see this menu on the screen.
Travis CI menu

Click on the + icon, then it will show all your Github repositories. Then, click the Sync account button at the top right corner of content, and turn on the codeConventionTooling repository for the CI. I will add the Travis CI badge to my repository to see more easily about the eslint status.

Go to the repository’s Travis CI configuration by clicking the cog icon next to the repository name. Click the badge icon, then you will get a dialog box. Please select whatever you like as format. I usually use markdown format.
badge selection

Copy the contents in the textarea, then paste it to your README.md

Next, we need to add a file to integrate the Travis CI with our repository. Create a file with .travis.yml name, and add these lines.

1
2
3
4
5
language: node_js
node_js:
- "6"
script:
- npm run eslint

That is it! Once you commit your change, you will see the Travis CI is triggered. And if the code validation is succeeded, your commit will have green checkmark next to the commit message.

After passing the code validation

Finally, you can see the Travis CI passing badge.

Passing Badge on README

Share Comments