Hacker News new | past | comments | ask | show | jobs | submit login
ESLint 7.0 (eslint.org)
205 points by himynameisdave on May 11, 2020 | hide | past | favorite | 90 comments



I didn't like programming in JavaScript so much because I think the syntax makes it a little harder to read than necessary.

However, I confess that after adopting ESLint in my workflow, things have improved considerably. I can ask it to warn me on unused stuff, to enforce the lack of semicolons, to format and indent my code correctly on save... it's a very useful tool. If you have something against JavaScript in general, give it a try.


I also recommend `prettier`. It can be configured to obey eslint and will reformat your code on the fly to fit standards so you can spend less time fighting spacing and more time just writing code. While `eslint --fix` is a thing, prettier parses the underlying AST to do it's transformations and it's a very impressive tool.


It should be renamed 'uglier' or 'obfusticate'

    const normals = [
      -1, -1, -1,
       1, -1, -1,
      -1,  1, -1,
       1,  1, -1,
      -1,  1,  1,
       1,  1,  1,
    ];

    const positions = [
      -1, -1,  0,
       1, -1,  0,
      -1, -1,  0,
      -1, -1,  0,
       1, -1,  0,
       1,  1,  0,
    ]

    ctx.drawImage(
       image,
       srcX, srcY, srcWidth, srcHeight,
       dstX, dstY, dstWidth, dstHeight,
    )

becomes

    const normals = [-1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1];

    const positions = [
      -1,
      -1,
      0,
      1,
      -1,
      0,
      -1,
      -1,
      0,
      -1,
      -1,
      0,
      1,
      -1,
      0,
      1,
      1,
      0,
    ];

    ctx.drawImage(
      image,
      srcX,
      srcY,
      srcWidth,
      srcHeight,
      dstX,
      dstY,
      dstWidth,
      dstHeight
    );
Those are less pretty and useful info is lost.


I used to feel as you do, which is basically "What about the special cases!" But then I realized that it was much preferred and easier to have consistent styling automatically enforced everywhere. For the rare times I really don't like it, I can just add an ignore prettier comment.

The one thing I'll give to you is the handling of arrays. There is an open issue to treat array literals the same as object literals in that newlines between elements will be respected and not automatically compressed onto a single line if the whole line is less than max-width. After about a half year of usage that's the only default I really don't like.


If your team consistently writes code that looks like your first example, you absolutely shouldn't use prettier. However, in my experience, your first example isn't what people regularly produce and the output is a wild improvement on a lot of things that I've seen people write.


The use of code "prettifiers" (in general) helps save effort on having a code style guide, and people following it. As you, and others have said, it depends on the project.

Clearly for projects where devs have the habit and follow a clear style, it's not necessary. However on mosy projects, you'll have the one guy who doesn't follow, or worse, the only one guy who follows the style. And so the prettifiers become absolutely necessary.


> However on mosy projects, you'll have the one guy who doesn't follow, or worse, the only one guy who follows the style. And so the prettifiers become absolutely necessary.

I'll bite - why, exactly, is this "absolutely necessary"? The justifications for needing style guides and linters that I get is usually something like "so we don't argue about this stuff". Well... I wasn't arguing in the first place - you were. And every project will have someone who wants to add their own preference in 'because'... so regardless of what you're in, nothing is 'standard', ever.

My experiences may be somewhat outside the norm, but in the last... 18 months or so, I've worked with 3 different teams (anywhere from 3 to 20+ other people) across php, js - angular/vue/node, java and ruby. There's been more in-fighting and bike-shedding about "standards" from people who tend to be the least productive.

I can fully admit some code is, sometimes, easier to read when formatted certain ways. No one seems to ever be able to admit or acknowledge that sometimes, it's very hard for me to read in their preferred style. I don't complain. I just ... get on with it.

Again, my experience may be different from others, but of the multiple folks I've dealt with in the past couple of years, the ones who were open vocal advocates about needing "standard" and forcing style/linting/etc on to projects - these people rarely ever found bugs in their own code or code from others, or spotted logical problems with the code, or, indeed, contributed tests. It's as if they equate 'code beauty' with the actual functioning of the code itself. "Hey, it looks good, I'm checking it in" - this is now reinforced with "hey, all my linting/style is passing - awesome - checking it in!"

I initially chalked this up to one person, but in my experiences, it's been a recurring trait/behaviour.

I jump between projects/contracts. I've never worked at one company on one project and one team for multiple years - the dynamics are certainly different from short term projects.

