How to Write Perfect Code with Standard and ESLint

How to Write Perfect Code with Standard and ESLint

In this talk, you'll learn about code linting – how to use Standard and ESLint to catch programmer errors before they cause problems for your users. We'll discuss how to get started with linting, as well as how to improve your setup if you're already linting your code. Feross will also share the secret history of how the Standard linter was created, for the first time ever in a conference talk.

Presented at JSConf Asia 2018 (https://2018.jsconf.asia) by Feross Aboukhadijeh (https://feross.org)

Read more about Standard at https://standardjs.com/

B498d33041627b07726dc29c28f02df7?s=128

Feross Aboukhadijeh

January 25, 2018
Tweet

Transcript

  1. WRITE PERFECT CODE with Standard and ESLint

  2. npm install standard --save-dev

  3. THE END

  4. WRITE PERFECT CODE with Standard and ESLint

  5. None
  6. What's a linter?

  7. A LINTER CATCHES BUGS

  8. What's a bug?

  9. WHEN YOUR CODE DOESN'T WORK

  10. “BUG”

  11. BUGBEAR BUGABOO BOOGEYMAN

  12. None
  13. None
  14. We could, for instance, begin with cleaning up our language

    by no longer calling a bug a bug but by calling it an error. — Edsger W. Dijkstra
  15. None
  16. ESLINT Catches programmer errors

  17. JSLINT ➡ JSHINT ➡ ESLINT

  18. PROGRAMMER ERRORS BEST PRACTICES STYLE ISSUES

  19. CATCH PROGRAMMER ERRORS Shorten the Feedback Loop

  20. QUIZ: DO YOU SEE THE BUG IN THIS CODE? for

    (let i = 0; i < 10; i--) { console.log(i) }
  21. ENFORCE “FOR” LOOP UPDATE CLAUSE MOVING THE COUNTER IN THE

    RIGHT DIRECTION for (let i = 0; i < 10; i--) { // This loop never ends! } for (let i = 10; i >= 0; i++) { // This loop never ends! }
  22. DISALLOW ASSIGNMENT OPERATORS IN CONDITIONAL STATEMENTS if (user.jobTitle = 'manager')

    { // user.jobTitle is now incorrect }
  23. DISALLOW DUPLICATE ARGUMENTS IN FUNCTION DEFINITIONS function foo(a, b, a)

    { console.log('value of the second a:', a) }
  24. DISALLOW COMPARING TYPEOF EXPRESSIONS AGAINST INVALID STRINGS typeof foo ===

    'strnig' typeof foo === 'undefimed' typeof bar !== 'nunber' typeof bar !== 'fucntion'
  25. DISALLOW INVALID REGULAR EXPRESSION STRINGS IN REGEXP CONSTRUCTORS RegExp('[') RegExp('.',

    'z') new RegExp('\\')
  26. Plus dozens more error checks

  27. How does one use ESLint?

  28. .ESLINTRC

  29. .ESLINTRC { "extends": ["standard"] } npm install eslint-config-standard --save-dev

  30. STANDARD VS. AIRBNB VS. GOOGLE

  31. .ESLINTRC { "extends": ["standard"], "rules": [ "quotes": ["error", "double"], "rest-spread-spacing":

    ["error", "always"], "semi": ["error", "always"] ] }
  32. WHY USE STANDARD?

  33. USE STANDARD $ npm install standard --save-dev $ standard Error:

    Use JavaScript Standard Style main.js:950:11: Expected '===' and instead saw '=='.
  34. VIBRANT COMMUNITY DOWNLOADED 1 MILLION TIMES PER MONTH EDITOR PLUGINS

    FOR EVERY MAJOR EDITOR BUILT INTO WEBSTORM
  35. PACKAGE.JSON { "name": "my-cool-package", "devDependencies": { "standard": "*" }, "scripts":

    { "test": "standard && node test.js" } }
  36. Should one use ESLint directly?

  37. BEWARE OF BIKESHEDDING

  38. BEWARE OF DUPLICATION

  39. PROGRAMMER ERRORS BEST PRACTICES STYLE ISSUES

  40. PROGRAMMER ERRORS BEST PRACTICES STYLE ISSUES

  41. QUIZ: WHAT DO THESE EXPRESSIONS EVALUATE TO? [] == false

    [] == ![] 3 == '03'
  42. QUIZ: WHAT DO THESE EXPRESSIONS EVALUATE TO? [] == false

    // true [] == ![] // true 3 == '03' // true
  43. None
  44. REQUIRE === AND !== // NOT OK if (x ==

    42) { } // OK if (x === 42) { }
  45. STANDARD IS PRAGMATIC // OK if (x == null) {

    } // THE ABOVE IS EQUIVALENT TO... if (x === null || x === undefined) { }
  46. QUIZ: DO YOU SEE THE PROGRAMMER ERROR? hashOut.data = hashes

    + SSL_MD5_DIGEST_LEN; hashOut.length = SSL_SHA1_DIGEST_LEN; if ((err = SSLFreeBuffer(&hashCtx)) != 0) goto fail; if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; err = sslRawVerify(...);
  47. if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto

    fail;
  48. if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) { goto fail;

    } goto fail;
  49. REQUIRE CURLY BRACE CONVENTIONS // NOT OK while (bar) baz()

    // NOT OK if (foo) { baz() } else qux()
  50. STANDARD IS PRAGMATIC // OK readFile(file, (err, data) => {

    if (err) throw err }) // OK readFile(file, (err, data) => { if (err) { throw err } })
  51. FINAL TIPS

  52. EVEN IF YOU DON'T USE STANDARD CONSIDER standard-engine

  53. WHAT ABOUT PRETTIER?

  54. PROGRAMMER ERRORS BEST PRACTICES STYLE ISSUES

  55. PROGRAMMER ERRORS BEST PRACTICES STYLE ISSUES

  56. Support me on Patreon PATREON.COM/FEROSS

  57. Thanks! FEROSS.ORG