Considerations on linteners
I was reading an article by Shawn Wang about eslint
and prettier
explaining the setup and how to deal with the details and I’ve got a couple of considerations.
The main point is that these tools introduce a little bit of disruption in our workflow. Let’s call them interrupts. And these interrupts can be quite fatal.
What does that mean? It means you’re coding, you want to fix the thing, you’re just™ exploring some possible solution, you save the file and BAM! Suddenly all your screen is red because you copy-paste dots instead of tabs or similar.
Now your focus is gone.
And that’s a disaster for your productivity. At that moment you’re just™ looking to solve the problem, and you want to explore, you want to be fast.
I bet some of these tools are always in between you and the solution you’re looking for.
In those moments they are not working for you. They’re against you, stopping you, punishing you on any ctrl+s
.
So, the first consideration is about speed and interrupts.
When these tools should run?
I guess one core principle is that uninterrupted speed is a good thing. It lets you focus. And linters are good too, but nice to have. Secondary in a way. The code is still working even if I use dots instead of tabs (mostly).
So, I would give more priority to speed and exploration than the linters.
Well, when then?
I think they should stay in a place in which they don’t disrupt the flow.
Thus, definitely not on save file, because it breaks your exploration mode. And not on commit neither. As I can imagine someone in exploration mode coding, committing, coding.
I would say a good compromise probably would be before pushing.
That’s because you’re finished with your chunk of changes, you’re ready to do your PR — It still gives you some interrupts, but it saves you to get back, polish the code, commit and push the update on the PR.
In the article was mentioned husky
which is a good fit for the job I think. pre-push
should do the rest.
Quick setup notes
# on V6
# if using npm add "prepare": "husky install" in scripts
npm install husky --save-dev
npx husky install
npx husky add .husky/pre-push "npm run lint"
Another consideration is where to put the linteres.
Most of the times I saw them as a plugin in webpack
, grunt
, gulp
.
That plugin, to me, feels like something else that can break.
Something that can cause trouble later on.
Let say when you want to update the task runner/bundler and the plugin is not there yet. Or maybe you want to switch the task runner/bundler itself for something else and porting that plugin is something more to take care of.
So, for this reason, I think that a more conservative/robust solution would be to use the lintener via cli through scripts
in package.json
.
An inspiring example for me is package.json
in Bootstrap.
I like the way they’ve got in there using "lint": "npm-run-all --parallel js-lint css-lint lockfile-lint",
using npm-run-all
to bundle together several linteners.
Other benefits of having the setup in package.json
are that you can run it manually if you feel to and it’s kind of orthogonal/independent from the rest of the system; which makes it more portable in a way.
Let say you want eslint in another project. You npm install it, copy the script line, and you kind of ready to go.
Note
Probably the interrupt/exploration mode consideration is true in some part for ts
and other linteners as well (eg: stylelint
).