JS code quality starter pack: linters, conventions, best practices
This article is about my view to convention building.
It includes some basic examples including linting tools setup.
That can be interesting for developers who like to follow coding best practices and who want to improve their own or team code quality.
As for me, I've explained and use those concepts many times. So, putting them into article will be handy.
First of all you can look at my linting guide with the linter pack setup here.
Also you can grab my article from git repo here.
What is it for
- Put and keep things in order together.
- To make productivity a little bit higher, and also reduce the volume of work.
- Conventions supports convenience of:
- migration. Facilitate the process of transferring the code between an old and new design / framework.
- debugging. Look at debug/dev tools and understand from which file this piece of code is, and where it can be inside the file.
- reading. Reduce the time for searching and analyzing information. The code units naming should help to immediately understand what it should do.
- development. Use generally(framework) accepted patterns and practices.
- communication. Reduce the length/duration of actions chains and loops(ping-pong)
How to make it
- Conventions should respect team's/framework's abilities and limitations.
- Conventions is always a compromise. You should learn how to do that before doing conventions.
- Compromise is based on the trust, and that's based on the respect and responsibility.
- Respect yourself and others results of the work and time which has been spent.
- Prepare and make discussions well:
- reduce the number of participants
- make and read agendas
- convert feelings into real facts and stories
- speak in plain English, avoid using abbreviations
- draw trees with facts decomposition
- write a summary and apply the decisions
Rules for the PR reviewer
- reduce the number of reviewers
- More than one can be the cause of duplicated work and time spending while one of them/you out of work or busy
- If more than one participants is necessary, you should divide the code for each reviewer
- check all code at once, reduce review-fix(ping-pong) time spending
- switch into PR branch
- execute and test at least one main functionality of the PR, prevent moving PR to QA engineers with silly issues like "forgot to run
- check the:
- unit test code coverage
- code convention compliance
- code complexity
Rules for the PR author
- Less code means less:
- merge conflicts
- reading time
- Do not shorten unit's names or line breaks:
- Long names and line breaks reduce analysis time and bugs count.
- Minifier will remove them anyway.
- describe PR's scope in a task to help make the review and a test better:
- modules/components or domain areas which have been modified
- new functionalities were added and where
- reduce the PR's scope, make a new subtask/story for:
- broken/disabled(xit/xdescribe) unit test
- optional parts of functionality/refactoring
- investigation and description(making notes/readme's) of how old code is working
- execute before the pushing into repo:
- reformat and auto fix all code using prettier, eslint and stylelint rules
- git pull && git merge origin master
- npm run lint
- npm run build
- npm run test
Rules for code quality
- make functions private as much as possible
- use camelCase
- remove an unused code
- reduce the code complexity:
- nested braces depth
- else blocks
- lines length
- lines per function
- params count
- make names readable like:
- put notes to share your knowledge
- The code describes how things works, and your notes describes why or what for
- One short note can prevent hours of investigation or days of rewriting code back and forth
- Put comments in one line, after the code not to increase lines number
- Put jsdoc in one line not to increase lines number. In popovers they are automatically reformatted.
- Put long notes in readme files: usage examples
- make separate unit test assertion for:
- every input option
- every output value
- every possible state: init, loading, disabled, broken(reproduce exact issue), valid
- add in every unit test not only the final state, but state transition: before/after loading, before/after issue fixing