Current situation - two client projects.

Client A - fanatical about 'null==' because there was some bad assignment by mistake issue a few years back. This is a hard rule, and code will be blocked if you commit

    if (customer.id == null)
has to be

    if (null == customer.id)
I understand the value, but ... tests help catch those issues as well. But... my habit over the last 6 months has been to default to that.

However - working with client B

    if (null == customer.name) 
"this is confusing - none of the other code uses this style, it's hard to read, stop doing it".

So, in the same week (sometimes, the same day), I have multiple competing styles in my head, and regardless of what I do, I have a productivity loss because something has to check/correct and I have to wait, or I have to recommit and re-push stuff because something was 'wrong' to someone. When you switch between "styles" enough, it begins to seem a bit cargo-cultish, to my eyes.


I understand your experience, and based on mine I can tell you this: I absolutely hated the time I had an intern to whom I taught python, showed him the guide style and he insisted in writing things like this:

    def some_function(arg1, arg2, arg3):
        temp=arg1*arg2;temp=numpy.some_function(temp, arg3);return temp
Those innecessary oneliners where a mess. And the arguments names? Not shortening for the example, they guy did that. In the end whatever work he did, we had to dedicate one of our programmers who had an idea of what those functions where supposed to do to "translate them back".

I was almost useless work. Worse yet, we couldn't fire him because we were mandated by higher ups to keep him in the team for the duration of the internship he had to do to comply with some scholarship requirement with an institution we're related.

Again, the style guide we've written works for our team and the #1 rule is: code must be clear. There are a few other rules (variables and functions are snake_case, classes are CamelCase and so on), but those are derived from #1 and habits/experience the team has developed over years of work.

I also understand they situation you say: putting style/beauty/the linters as an objective and forgetting about what the code has to do in the first place. Can't really help you there, I am aware (and happy) that my team and I are in sync.


You can tell prettier to ignore the next node: https://prettier.io/docs/en/ignore.html


While I agree about the arrays. I much prefer the function call.


I highly recommend spending some time configuring your prettier, especially if you regularly write out matrices. It's very much preconfigured for FE heavy development which doesn't work for me either - but you can have a global root config tweaked to your preferences.


Yeah, prettier rocks. I was skeptical for a long time and if I’m honest and think about it I still don’t like some of the formatting choices it makes, but I don’t notice because of how fluid and pleasant it makes writing code. As an aside, often the “workarounds” result in clearer code, e.g. long formulas getting split up weirdly leads to me splitting stages of the calculation into named variables, which actually reads much better when I return to it months later.

No worrying about formatting code as I type, no worrying about checking style on PRs... definitely worth the trade offs for me, I enable it on every project I work on now.


And if you are working in a team it makes those arguments about styling moot. One of the best aspects of JavaScript.


Yeah that’s what I mean about PRs - such a time saver to not discuss trivial code style issues and be able to just focus on the code itself!


I'll never forget getting our team of 90+ devs to move to prettier because of this argument and then having team members proceed to strong arm me to change the configs to things that they preferred six months after we made the move and we had adopted it across over 10 different repos. Talk about counter to the whole point of using such a wonderful tool.


That must have been frustrating - I do feel like perhaps they made a mistake adding configuration to prettier at all! But especially for matters of preference such as single vs double quotes where ultimately it makes very little difference. Luckily my team are happy with the defaults + slightly longer line length


yeah, I pretty much rely on eslint and prettier across the board... I do have a couple tweaks though[1].

1. https://gist.github.com/tracker1/e6c2befae41856da27973cf22cf...


And editorconfig


Show me where editorconfig does formatting or linting.


TypeScript. ( + ESLint, + Prettier ). It has made writing JavaScript tolerable. Classes as you expect them. With proper editor support, you get real errors, and the whole thing starts to feel more like writing code in python. It is no python, but at least it feels significantly less foreign. Its very progressive in the sense that regular JavaScript is valid TypeScript, and everything else is just a cherry on top. And it is easy to include the typing outside of the source file, so many libraries not written at all in TypeScript have typing support built in (likely by simple PRs from the community)


> to enforce the lack of semicolons

Why would... you want that? You're trading minimal syntactic noise for possible ambiguity errors. You don't really gain anything.


This is like asking "vim or emacs". You'll never change anyone's mind on the matter, but you'll get the same old arguments from ~ten years ago [0] about how this is both "very simple†" and "pointless mental overhead" at the same time.

