mocha
mocha copied to clipboard
Repo: Move to neostandard instead of ESLint recommended
Perhaps we could go with https://github.com/neostandard/neostandard as a base? Considering that
semistandardwas what was used before #5060 andneostandardnow is an option?
Originally posted by @voxpelli in https://github.com/mochajs/mocha/issues/5281#issuecomment-2567383082
Copying https://github.com/mochajs/mocha/pull/5282#issuecomment-2729360932:
@voxpelli I don't see why we need to block this in the meantime. Are there specific lint rules from the ESLint recommended set that you don't think we should enable?
I personally don't like big conglomeration projects like neostandard. I find them to conflate logical rules with stylistic ones, and obfuscate the differences by presenting a single unified config area. I might not be correct and am certainly open to the discussion - but I think there's going to be back-and-forth on whether to use neostandard.
If anything, I would think enabling the ESLint recommended rules would help onboard to neostandard, no? Either:
- (my understanding) ESLint recommended is a subset of neostandard, so this will reduce the cost of moving to neostandard
- ESLint recommended isn't a subset of neostandard, so these rules are presumably additional usefulness
Separate from the discussion of whether to enable ESLint's recommended in the meantime, I'd like to hear more on what the benefits of neostandard over vanilla ESLint-core + typescript-eslint are. Who better than @voxpelli to advocate for the project? 😄
A PR is up in #5302
As for why:
- See https://github.com/neostandard/neostandard#mission-statement
- Used by many large node.js projects and even more if one count
standard(which eg. has even more GitHub stars thaneslintitself does) - Has extensive compatibility / canary tests (more extensive than most eslint plugins has) that has showed to catch regressions in the eslint ecosystem ahead of time and as such has been able to catch and shield users of
neostandardfrom regressions (see eg. https://github.com/neostandard/neostandard/pull/230) - And also: It was what was used before https://github.com/mochajs/mocha/commit/8317f902a11a5837d00581e7926b145d20f59b61#diff-9e1ecc14c733bb1ae2e523089f1262ac6ffccbcf950487ee0984403603550e57 and it was something I highlighted that I was looking into fixing (https://github.com/mochajs/mocha/pull/5060#pullrequestreview-1800661242) but since it required solving a governance issue (https://github.com/standard/standard/issues/1948#issuecomment-2138078249) it took a while and #5060 was merged anyhow
Formatting rules: I am strongly against using ESLint for formatting. Especially given our desire to eventually transition Mocha to ~TypeScript~ edit: typed linting (#4154) which will make the performance + usability issues with stylistic rules as described in https://typescript-eslint.io/users/what-about-formatting more prevalent.
I don't think Mocha having been set up many years ago to use Standard is enough motivation to add a successor back in now. The web dev community has mostly moved towards dedicated formatters as faster, more comprehensive solutions. Mocha's infra was -and in some places still is- rather ancient.
IMO the right direction for specifically formatting would be a dedicated formatter such as Prettier.
Stylistic rules: same questions as https://github.com/neostandard/neostandard/issues/273, I suppose. What does neostandard actually bring us? How is that different from eslint-recommended? Why use one or the other or both?
Still learning here but I'm also against ESLint for formatting. I like separate tools for separate purposes. ESLint is for telling me whether I'm writing "hygenic" code or not (let vs var vs const, for example) where Prettier is for fixing up the appearance of my code without changing any of the symbols.
An all-in-one tool sometimes sounds nice, but it becomes harder to tell why a change was applied by the tool, and harder to identify which changes were hygenic changes vs formatting ones.
(Still learning what a stylistic rule is)
I like the --noStyle option that's been mentioned, seems like it solves the conflation problem of hygenic vs formatting changes
Some benefits of an all in one tool:
- It's an all in one tool – one doesn't need to add and maintain more than one
- It's less likely to conflict with itself whereas the slightest overlap between two tools can cause chaos if they are not run in a proper order (been in way too many projects where one needs to run a Prettier fix before the ESLint fix and after doing so the Prettier check will no longer pass, only the ESLint check)
- Prettier isn't a very configurable tool
- One has a fitting coding style expressed in ESLint but not an equivalent one in Prettier / Dprint / Biome
I'm okay with us skipping styling rules, especially for now, but also noting that we do not have Prettier either right now
I have been convinced, or at least moved to the fence. --noStyle addresses my main concerns, and I don't really foresee any performance issues (that'd be premature optimization in my view).
It's an all in one tool – one doesn't need to add and maintain more than one
I don't think it is? If we're not using it for formatting then that's two tools, a formatter and a linter. What do you mean by "all in one" in that case?
If it's that we wouldn't have to configure linter plugins, then this goes back to https://github.com/neostandard/neostandard/issues/273. Does neostandard provide every reasonable+good plugin that Mocha would want to use? For reference, https://github.com/bingo-examples/created-typescript-app-common/blob/86470fee9a41aea728828a7f7c74cc442842bcd9/eslint.config.js has the list of plugins that I am likely to propose - minus perfectionist and yml since that's nitpicky, and minus vitest for obvious reasons.
It's less likely to conflict with itself whereas the slightest overlap between two tools can cause chaos if they are not run in a proper order (been in way too many projects where one needs to run a Prettier fix before the ESLint fix and after doing so the Prettier check will no longer pass, only the ESLint check)
🤔 Running Prettier before ESLint strikes me as a misconfiguration. In a properly set up repository, you lint and then format. What tools are formatting and then linting?
Prettier isn't a very configurable tool One has a fitting coding style expressed in ESLint but not an equivalent one in Prettier / Dprint / Biome
Why do we need to configure the style so much? IMO the specifics of the style aren't very important (as long as they're not horrendous, which no tooling defaults are). Being similar to other tools IMO is a much nicer benefit.
Should I file a separate issue suggesting using a separate formatter? We'd removed it alongside other cleanup work and I was waiting for this conversation to settle.
I don't think it is? If we're not using it for formatting then that's two tools, a formatter and a linter. What do you mean by "all in one" in that case?
What I meant with "Some benefits of an all in one tool:" was the benefits when using a tool like neostandard to do both style and non-style linting.
Does neostandard provide every reasonable+good plugin that Mocha would want to use?
That's not the goal of neostandard.
As mentioned in https://github.com/neostandard/neostandard#mission-statement which I linked above it's:
neostandard sets an expectable baseline for project linting that's descriptive of best practices rather than prescriptive of any opinionated approach.
In regards to:
For reference, https://github.com/bingo-examples/created-typescript-app-common/blob/86470fee9a41aea728828a7f7c74cc442842bcd9/eslint.config.js has the list of plugins that I am likely to propose - minus perfectionist and yml since that's nitpicky, and minus vitest for obvious reasons.
My personal superset of neostandard is here: https://github.com/voxpelli/eslint-config
Running Prettier before ESLint strikes me as a misconfiguration. In a properly set up repository, you lint and then format. What tools are formatting and then linting?
Formatting you do at save or commit time or manually. Checks you do at CI, commit time, push time and/or continuously in your editor.
The mere possibility of misconfiguration is troublesome, especially for people less experienced in the tools and/or in contexts where a wide variety of editors and editor extensions are used.
Eg: Prettier may be run in a pre-commit hook sequentially with an ESLint fix while a developer has a save action in their VS Code that does only the Prettier or does it the other way around. Every save will then reformat any overlapping rules to the prettier variant when they edit, making eg the staging of changes in git or the swap between branches needlessly hard
When there's only a single tool involved it can be run out of order with another tool or disagree with another tool.
And these are not theoretical points – it's what I have experienced in many/most large projects I have joined in recent years and which has used both.
Why do we need to configure the style so much?
So you want to use a predefined style setup but do not want to use a predefined linting setup like neostandard?
This is a big topic.
I find the way that neostandard is set up to be preferable to the way prettier is set up.
Prettier is opinionated and prescriptive when it comes to style.
neostandard is descriptive and opts to rather not include a rule than to become opinionated and prescriptive (of course that approach in itself might be seen as opinionated and of course if one reaches far enough outside the part of the ecosystem that uses standard / neostandard then it's seen as prescriptive there, but then neostandard isn't the right tool for them)
If someone did a port of eg. the neostandard descriptive coding style to a configurable formatter like dprint, biome or such then that would be great.
So far the only such definition is the one carried forward from older versions of standard and as such that is what I use.
(Sorry for many comments, the GitHub app, especially on an iPhone 12 Mini, is not easy to write long comments in)
Should I file a separate issue suggesting using a separate formatter?
I'm not too keen on pursuing adding that in the near future so maybe we'll wait with it
The mere possibility of misconfiguration is troublesome ... When there's only a single tool involved it can be run out of order with another tool or disagree with another tool.
It seems we're stuck between a rock and a hard place:
- You don't want to use a separate dedicated formatter for formatting, because it's troublesome to configure alongside a linter
- I don't want to use a linter for formatting, because of https://github.com/mochajs/mocha/issues/5301#issuecomment-2730359286
Speaking of which, what is your response on the "don't use a linter for formatting" concerns? My concern is that it is inherently a misconfiguration to do so.
Should I file a separate issue suggesting using a separate formatter?
I'm not too keen on pursuing adding that in the near future so maybe we'll wait with it
Can you speak more on what you find disagreeable about Prettier's formatting? What specific spacing, etc. it does that can't be turned off?
And these are not theoretical points – it's what I have experienced in many/most large projects I have joined in recent years and which has used both.
Can you point to specifics, please? It sounds to me like the projects are misconfigured. To my knowledge this is not an issue in any of the projects I work on. I'd want to help fix things if I can, or at least understand what the specific misconfiguration is. 🙂
So you want to use a predefined style setup but do not want to use a predefined linting setup like neostandard?
I see eslint/recommended as a "predefined linting setup" in this context, I believe.
I've also personally never had linters interfere with formatters or vice versa, but I don't have a ton of experience.
Overall I'm curious if we can merge #5282 while we discuss? I don't think it'd add extra churn, really, as the changes are automatic and I don't see conflicts between the two proposals at this stage
It seems we're stuck between a rock and a hard place
I don't think that we are. I'm only objecting to #5282 as two out of three maintainers voiced that they wanted to go down the neostandard approach: https://github.com/mochajs/mocha/issues/5281#issuecomment-2567435225 And I don't like a "do-ocracy" approach where mine and @Uzlopak's opinions are disregarded just because we don't have the time right here and now to implement them.
Projects in general, this one included, needs to give merit to more than just code. A "do-ocracy" creates a fear of loosing out and with that comes stress, frustration and burn out.
We don't need to add a formatter / coding style approach here and now. My reply and explanation was simply to rebut your statements and questioning – and to explain the merit etc of the neostandard project (which I during these last 6-12 months have had to done to people within the ESLint ecosystem far far too many times)
what is your response on the "don't use a linter for formatting" concerns? My concern is that it is inherently a misconfiguration to do so.
I don't care if it's "wrong" or "right" to use a linter for formatting. I care about what works and what gives a productive outcome. Eg. neostandard works. Whether its "misconfiguration" or not is more of a theoretic exercise than a pragmatic one.
(I can also historically reflect on ESLint replacing the need for combining JSHint and JSCS, replacing them both with a single tool as described in eg. this article from that era. So someone thought it was a good idea to combine the two and only recently did ESLint change their mind and take the original stance of JSHint – a stance that JSHint took in relation to JSLint which had some styling rules in it as well)
Can you speak more on what you find disagreeable about Prettier's formatting?
Can you speak more about what you find disagreeable with neostandard's formatting and why you prefer Prettier's?
Can you point to specifics, please? It sounds to me like the projects are misconfigured. To my knowledge this is not an issue in any of the projects I work on.
I have given you plenty of specifics in regards to setup? But I won't be pointing fingers at any specific people or projects.
Overall I'm curious if we can merge https://github.com/mochajs/mocha/pull/5282 while we discuss?
I'm not sure why #5282 was made when both me and @Uzlopak had voiced that we wanted to go with the neostandard approach.
I think #5313 is the one to be merged while we optionally discuss future improvements.
All in all: I'm very busy with my full time job and I get pretty frustrated that I need to step in and remind about what we have discussed and even more frustrated about the push back.
I don't have the time right now for this, but the time is demanded of me or else I will be disregarded. Not cool.
"do-ocracy" is a great term, I haven't heard it in ages. Thanks for that one. 😄
First of all, I never meant to sidestep you or Uzlopak with #5282. I apologize for taking actions that made you (two?) feel disregarded. That was never my intention. ❤️
I can see how #5282 would come across as working around you though. I didn't and don't intend on merging anything we'd previously discussed without your consensus. It was a request for review, not some ham-fisted attempt at circumvention. I'd marked #5281 as in discussion, but now just to be explicit I've marked the PR as blocked.
Rather: I've seen Neostandard as a layer on top of ESLint. As in, https://github.com/mochajs/mocha/pull/5282#issuecomment-2729360932: that moving to ESLint's recommended step individually doesn't impede moving to Neostandard at all. Given how much its rules overlap with those #5313, I would have thought you'd be in favor it!
(which I during these last 6-12 months have had to done to people within the ESLint ecosystem far far too many times)
I don't want to come across as judgmental or preachy here (again, absolutely not the intent), but I'm not sure how else to phrase this: the fact that you've repeatedly had to explain the project is more an indictment of its documentation than the ESLint ecosystem. Neostandard's README.md only explains its high-level approach and theology. It doesn't give practical or tangible explanations of what users get with it. Hence https://github.com/neostandard/neostandard/issues/273: I am trying to ask the project to explain itself, so that folks like me don't have to each individually do a deep dive into the code & config inspectors to understand it.
From another angle: Neostandard's approach is a pretty thick layer on top of ESLint that hasn't been popular for several years. People -myself included- need to be convinced why that layer is worth it. The project does not do a thorough or convincing job of making that case. I think it's a really interesting discussion: the benefits of layers like Neostandard, what they should or shouldn't do, etc. And obviously anything that helps with the mess that is configuring formatting+linting sounds great. But adding yet another tool to the mix comes with downsides (additional dependencies, more configuration to learn, config details from the underlying tools leaking through). Until that discussion resolves I am not convinced it's worth it to adopt such a thick layer.
"wrong" or "right" to use a linter for formatting what you find disagreeable with
neostandard's formatting and why you prefer Prettier's?
Two issues: it's not comprehensive enough, and it slows down linting.
Comprehensiveness: the one-rule-per-concern architecture of linters means it's exceedingly difficult to encapsulate all formatting concerns, let alone have them work well together. What you end up having is a lot of individual rules whose fixers intersect with each other, resulting in many rounds of lint fixers running. These concerns and a few more are explained better in https://eslint.org/blog/2023/10/deprecating-formatting-rules (I know you've read that, just posting the reference as this is a public discussion). You can find a bunch of examples of comprehensiveness issues in most of the enhancement issues in eslint-stylistic.
Slowdowns: when you have many rounds of lint fixers running, any slow rules have to also get re-run alongside the fast formatting ones. This isn't an issue for smaller projects that don't have many rules. But slower rules such as file import analysis and linting with type information can take multiple seconds each round to run. https://github.com/eslint/eslint/issues/18642 explains this better -> https://github.com/eslint/eslint/issues/18642#issuecomment-2286786282 has a comparison baseline.
OTOH, the way Prettier and other dedicated formatters are generally set up to drop almost all formatting information from the AST before re-printing results in a much more consistent result. Except for newlines (mostly) the result is based purely on the AST and so isn't influenced by human nitpickness. Which IMO is good - it's almost always a waste of time thinking about little intricacies of code. The more the tooling can remove our need to spend thoughts and time on these things, the better!
I have given you plenty of specifics in regards to setup? But I won't be pointing fingers at any specific people or projects.
Haha, I'm not trying to finger-point or lay blame at any projects. I am trying to be helpful! 😄 Specifically:
- If there are projects out there whose usage of these tools is giving them pain, I want to help.
- You've described the general theory of how a formatter<>linter conflict might happen but what I'm really looking for is a reproduction so I can better understand how what you're saying can happen. Like, technically, what are the configuration details that lead to it?
My offer still stands independent of this issue, if there is some open source project that is experiencing slowness / other pains configuring ESLint and a formatter together, I'm generally happy to try to help.
Taking a step back: I was honestly enjoying this discussion and am sad & surprised it's become a source of frustration for you. I agree that we don't need this to be resolved soon. I'm up for holding off and maybe coming back to this at some future date when we've gone through more important things?
That being said, part of why I'm surprised here is that you and Uzlopak have mostly avoided interacting with me on these issues. While #5281 has "only" been open for 3.5 months -including my request for clarification in https://github.com/mochajs/mocha/issues/5281#issuecomment-2567403893- I've been waiting on assorted issues for months or over a year in some cases (quick starting query for some of the un-answered questions). I of course agree we don't want a do-opoly, but I hope you can see why it's surprising to me that this issue has suddenly become contentious. We've never discussed expectations of timing for things like this, maybe the concerns about me working around you two are a good instigator to? Maybe we should take this into our established private channels.
the fact that you've repeatedly explain the project is more an indictment of its documentation than the ESLint ecosystem
Its a continuation of the standardjs project which is one of the top shareable configs along with eg. eslint-config-airbnb. standardjs as created by @feross – a very high profile figure in the Node.js ecosystem – and its list of contributors reads like a whos-who of the node.js community.
While it hasn't seen the same growth in recent years as ESLint it wasn't that many years ago that it made up +10% of all ESLint downloads – and as can be seen in that list, it and other popular shareable configs all still have more stars on GitHub than ESLint does.
So it strikes me as odd that the ESLint ecosystem would be so unaware of the most widely used shareable configs within it – and I the README of neostandard won't change any such potential lack of knowledge around the ecosystem.
(Its too small: https://github.com/eslint/eslint/issues/18800#issuecomment-2305665257 Shareable configs are no longer a thing: https://github.com/eslint/rfcs/pull/126#discussion_r1861031266 It doesn't matter if users of shareable configs gets breaking changes: https://github.com/eslint-stylistic/eslint-stylistic/issues/633 One needs to make reproductions for other maintainers as else one wastes their time, meaning that shareable configs will need to service everyone else with reproductions if there's ever a regression somewhere https://github.com/typescript-eslint/typescript-eslint/issues/9164)
Neostandard's approach is a pretty thick layer on top of ESLint that hasn't been popular for several years. People -myself included- need to be convinced why that layer is worth it.
Or people are more interested in protecting the projects that give them an income than in supporting alternative approaches... Its another needless way of framing it. One can focus on that, or one can collaborate.
I hope you can see why it's surprising to me that this issue has suddenly become contentious
Well, it happens to tie all of my main projects together – Neostandard, ESLint Community, Mocha – and plenty of yours as well – TypeScript-ESLint, ESLint, Mocha.
I don't have time or energy to read or respond to all. I have spent more time on this issue than I can afford already. I'm tired of having to argue and describe neostandard like this when all I am is the current caretaker of standard, not the creator and neither the main user of it, and when I also have gone out of the way to contribute to the ecosystem over and over and can't see where all the distrust arise from. It causes severe frustration and makes me just want to quit it all.
So with that said: I'm done with this thread. Its already grown too big anyway. Nothing else written will add anything to it.