The Code Etymologist is a multi-part series that covers typical software knowledge that deserves to be documented and shared within development teams.
- Preface
- Part 1: Project setup
- Part 2: Coding guidelines
- Part 3: Development workflows
- Part 4: Product requirements
- Part 5: UI Components library
- Part 6: Data structures
- Part 7: Technical decisions
- Closing thoughts
As soon as we have the project running locally, we can get to actual work and start coding. However, every team has its own coding style, practices, and standards, regardless of whether they are written somewhere or not.
The question is, "How can we discover these guidelines as new team members?". In case there's no written documentation, we'll most likely discover them during code reviews.
To avoid repeating the same comments to different team members, writing down repeating (anti) patterns, along with explanations of the problem and solution examples, can eventually become the internal coding guidelines document. Some examples of such documents include:
Some guidelines like naming conventions, the use of code comments, error handling, or using early returns require manual effort and code review and cannot be enforced through tooling.
However, there is a vast set of guidelines, both stylistic and functional, that can be easily enforced through code formatters or linters.
Code formatters
Code formatters like Prettier or Biome truly impacted our development cycle. Instead of manually spending time to align and indent code blocks, managing spaces and newlines before or after curly braces, having endless disputes over tabs vs spaces or single vs double quotes, we let the tools handle all these stylistic concerns automatically in milliseconds.
And all it takes is a simple configuration file that we need to define, to ensure every team member will use the same set of rules for code style. It's worth mentioning that the formatter will use the project-level configuration instead of a global one, therefore different projects can have different configurations.
There are multiple ways to use code formatters. We can either run them:
- Inside our code editors and configure them to always format when we save the file. However, this is not a guarantee that all team members will properly configure their code editors.
- As a pre-commit hook, before pushing code to the central repository. But even this approach is not 100% bulletproof, as we still rely on local git configurations, which can ultimately be bypassed.
- On our continuous integration solution, to either verify that the code is properly formatted or perform automatic formatting as well. This centralized approach offers the highest degree of confidence to prevent malformed code from being merged.
Linters
Linters, on the other hand, such as ESLint, Biome or Stylelint, provide deeper static analysis to detect broken coding rules, or even potential errors.
Most coding guidelines can be easily enforced using linters. We can start from a recommended predefined configuration and customize it to suit our own preferences.
We can use linters in various ways:
- Integrate them in our code editors.
- Run them as a pre-commit hook.
- Use the command line interface to lint code in our CIs.
Custom rules
Sometimes the predefined rules bundled in linters are not sufficient. Sometimes it helps to add project-specific custom rules to enforce certain practices. Some examples include:
- Preventing deprecated imports is a useful technique, especially during code migrations. The
no-restricted-imports
rule allows us to define forbidden imports and provide custom messages to instruct team members what to do instead. - Implementing architectural boundaries to prevent certain folders from depending on others is helpful to maintain a structured file hierarchy. The
eslint-plugin-import
is built exactly for this purpose.
Editor extensions
We all have our own preferred code editor plugins to aid us during development. At some point, certain plugins become de facto standard in our team. Ideally, we would like all team members to have a particular set of plugins installed.
Instead of providing a list of links in written documentation, VSCode provides a way to define recommended extensions for a particular project.
{
"recommendations": [
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"esbenp.prettier-vscode",
"aaron-bond.better-comments",
"mikestead.dotenv",
"axetroy.vscode-npm-import-package-version"
]
}
Adding this file to the repository will prompt the team members to install the recommended extensions. It's not mandatory, we can simply ignore it, or we can install a subset of the recommendations.
Continue reading Part 3: Development workflows