† (if you follow these rules I memorized to show off how smart I am).

---

[0]: https://github.com/twbs/bootstrap/issues/3057


In combination with other linting rules to catch reckless conditionals and multiline returns, it is absolutely safe to enforce no semicolons. And the visual noise is, at least to my eyes, a significant impact.


If visual noise is an issue, I made a VSCode theme specifically for muting things like quotes and semicolons, that way I don't have to choose between explicit semicolons and reduced visual clutter: https://marketplace.visualstudio.com/items?itemName=wildpeak...

The theme was primarily made for me, but I published it because others might find the idea useful.


You need to know when semicolons are necessary whether you use them or not.

And the whole point here is that tooling eslint/prettier prevents bugs.

Prettier will turn this:

    const x = foo()
    [1, 2, 3].forEach(...)
into this:

    const x = foo()[1, 2, 3].forEach(...)
Which makes the problem pretty obvious.

Btw, if you decide to avoid semicolons, one of the only rules you need to know is to prefix any line with a semicolon if it starts with "[(.


Introducing any mental overhead to eliminate a single character per line at most seems a tad ridiculous.


I haven't used semicolons for at least 5 years. Let's not overstate the "overhead", which I would say is zero. Especially in this comment thread where we just established the tooling handles it for you.

Frankly, I die inside every time I work with a semicolon codebase and have to move a semicolon just to chain onto:

    promise
      .then()
      .catch();
    + .then();

    foo
      .bar()
      .baz();
    + .qux();
You are making the common developer/HNer mistake of overvaluing familiarity and overestimating how hard anything slightly unfamiliar must be.

I challenge you to try it the next time you write some Javascript. Don't use semis and remember the one rule I taught you.


After every single line is not minimal. It's redundant.

In 30 minutes you can learn to recognize and practice handling all of the cases where a semicolon would be necessary. There is no ambiguity because the rules for statement termination are rigid. If you find it hard to navigate with only explicit semicolons, then you should brush up on your JavaScript knowledge.

And seeing as how we're on an ESLint thread... there are tools for that. ;)


I used always have semi-colons too, but now that my code is always transpiled, I just let the transpiler handle it (and TypeScript does a good job catching ambiguities/unintended code pretty well too).


You can do most of that without ESLint for any programming language with an IDE. Speaking about jetbrains intellij/pycharm from my own experience.


The IDEs will sometimes use their in-house solution, and sometimes integrate one of these external tools that focus on doing just one thing very well. My setup is VSCode + ESLint when dealing with JavaScript.


The point of these tools is that the configuration is specified in the project, and works regardless of the developer's workflow.


TypeScript.


My use of JavaScript is mainly for small code bases. The gains of TypeScript are less relevant in this scenario over the bureaucracy that it brings to the game.


What does this bureaucracy look like?

Asking because to me personally it seems that it's easy to create a new TypeScript app from a template with zero configuration, and then it just works. Perhaps I'd need to spend 5 minutes to write the type for the API responses or some other basic stuff like that.


I have been waiting for this release for the new possibility to include a comment in eslint-disable-{next-}line:

  // eslint-disable-next-line no-console -- Here's a description about why this configuration is necessary.
  console.log('hello');
https://eslint.org/docs/user-guide/configuring#disabling-rul...


How is that different than:

  // Here's a description about why this configuration is necessary.
  // eslint-disable-next-line no-console
  console.log('hello');


In short: it's more comfortable and more versatile.

1. Sometimes there's already a comment on the preceding line commenting the logic, and the new comment explaining ESLint would have to go awkwardly in-between.

2. Sometimes it's just complicated to word the comment if it can't be on the same line.

3. Sometimes eslint-disable-line is in a place where it would be ugly to have a comment above. Here are two examples from my current project, both from cases where the disable is right after a closing curly brace:

  } as any // eslint-disable-line @typescript-eslint/no-explicit-any

  }, [map]); // eslint-disable-line react-hooks/exhaustive-deps
Other cases can be found in the issues:

Feature request #1: https://github.com/eslint/eslint/issues/11298

Feature request #2: https://github.com/eslint/eslint/issues/11806

RFC: https://github.com/eslint/rfcs/tree/master/designs/2019-desc...

Next up: an ESLint rule that makes the comment obligatory for disable directives.


Well, it's on one line for starters ;)

Looking at one suppression in one place it doesn't make a big difference.

It will help a lot with whole-project search results, though, if you're trying to e.g. fix all the places you had to suppress X because of Y.


