DEV Community

Cover image for Coding Style Guide: A Practical Guide to Writing Clean Code
Mohsen Karami
Mohsen Karami

Posted on

Coding Style Guide: A Practical Guide to Writing Clean Code

Over the last five years, I have been constantly attempting to improve my coding skills, and one of them was learning and following the most recommended coding styles.
This guide aims to help you write consistent and elegant code and includes some advice to improve the code readability and maintainability. It is inspired by the most accepted popular guidelines within the community but has some modifications to fit more suitably to my preferences.
It is worth mentioning that I am a full-stack JavaScript developer, and all my notes are specific to my tech stack (MEVN) and may not be applicable to other stacks.

General Rules

Avoid code duplication

If there is a need to write the same code block (or with some manageable differences) in more than one place, it is essential to merge them into a function and, hereafter, call the function whenever needed.

Consider loose coupling

Functions should work independently, meaning that editing one should have absolutely no effect on the others as long as the input and outputs remain the same. Each function should have no knowledge of definitions of the others and work as a separate component. In this situation, all it knows is its parameters, and no matter who calls the function, the same inputs always return the same results.

Declaration

First and foremost, remember to declare the variables all the time.
Use the const keyword when a variable is not going to be reassigned. However, you can still use const for variables that are objects or arrays, even if you plan to reassign their nested elements.
Please note to require modules and define constant variables always using const keyword.
Use the let keyword when you can not use const, and only use the var keyword if you need to support older browsers.

Functions

Functions should be limited to the following:

  • Four variables
  • Four parameters
  • Thirty lines of code (ignoring comments)
  • Four branches (if-else, while, for, or-and, switch-case)

Code lines should be limited to 100 characters, and in order to group/organize the functions, it is better to keep the related functions close to each other as much as possible.
Privilege the arrow function syntax to the traditional alternative whenever it's possible.

Strings

Use single quotes ' (rather than double quotes ") for the ordinary string literals, but for strings with embedded variables/expressions, multiple line strings, and strings that contain single quote characters, use template literals.

Naming

It's essential to maintain consistency when naming variables. It means that if variables on different pages are responsible for the same data, they should have the same name.

The names of variables, functions, methods, and parameters should be self-descriptive, meaning anyone should be able to know (or at least make a fair guess) about the contained data just by looking at their names.

Constant variables should be in uppercase, with words separated by underscores. Functions, variables, and methods should follow the camelCase syntax, while CSS classes and ids should follow the kebab-case syntax.

Comments

Comments should always start with an uppercase letter and be limited to 100 characters. You might remember that the code lines would follow the same rule, but note that if lines include both, they can only exceed up to 150 characters.
Comments describing the functions should not be written where they are called but where they are defined.

Place the comments after the one-line codes unless the line's length exceeds 150 characters. In such cases, and for multi-line codes, put the comments at the top.

Regarding the if statements, the comments should be placed after the conditional statements.

if (conditionIsTrue) { // Put your comment here
    doSomeThing();
} else { // Put your comment here
    doSomethingElse();
}
Enter fullscreen mode Exit fullscreen mode

Remember to use double slashes // for one-line comments and /* */ for multi-line ones. When adding multi-line comments to one-line code or conditional statements, place them within /* */ so that /* is written in front of the code, the comment starts on the following line, and */ is written on a new line.

if (conditionIsTrue) { /*
        Put your comment here
        Put your comment here
    */
    doSomeThing();
}

functionName(parameter), /*
    Put your comment here
    Put your comment here
*/
Enter fullscreen mode Exit fullscreen mode

Function descriptive comments

Place the comments on top of the functions wrapped by /** */.

  • Describe parameters using @param {type} variableName description.
  • If the parameter could accept more than one variable's type, use @param {type1 | type2} variableName description.
  • If the parameter is optional and could be absent, use @param {type} [variableName] description.
  • If the parameter has a default value (it must be optional to could have a default value indeed), use @param {type} [variableName="value"] description.
  • Describe the function output using @returns {type} description.
/**
 * Describing the function here
 * @param {type} normalVariable A normal variable
 * @param {type1 | type2} multiTypeVariable A variable with multiple expected types
 * @param {type} [variableWithDefaultValue="value"] An optional variable that has a default value in case of being absent when calling the function 
 * @param {type} [optionalVariable] An optional variable
 * @returns {type} description
*/
const functionName = (normalVariable, multiTypeVariable, variableWithDefaultValue, optionalVariable) => {
    doSomeThing();
}
Enter fullscreen mode Exit fullscreen mode

Regarding server functions with req and res parameters, there is no need to describe request parameters; only describe the response using @returns description.

/**
 * Describing the function here
 * @returns description
 */
functionName = (req, res) => {
    doSomeThing();
}
Enter fullscreen mode Exit fullscreen mode

Generally, there is no need to describe the req, res, next, to, and from parameters.

In HTML files, use <!-- description --> to separate different parts of the code; hence the user could identify each part easily.

In case you write comments in the middle of a line of code, use /* */.

const calc_result = (firstNumber * secondNumber)/* Explain the reason for the multiplication */ + thirdNumber;
Enter fullscreen mode Exit fullscreen mode

Indentation

Trailing whitespace is forbidden.
Remember to always put spaces around expressions, operators, and symbols, and also after commas and curly braces, if they are not the last characters of the line.
Empty lines are only allowed (and required) at the end of the file (all files should end in an empty line), after the last imported module, separating Template, Script, and Style tags, and between CSS rule sets.
Remember to use Tab for indentation and Space for alignment.

Order

  • Order variables of the mongoose schemas and the Vue Reactive State of the components in alphabetical order, but for the rest of the time order the lines from the shortest to the longest.
  • Order the route methods in the order of put, get, post, and delete, while each itself is in alphabetical order, and all routes should be grouped based on their URLs.

Wrap-Up

While obviously, these are not the best advice ever, I believe they offer a solid starting point for anyone interested in learning clean code principles.
Moreover, although strictly adhering to these rules might initially seem challenging, it becomes much more straightforward with practice.

It is essential to emphasize the necessity of sticking to the current project's guidelines when working on a long-term codebase, even if they are insufficient. If you are serious about revisiting the project's guidelines, consider the most beneficial modifications and let them be injected into the project gradually.

Cover image credit: Photo by luis gomes from Pexels

Top comments (0)