Release 0.3a: #telescope-in-motion - Is it possible to avoid coding style conflict in big project?

Last week I mentioned project Telescope in my post about my upcoming plan for contribution to open source. It is amazing looking at it right now and see that, at this exact moment, there are 113 PRs solving 138 issues (and still counting) in the repository. I am happy to be 1 of contributors, too.

My contribution is about integrating tools to uniform and enforce coding styles and practices to the project. This would solve a few current problems such as:
  • Indentation type and size mismatch - 1 tab vs. 4 spaces and 2 spaces vs 4 spaces
  • Newline character mismatch - Windows CRLF (\r\n) vs. Linux LF (\n)
  • Naming convention mismatch - Camel case vs. snake case (underscore-separated)
  • Anonymous function form mismatch - function() { } vs. () => { }
  • Inconsistent (or bad) code formatting in general
  • and many more...
in the project to which there are a large number of developers contribute.

The tools I mentioned are not completely unfamiliar in any way, they are the combination of ESLint, Prettier and EditorConfig.

Besides that, the project is also configured to adopt Airbnb's JavaScript coding style. This greatly improves code readability and helps developers effectively avoid many common bugs. Therefore, it is favoured by many developers around the world.

But why do we need all 3 tools?

Ok, let's be honest, we hate adding more dependencies/plugins to our project. Then, why do we even need 3 only for code styling? I am glad that you ask!

The answer is that each of them takes on different responsibilities (though not without overlap on each other, unfortunately), specifically:
  1. Prettier:  This tool is a powerful code formatter. It receives our code as input, generates a syntax tree and outputs the "prettified" version of the code. We can define our coding style such as 4 spaces indentation, line-ending with CRLF, each statement per line and strings must be used in single quotes... etc.
  2. ESLint: This tool is a very popular linter for JavaScript. Its job is to point out which part of the code does not align with the predefined guidelines (of Airbnb in this case) or is a bad coding practice. Also, ESLint does check for and allow configuration of code format.

So, what differentiates ESLint tool from Prettier?

Short answer is that Prettier worries about code appearance and ESLint worries about code quality.

While Prettier only looks at the format of the code and nothing further, ESLint looks deeper into the semantics of the code. It can see (common) "things" that is ok but might lead to a bug later. Examples would be:

And one of my favorite:
In addition to the 2 tools above, we also have:
  1. EditorConfig: This tool simply overwrites the developer's editor configurations based on a config file and does not effect the code the developer writes in anyway. We need this tool although we have ESLint and Prettier because if the editor's configuration does not align with ESLint or Prettier, during the process of writing code, the linter will continuously shows error signals indicated by red underlines. Though this can be easily fixed by linter or prettifier later on with 1 click or command, it is best to avoid in the first place.
An example of a potential behavior of any project integrated with ESLint but without EditorConfig:

Integration Process

Integrating the tools into project is easy. Making them working together in harmony, especially ESLint and Prettier, is a bit trickier. Thank to an article here from the professor, I am able to accomplish the task.

After the integration, all the job of code format checking are delegated from ESLint to Prettier. ESLint only checks for compliance of code-quality-related rule. An example of ESLint config file after the task follows, you can notice that it does not contain rules about code format:
module.exports = {
    extends: ['airbnb-base', 'prettier'],
    plugins: ['prettier'],
    env: {
        jest: true,
        browser: true
    },
    rules: {
        'prettier/prettier': ['error'],

        /**
         * Disallow Reassignment of Function Parameters
         * https://eslint.org/docs/rules/no-param-reassign
         */
        "no-param-reassign": ['error'],

        /**
         * Disallow Assignment Operators in Conditional Statements
         * https://eslint.org/docs/rules/no-cond-assign
         */
        'no-cond-assign': ['error'],

        /**
         * Disallow Unnecessary Semicolons
         * https://eslint.org/docs/rules/no-extra-semi
         */
        'no-extra-semi': ['warn'],

        /**
         * Require or disallow named function expressions
         * https://eslint.org/docs/rules/func-names
         */
        'func-names': ['off'],
    }
};
and example of Prettier config file which stores only rules about code format:
{
    "printWidth": 100,
    "singleQuote": true,
    "endOfLine":  "lf",
    "tabWidth": 4
}
The EditorConfig config file stores the list of configuration entries to be overwritten, these setups has to align with the setups above or there will be error signals during the process of writing code as an exmaple above:
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Size 4 space indentation
[*]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
end_of_line = lf
insert_final_newline = true

# The indent size used in the `package.json` file cannot be changed
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
[{*.yml,*.yaml,*.json}]
indent_style = space
indent_size = 2
Now... I am sitting here, waiting for all the code from my fellow contributors to come in and I will worry about the styling part.

Conclusion

With the combination of the trio, code in big projects, especially open surce projects, would not have any major conflict in coding style. The software would be easier to maintained and transfered to other developer team if necessary.

Through this issue, I got to investigated an aspect in the process of creating software that I haven't looked into before. Not just with the use of the tool, thank to a lecture of the professor in class about Prettier, I also know how it is created and see the struggle without it in a project.

Comments

Popular posts from this blog

Release 0.1b: Contributing a new feature... Why not?

Release 0.1a: My First Contribution

Release 0.2a: #good-first-issue - Make web app work offline!