You could be commenting functions too (day JSDoc it TSDoc) but also want to do an eslint-ignore. It looks better then, IMO.


Yo dawg, heard you like comments


I haven't done TypeScript/JavaScript in a while. What's the status of ESLint taking over from TSLint (for both the tool itself and the vscode extensions)?


I think the transition is nearly ironed out, I'd say the only concerns are the edge cases but everyday usage should be fine:

https://github.com/typescript-eslint/typescript-eslint

Haven't ran into too many issues within the last 8 months or so. Only in Spring 2019 was it bad IME.


Have exclusively used ESLint for TypeScript over the past year. It works great, no issues. The only slight problem is some rules conflict, but that only comes into play if using a comprehensive preset like airbnb.


Ah ESLint, the most necessary bane of my existence. Good work to the team for the update.


I just could not deal with such an opinionated tool. ESLint would not let us adjust settings to accept some of our normal convection's and company code style guidelines.

I switched to jshint and have lived a much happier life.


That's interesting, given that the original idea behind eslint was to create a tool to fix the warts of jshint which was apparently not enough flexible!

https://eslint.org/docs/about/

> The primary reason ESLint was created was to allow developers to create their own linting rules. ESLint is designed to have all rules completely pluggable.

> Every rule... Can be turned off or on (nothing can be deemed "too important to turn off")

> Rules are "agenda free" - ESLint does not promote any particular coding style

Is it the eslint that's opinionated, of the rules config that you were using? Or the maintainers of the rules in the github repo? (or is this sarcasm :)


Sorry this was me mixing up JSLint and ESLint


Ah, gotcha. JSHint was indeed created to fix JSLint's even greater non-flexibility, long time ago.


> I just could not deal with such an opinionated tool.

ESLint is not opinionated.

> ESLint would not let us adjust settings to accept some of our normal convection's and company code style guidelines.

Example?

> I switched to jshint and have lived a much happier life.

JSHint is more opinionated and less configurable than ESLint.

I have to ask, but uh...did you maybe get the names of the tools mixed up?


Yes ESLint didn't exist when I set up this project and I confused it for JSLint.


I feel this way but about `prettier.js` (as opposed to eslint.js) instead.


That's expected - Prettier intentionally and openly positions themselves at the most extreme extreme end of convention-over-configuration. Their tagline is "Opinionated code formatter". If this bothers you, you should look for a different tool.


> That's expected - Prettier intentionally and openly positions themselves at the most extreme extreme end of convention-over-configuration. Their tagline is "Opinionated code formatter". If this bothers you, you should look for a different tool.

Sometimes I can't use another tool because another dev has snuck the change into the repo. I can't be privy to every change at a large company. I also can and will continue to be bothered by the existence of prettier because of this. Sometimes I like being bothered. It let's me know what kind of crap to avoid in the wild. If this explain bothers you, you should consider other contexts where problems may apply.


Hopefully it got a little less „dependency-heavy“ than before. Using eslint and babel tends to add 200mb of dev dependencies to a project...


~ λ mkdir -p /tmp/js

~ λ cd /tmp/js

/tmp/js λ npm init -y & npm i eslint babel

[snip]

/tmp/js λ du -h node_modules

[snip]

36M node_modules


While this might be correct, in the a lot of cases you'll also use a lot of plugins for both to enable the desired transpilations and checks...

I should have been more precise in my first comment though.


Does anyone know if they have addressed the major performance problems with typescript?

This was a few months ago, but tslint takes a few seconds on one of our larger code bases. However ESLint with the typescript plugin would take up to a minute+, and seemed to make webstorm struggle with the eslint integration.


Could it be that you were using type-aware linting rules? If you have these rules enabled, ESLint basically has to compile all your TS files to check if the rules are followed. Note that most of the ESLint rules are _not_ type aware, but following the setup guides quickly has you turning them on “by accident”. For more details, see: https://github.com/typescript-eslint/typescript-eslint/blob/...


Been testing it out the beta, in my experience performance is better but still behind tslint, though tslint lacks a ton of rules compared to eslint so I am guessing that is partially why. I think the webstorm struggle is a webstorm specific issue, I've seen a few of my co-workers experience similar webstorm slow downs from eslint (and ts) but it works fine for me in vim without any slowdown of the editor itself.


You’ll probably need to be more specific about the speed issues you’re seeing. I don’t see that issue, but I also factor my code into smaller packages in my monorepo (which is a good practice). I still have relatively long lint times against the monorepo (greater than a minute), but that’s part of the CI stage.


