DEV Community

Majd Al Mnayer
Majd Al Mnayer

Posted on

Clean Code: Open Source Linting & Formatting

For this week, we were tasked to choose a linter, a formatter, and to add a CONTRIBUTING.md file for our project!

Personally, I always consider adding a formatter and a linter to be one of the most essential first steps before even starting to work on a project. I set them up weeks ago because I simply cannot work without following the standards. However, I will discuss them in detail, why I chose what I chose, and how I set them up.

Formatting

For formatting, my go-to is always the beloved Prettier package/extension! This was introduced to me first in the Cloud Computing for Developers course I took with Professor Humphrey last year.

Prettier is a wonderful tool that automatically formats your code based on some guidelines set in its config file. For example, here is the .prettierrc config file I use for OptimizeIt:

{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 80,
  "endOfLine": "auto"
}
Enter fullscreen mode Exit fullscreen mode

While Prettier does have its default rules, you can add your own rules in this file. Personally, I asked it to always include a semicolon at line endings, use single quotes ('') instead of double quotes ("") where applicable, and apply some other settings!

This tool helps a dev team, a company, or a department establish its own standards and guidelines for writing clean and maintainable code.

Prettier can also be configured to automatically format on file save! This can easily be done in Visual Studio Code by simply going into the settings and enabling the option. It can also be done in many other IDEs!

I also provided a script to run Prettier manually:

npm run prettier
Enter fullscreen mode Exit fullscreen mode

Linting

For linting, my go-to is usually ESLint. Unlike formatting, which is meant to keep your code clean and readable, linting helps detect issues in your code, such as unused variables, attempts to change an immutable variable, and many more. ESLint is my go-to because I always use Airbnb's ESLint Configurations in my projects. ESLint allows you to set many rules for your source code, such as using a specific naming convention, forbidding vanilla for-loops, or prefix and postfix operators, restricting single exports in a file to export default, and many more.

The reason I always use the Airbnb ESLint Config is that it's widely regarded as one of the cleaner and more efficient ways to write code. Many smart people spent countless hours carefully choosing the best rules to follow, and which to avoid, and placed them all together in that config file, which is used by millions of projects every week!

However, ESLint is slow. It takes time to run and fix issues, particularly in large projects. I wanted to try out something I hadn't used before for this lab, since I had already implemented the formatter and the linter weeks ago. I tried Oxc, which is a JavaScript linter that is Prettier-compatible and ESLint-friendly, written in Rust.

Installing this tool was pretty straightforward, and I was really excited to see its performance given that it's written in Rust, and on their official website, they boast about how much faster their tool is than alternatives.

Not only was this tool fast, easy to use, and efficient, but it also displays errors in an incredibly intuitive way! It clearly shows what is wrong, what rule was broken, and how to fix it clearly! Unlike ESLint, which doesn't show as much detail about what went wrong.

The documentation also mentioned an ESLint plugin so that Oxc works with ESLint, that I simply injected into the ESLint config file eslint.config.mjs.

Here is an example of an error caught by Oxc, just look at how elegant and clean it is, it has colors too!

Oxc Error Example

I also provided a script to run linting manually, which runs both Oxc and ESLint:

npm run lint
Enter fullscreen mode Exit fullscreen mode

Pre-Commit Checks

Once both linting and formatting were set up, I wanted to dig in and see how to run both linting and formatting before a commit is made! This is something I hadn't done before, and I didn't know where to start or what to look for. My first approach was to go to Google and search "pre-commit command run packages npm". However, I didn't get very far doing that.

My second approach is to always ask ChatGPT to do a Bing (I wish it was google too, believe me) search for me and find tools that fit my criteria. And it did! I was recommended two packages, Husky and lint-staged, which work together! Husky is a package that provides ultra-fast modern native Git hooks, and lint-staged is a tool that allows running linters against staged Git files!

Once I knew what tools to use, I delved into the documentation, which was surprisingly very easy to follow. I simply had to install Husky, lint-staged, and update the Husky pre-commit script to run the lint-staged configuration I made before a commit is made!

For context, this is my lint-staged configuration for OptimizeIt:

{
  "lint-staged": {
    "*.{js,ts,json}": [
      "prettier --write",
      "eslint --fix",
      "npx oxlint --fix"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

For my config, I require formatting and linting for all JavaScript, TypeScript, and JSON files!

And it worked like magic. I tested it in different scenarios. Whenever a commit is made and a violation occurs, I get an error in my IDE with a button to check the logs. In the logs, there is detailed information about what issue happened, why the error occurred, and everything we need to solve the problem!

Results

Now, the reason I did not encounter any linting or formatting issues when I ran the scripts is that I had them installed several weeks ago. However, even when I am developing, I rarely encounter ESLint issues, mainly because I have been working with it for a while and I know how it works and what it violates. Although, encountering ESLint issues is very normal when working on new projects with different rules, and we as programmers have to simply follow these rules to provide the cleanest, most error-free code possible.

What I loved the most this week was learning about pre-commit linting and formatting. This was something new for me, and I honestly thought implementing it would take quite a while, that I'd have to work with shell scripts and other Git configurations. However, it turned out to be much easier than I thought!

Overall, these steps are extremely essential, and I believe that formatting and linting should be the very first things introduced in a project, to avoid issues if implemented later on.

Top comments (0)