After 3 Months Of JavaScript Linting, It's Pretty Much All Pain And No Gain
Up until about 3 months ago, I had never used a linter. When we started InVision App, we played around with a coding style-guide; but, we quickly found out that no one stuck to it; and, frankly, we didn't have time to worry about it - we were just trying to get product out the door. Three months ago, I joined an internal team that uses the JavaScript linting library, Standard.js. After three months of trying to adjust to it, linting feels very much like it's all pain and no gain - a negative-sum scenario. And, the more code that I read through, the more I realize that the goal of consistency is a complete charade.
I want to say right up front that static-analysis of code is a good thing. It can help find bugs before you deploy code, through features like unused variable and dead code detection. That stuff is awesome, no doubt. When I talk about "linting", I am not talking about those features - I am talking solely about stylistic rules. Tabs vs. Spaces. Const vs. Let. Single quotes vs. Double quotes - that sort of thing.
That said, my approach to code formatting is the best. If it weren't, I wouldn't use it. Formatting is part of my being - an extension of my genetic makeup. And, when I write code, my formatting is the fingerprint that I leave behind. When I'm asked to change my style, I am - quite literally - asked to deny a fundamental Truth of my being.
|
|
|
||
|
|
|||
|
|
|
My coding style wasn't perfect on day one. And, twenty years later, it's still not perfect. But, today does represent the best that I've been able to come up with so far. And, as time goes on and I collect more evidence and experiment with new choices, my approach to code formatting will continue to evolve and become more refined.
Hopefully, you feel as passionately as I do about your own stylistic choices. My approach works best for me; but, it's not for everyone. And, clearly, other people's choices don't thrill me. It's a completely subjective matter.
NOTE: Years ago, I was naive enough to try and make an objective case for my design choices - I even used science. But, today, I now realize that, while there is some validity to my argument, personal preference is ultimately the source of Truth on such topics.
Trying to get people to leave their own approach - to give-up their own identity - and adhere to an arbitrary standard is painful. And, from everything that I can see, there's no real value in it. Because, the choices that can be controlled by a linter are, ultimately, not the choices that matter. The architecture of an application and the structure of its algorithms are what make an application readable, maintainable, and extensible. And, even on a team that uses linting, you will find wildly different choices being made by every engineer on this front.
|
|
|
||
|
|
|||
|
|
|
The reality is, linting doesn't make it easier to read and understand other people's code because code is so much more than indentation and quotation choices. It is art. And it is science. And, it's already hard enough. There's no need to make it harder by adding an additional layer of friction to the landscape of problem solving. Engineers are peacocks - you have to let them fly!
|
|
|
||
|
|
|||
|
|
|
Epilogue On Auto-Fixing Features
I am sure that many linting libraries, including Standard.js, come with utilities that allow you to auto-fix code. Meaning, convert your personal coding style to the one enforced by the team linter. This is not a solution. If anything, this is just more evidence of the absurdity of linting - that we have to create tooling so that our engineers don't have to feel the pain of linting as they work. If you're using an auto-fixing utility, I strongly urge you to step back and question what value you think it's adding to your project.
Epilogue On Copy-Pasta
I once heard the argument that linters make it easier to copy-and-paste code from one file into another. This argument defeats itself. Not only is copying-and-pasting a potential indication that said code should be factored out into a new concept; but, if you copy-and-paste code and you don't take the time to test it and assimilate it, that's not a linting problem, that's an awareness problem.
Reader Comments
Have you tried Prettier? At least then you can format on check-in and not worry about other people's style choices.
I can't help but feel like there would be an eslint config out there you would appreciate for catching a level of structural issues, yet only warn or be silent for stylistic things.
I'm on your side with this. I love more static analysis to make better code (which is why I also really enjoy Typescript) but linting to me never made a tone of sense. I understand the arguments for it, mainly because when i do see things stylistically different from mine, I do feel that urge to change them, but I also know they don't make much of a difference. I know that's just my personal preference. Or at least for a lot of the things you mentioned. I do think a style guide is important, but more the type of style guide like John Papa created for Angular, where "you can do it one of three ways, but this is the way we should do this".
I fully agree, that coding is art and code style is an expression of personality.
But still, I strongly support linting because it makes sense in teams. I don't want each single developer write his own personal code style. There is no code ownership, thus all code have to be the same style. Pick the style that you like, no problems. But it must be consistent. I value consistency over style -- and linting helps doing that.
@Frank,
I agree. The style that is enforced by linters ultimately does not matter. However, consistency does matter, particularly when working with a team. Complying with the linter can cause some friction, but it causes much less friction that team members arguing over style, or silently reformatting each other's code causing noise in the source history.
Const is not just a style choice. Sure, it results in the same code if you are compiling to ES5. But, it's actually informing the compiler or runtime (and readers of the code) that you do not intend to re-assign that variable.
I like linting tools, but I also work on a contractor heavy team. People come and go with no feeling of ownership to the code they write. The goal is clearly to close the ticket as fast as possible and to move on. Obviously their are some exceptions where people take pride in their work, but it is not the average case. An argument can be made where simple code review could solve the same issue, but the linting tools does provide some much needed constancy, allowing the code reviews to focus more on design then frivolous styles.
@Daniel,
I think you make a valid point, I've worked on projects where the exact scenario happens regarding contractors and ownership. Linting forces a default level of consistency in this scenario though my feelings regarding Ben's points are that it all really depends.
If you're dealing with a product and a team that's really invested in the project then maybe linting offers less than it rewards. But public sector projects are quite often contractor heavy and the teams and team members can change over time.
This is often compounded by the fact that we are in the era of the "full stack developer" and it's quite easy for someone with only a basic knowledge of the front end to work on large chunks of Js code. Obviously, the hiring process could be an issue here but contractor heavy teams are usually under tight deadlines hence why they are bulking up the numbers with a temporary resource. In this scenario, it's quite common for the hiring standards to become somewhat "flexible". In this case, a linter really helps stop some obvious mistakes from happening.
"I'm a special snowflake and my use of tabs next to everyone else's spaces is just my way of expressing my artistic soul."
I'm sure your coworkers love you.
@Joe, @Eric,
Standard.js is the only one I've tried, since I've only been on one team that enforces a linter. And with Standard.js, I don't believe you can change anything (ie, it's _the_ standard). It sounds like there are linters out there that are much more flexible. But, at the end of the day, I just think what works for me won't work for my teammate, and vice-versa. So, I am not sure how much flexibility actually helps.
Now, when I am on my own, I often use TypeScript, so I get the advantage of all the static analysis for catching errors, which is awesome!
@John W,
Yeah, I'm a huge fan of TypeScript. And, I'm a huge fan of the Angular style-guides, though I don't necessarily agree with everything they say. What I like about NG style-guides is that they also talk about general architecture, which I think it very helpful to agree on at a team level.
And trust me, I TOTALLY understand the urge to change code :D
@Ben,
In my experience I've found "standard" to be highly opinionated (and the airbnb one is also somewhat opinionated). With any eslint config, you can provide additional rules as overrides, but if you're in project/repo with shared settings, that could make people cranky. I personally tend towards a lightly modified version of Sindre Sorhus's eslint-config-xo-space, but that's because it matches more of my style of code.
I think the ultimate takeaway, especially for sharing configurations, is to pick something that generally works for everyone, otherwise it seems that there will always be someone who fights it / suffers through it.
¯\_(?)_/¯
@Frank, Tim B.,
Regarding this:
> ... causes much less friction than team members arguing over style, or
> silently reformatting each other's code causing noise in the source history.
I agree with that. Though, I suppose my hope is that no one will argue over style because it just becomes something that's not _worth_ arguing over. And as far as changing the formatting of existing code ... again, I sort of hope that is just something people avoid doing. Of course, if you are fixing a bug, or changing the functionality in a block of code, I don't take issue with reformatting that block of code. You're already in there monkeying around.
@Tim B.,
I'm just a "var" kind of guy. I understand that "const" is actually doing something different (and, it may even be doing something different at the compiler level); but, for me, it's just one more thing I have to think about, especially as I'm refactoring code (and having to change "const" to "var" when it gets stuck in a block-scope).
I like "var" cause it _just works_. And, if there is ever a truly hot path in the code and the compiler would make the code execute faster if a "const" were used, then I'd definitely consider it. But, I'd rather see some numbers first.
For me, "var" just makes life easier.
@Daniel,
Yeah, that's a tough situation. If people aren't going to have ownership / pride in their code, then sometimes you just gotta bring down the hammer. If linting can be that hammer for you, then I'm a pragmatist - I say use it :D
@John J,
Regarding:
> "I'm a special snowflake and my use of tabs next to everyone
> else's spaces is just my way of expressing my artistic soul."
.... to be clear, I would never mix tabs and spaces in the same file. I'm not a monster!
If I were to start a new file, I would use tabs. If I opened an old file, and it was using spaces, I would use spaces. The whole point here is to keep consistency that is _meaningful_ front-of-mind ... and to stop worrying about the rest. A file with mixed spaces / tabs is - I think without argument - harder to scan and understand.
You'll also see in my portion on Copy-and-Pasting, that I specifically talk about keeping things consistent within a file:
> ... but, if you copy-and-paste code and you don't take the time
> to test it and assimilate it, that's not a linting problem, that's an
> awareness problem.
Consistency is good, when it is good ... and painful when it is unnecessary.
@Ben,
It doesn't need to be painful, what editor are you using? In Atom and Sublime my files are automagically fixed up with my team's standard eslint config (airbnb+google with tweaks) for most trivial things while I'm typing. The only time I see warnings is when they're saving me from oversights that will either throw (like missing parens) or make my code misleading (I find var shadowing particularly annoying).
It kind of seems like you're running lint periodically instead of having it as live feedback. Linting should be a helpful guide as you're working not a hurdle to overcome on commit.
@Ben,
I agree that arguing over style is mostly pointless. However, I do prefer to keep the noise of reformatting to a minimum even when someone is modifying the code for legitimate reasons. That tends to make it much easier to see what's actually changed when you are reviewing code, or looking through history.
@Tim,
Totally agree! There's nothing more frustrating than seeing 400-lines of whitespace changes and ONE lines of logic change :( #TeamFail.
@John J.,
I get conflicted about trying to do the linting as I go vs. trying to do it at the end. Right now, I err for at the end so that there is some _extra_ degree of pain to it -- the hope being that the added pain will drill the rules into my head (so that my head can avoid them next time). This seems to work for some rules and not for others.
@Ben,
That seems so masochistic to me, and I get the mindset, but I'm not sure it's a fair trade.
The parallel that comes to mind for me would be like if I had ignored my wife's input while redecorating our house and then asked her opinion right before bedtime. She'd likely scoop my eyeballs out, and I'd certainly remember her response better, but the whole situation could have been a lot less stressful if I had let her help.
Spouses and linters aren't that dissimilar really, keeping up communication with both has improved my life at least lol.
@Tim & Ben,
If all the code was already in a set style why would massive whitespace changes even need to happen? A couple of people on my current team had this same resentment because eslint and Resharper would autoformat blocks, the issue resolved itself once we actually got everyone on board.
Also, most diff tools I've used have the ability to ignore whitespace changes.
@John,
That's what I am getting at though. Without a linter or other tooling to keep things in line, everyone tends to follow their own style, so there is no consistency across the code base. It's not always just whitespace.. there can be differences in wrapping, quotes (when talking JS), etc. that diff tools don't ignore. Like you say, if everyone just gets on board with letting the tool handle it instead of fighting it then you can stop worrying about it.
@All,
The PopMotion blog wrote up a response to this. I feel like some of my tone was misinterpreted (as is often the case with text-based communication). But, you may relate to the point-of-view:
https://popmotion.io/blog/20170803-coding-style-dont-be-a-dick/
Perhaps part of my point-of-view is that I've been on projects with no linting, that included many engineers, and I've not seen problems with it. People pretty much just get along and have a good time (as least as far as I know). So, it's possible I've just never been *burned* by not having linting.
@All,
In the PopMotion blog, it seems that I have come off combative. Just to be clear -- that was not my intention at all. If anything, my hope was just the opposite. I do say that I have the "best" formatting ... but, I follow by saying that I hope YOU ALL feel the same way about your OWN formatting. I know for a fact that most people don't care for the way I format (too much white space ... or some such nonsense ;P).
Also, if anyone misses the "peacock" reference, it was from The Other Guys:
https://www.youtube.com/watch?v=iV6539XsWrc
.... classic comedy gold!!
@John J,
Ha ha, nice analogy. The main difference, though, is that I'm trying to be an "interior decorator" as a living, not doing it as a one-time thing ... if I can extend your analogy :D
That said, the problem with anyone saying, "Well, if everyone uses the linter, then it's not a problem," is that you could just as easily say the same for the negation -- "If no one used the linter, then it's not a problem." If removal of friction is a selling point, then I suppose you can leverage it on either end.
Really, at the end of the day, the people who should be most blamed are the people who have automatic white-space trimming turned on their IDE :P
@Ben,
> the people who should be most blamed
> are the people who have automatic
> white-space trimming turned on their IDE :P
Haha, I've been doing this for the last 4 years :p Makes me wonder if I should turn it off, but the ocd in me hates trailing spaces.
This was an awesome post. While I can't agree with it all, I do get the sentiment behind it. I do find linting to be useful though, if not for others, at least for yourself. It helps keep my own code consistent without me having to think too much about it.