I know the whole "there are two types of programming languages" Stroustrup quote applies to JS just as much as it does to C++, but can anyone comment on whether JS was hated as much as it was back when this second generation of browsers was being built? As someone who went straight into research and low-level work, I don't touch JS very often, but it seems to me as though the Web is in this arranged marriage it doesn't like, but refuses to leave because of the inconvenience.

I feel like in some regards, we have seen generational shifts in other languages. In domains where Perl, Java, and C++ used to dominate, we now have Go, Rust, and Python.

Absolutely worth noting that with the exception of Python, there are probably still vastly more lines of C++/Java code running in production than Go/Rust. I kind of don't get how if JavaScript is so bad, then why do we now have things like Node?


If I had to guess, I'd say Node is popular because the web has eaten the world, and if you already have a web app as the core of your development, it starts to make sense to make everything else just an extension of that, including your server so you can do things like server-side rendering.

A lot of that development seems to be TypeScript too, which helps mitigate a lot of the problems of raw JavaScript, and the structural typing makes working with JSON (something now pretty universal too) far easier than with a lot of languages.

There are a lot of things I hate about JavaScript itself, but TypeScript's type system is genuinely great.


Sad to see that bundled packages with shareable config are still not supported :(


Does this release support Yarn v2’s Plug’n’Play?


There is a rule in eslint that warns you when a promise is dangling and hasn't been handled.

Please use that rule. So many bugs in the JS world is because of dangling promises.


I think that's part of the typescript plugin, not part of eslint core - https://github.com/typescript-eslint/typescript-eslint/blob/... (I assume that means it only works on TypeScript.)

But, I agree with your point, that rule can catch a lot of bugs.


There are many ways to get this rule, but the primary one being: https://www.npmjs.com/package/eslint-plugin-promise


I don't think that plugin catches floating promises, i.e. promises that are not waited (either via await or then/catch method). The rules listed in that package's readme don't seem to mention it at least (unless I'm totally misreading something). You kinda need TypeScript for that because you need the type info to know if a value whether some value is a Promsie to give the warning.


We use Pulumi and Typescript, and it seems to rely heavily on Promise. I wonder how that ESLint rule would affect Pulumi code?

https://www.pulumi.com/docs/intro/concepts/programming-model...


I’m not sure on Pulumi specifically, but a .catch on a non-awaited promise should be fine.


If you add a catch block it will be even worse, all errors inside a promise callback will then become soft errors. Only add the catch if you actually plan to handle the error.


promise.catch(console.error) is still handling the error.


That's still a soft error. Meaning the app will continue like if nothing happened. Resulting in poisonous state.


I can't speak to the front-end, but there are plenty of situations in dealing with node where the correct thing to do is to throw a fatal error. If you have properly setup handlers for the end of the process lifecycle I don't see what the problem is.


But until recently an unhandled promise failure was NOT a thrown error, and when it is it's not the error you want.


Absolutely! I guess what I'm trying to say is that in my experience, crashing on an unhandled rejection is a better remedy to the dangling promise problem than banning them outright.


There is a saying - what you don't know can't hurt you. The idea of Promises comes from strongly typed static functional languages. Adding it to JavaScript was a terrible idea. Like with static modules - forcing the user to download the whole website/app before anything is rendered on the screen.


Lol what are you on about.

You're mixing so many different things right now.


hundreds of rules to read, is this on its recommended list if it's so critical? is its name 'no-floating-promises'?


> is its name 'no-floating-promises'

Yes, and I subscribe to the parent's sentiment: this rule is essential



It's unfortunately not on the recommended list. For very few circumstances the rule doesn't make sense, but most of the time that shows bad programming design.

That's the name!


I also highly recommend just reading all the rules if you're a JS/TS developer. It really helps you see what stuff could be very useful.


>is this on its recommended list

Not now, but it's planned to be starting with the next major version. They are holding off until then since changing the default rules is considered a breaking change.

https://github.com/typescript-eslint/typescript-eslint/issue...


Please don't use uppercase for emphasis. If you want to emphasize a word or phrase, put asterisks around it and it will get italicized.

https://news.ycombinator.com/newsguidelines.html.


HNLint


Thanks!

HN should automatically detect this and let me know :D

Unfortunately I think the comment is too old to edit.


> HN should automatically detect this and let me know

That's on the list!

I've reopened the comment for editing if you still want to.


Done! Thanks :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: