For some reason the Javascript code formatters available are kindof a mess. Here's what I've discovered.

Javascript Code Formatting Nightmare

June 10th 2021

Code formatting is often taken for granted in most languages. But it is not so easy to make a good formatter.

Back in the days of Adobe Flex, I remember someone in Brazil wrote a brilliant plugin for Eclipse that had an option for literally everything. It was amazing, you could customize the decisions for every possible thing you could imagine and then export or import the settings so that it could be shared across the team.

For Javascript the situation is not so easy. Part of the problem stems from the fact that a lot of Javascript code is transpiled. Transpilers can have different options enabled or disabled which means that the formatter needs to know which transpiler options are enabled or disabled in order to properly know how to parse the code.

If you introduce something like JSX or Vue.js it gets even more complicated. Consider a file like the following in Vue.js:

<template>
...
</template>
<script>
...
<script>
<style>
...
</style>

In this case, a code formatter needs to know how to properly style Vue.js templates (which do not strictly conform to HTML or XHTML standards), Javascript code with varying options for ES5 and ES6, and various types of CSS. For example, you can specify that your style is in CSS or SCSS. This means that a single formatter needs to be smart enough to work with potentially half a dozen different formats. On top of this, what if a codebase has a mix of TypeScript and ES5 and ES6? What if someone decides to use some CoffeeScript? What if someone also wants to integrate some web assembly?

So what we end up with for something like Vue.js is a complex scenario where you cannot just install a "code formatter", you would need to specify dozens of options. And if the formatter runs into some lines of code that are using an obscure rule in the Babel transpiler, like asynchronous imports, the standard syntax is not what it expects.

Typically a good formatter will use a parser to build up an AST (abstract syntax tree) of the code, and then pass the AST back through the formatter to output new text. However, this means that the formatter would need to have access to the AST for Babel, for example. This might be available to some extent, but it also means that potentially the formatter would need to know all of the options specified in various configuration files (e.g. Webpack + package.json + babelrc). It could offload this to the Babel transpiler, but I have not dug into this enough to know how much access they provide to third parties that do not intend to actually transpile the code.

Long story short: code formatting for Javascript is a nightmare.

Prettier

One classic option is Prettier, which works fairly well for basic Javascript. However, it is rather opinionated. It gets more complicated if you want to integrate Prettier and ESLint, as the options you can specify end up rather obtuse and buried in JSON or Javascript files.

Not to mention, there are obscure bugs in Prettier that I have found that make it especially difficult when working with JSX or Vue.js templates. In some cases, people on Stack Overflow have even suggested just abandoning Prettier because some of the bugs have been dormant for over 4 years without a fix in sight. There are workarounds, but quite frankly at this point one has to wonder whether it would just be faster to avoid a formatter at all rather than fighting issues like this.

ESLint

ESLint can do some formatting, but again it has some of the same problems we discussed at the beginning. You have to install plugins for every deviation from standard Javascript you use. You might end up with your code littered with comments specifyign that "well, normally we want ESLint to spot this error, but for this line only we want to disable this ESLint check". Quite frankly, this means you end up writing comments that are technically required in order for a build to pass. In other words, you now have comments that are code.

JSLint and Others

There are a few other options, but from what I have seen they are not maintained well. JSLint was apparently abandoned in favor of ESLint - or merged in. Not sure of the history. But in any case, it would be a sad state of affairs to adapt a codebase to a poorly maintainted formatter.

Conclusion

I think that it is probably just easier to avoid a formatter for most Javascript projects. The exception would be something like TypeScript, where there is a more strictly defined modern syntax. Quite frankly, this entire debacle has me wondering if switching to TypeScript might be worth it not just for the strict typing but also for the formatting capabilities. However, I have found reading through TypeScript definition files to be quite frustrating and it means the simplest code now requires more time to develop, and I am not sure it actually leads to much gains, since you then have a compiler that is slower.

Basically, I would love an awesome formatter setup for a classic Javascript ES6 project but have found it quite troublesome, with tons of digging through Stack Overflow posts and whatnot, to resolve all the issues.