$30 off During Our Annual Pro Sale. View Details »

Make Linting Great Again (Long version)

Make Linting Great Again (Long version)

Presented at Agent Conf 2018

Andrey Okonetchnikov

January 25, 2018
Tweet

More Decks by Andrey Okonetchnikov

Other Decks in Programming

Transcript

  1. Make Linting Great Again
    with @okonetchnikov

    View Slide

  2. View Slide

  3. https://reason-conf.com

    View Slide

  4. What the #$&% is lint?!

    View Slide

  5. –Wikipedia
    “lint or a linter is any tool that flags
    suspicious usage in software written
    in any computer language.”

    View Slide

  6. –me
    “linter is a tool that finds stupid bugs.”

    View Slide

  7. View Slide

  8. These things here :(

    View Slide

  9. View Slide

  10. View Slide

  11. View Slide

  12. How to fix that?

    View Slide

  13. Lint all the things!

    View Slide

  14. Stylelint
    JSON Lint

    View Slide

  15. Why lint?

    View Slide

  16. – http://www.prweb.com/releases/2013/1/prweb10298185.htm
    “On average, software developers spend
    50% of their time finding and fixing bugs.”

    View Slide

  17. – http://www.prweb.com/releases/2013/1/prweb10298185.htm
    “…this inefficiency is estimated to cost the
    global economy $312 billion per year.”

    View Slide

  18. View Slide

  19. In reality, though…

    View Slide

  20. – http://www.prweb.com/releases/2013/1/prweb10298185.htm
    “On average, software developers spend
    50% of their time finding and fixing bugs.”

    View Slide

  21. – me
    “On average, software developers spend
    50% of their time discussing code style.”

    View Slide

  22. View Slide

  23. You don’t need to uglify
    your code if it’s already ugly!

    View Slide

  24. How to fix that?

    View Slide

  25. One code style to rule them all!

    View Slide

  26. View Slide

  27. View Slide

  28. Using linters & formatters leads to
    1. Fewer (stupid) bugs
    2. Better readability => less time in code reviews
    3. But it can slow you down… :(

    View Slide

  29. —Slow down?!
    —We’re not doing that then!

    View Slide

  30. My typical day…

    View Slide

  31. View Slide

  32. View Slide

  33. 10 minutes later…

    View Slide

  34. View Slide

  35. View Slide

  36. View Slide

  37. View Slide

  38. View Slide

  39. View Slide

  40. View Slide

  41. View Slide

  42. View Slide

  43. Raise your hand if this sound familiar to you

    View Slide

  44. View Slide

  45. View Slide

  46. View Slide

  47. 428.689

    View Slide

  48. View Slide

  49. 2.844.799

    View Slide

  50. – Everyone
    “I wish I could lint before committing the
    changes to the repository”

    View Slide

  51. git hooks

    View Slide

  52. View Slide

  53. git hooks are
    1. Hard to setup
    2. Hard to manage
    3. Hard to share across the team

    View Slide

  54. npm install -D husky
    yarn add --dev husky

    View Slide

  55. {
    "scripts": {
    "precommit": "eslint ."
    }
    }

    View Slide

  56. View Slide

  57. View Slide

  58. Thanks husky!
    1. Hard to setup
    2. Hard to manage
    3. Hard to share across the team

    View Slide

  59. …but linting the whole project
    1. Can be quite slow
    2. Will display irrelevant results

    View Slide

  60. View Slide

  61. What if we could run linters only
    on files we’re about to commit?

    View Slide

  62. Meet lint-staged!

    View Slide

  63. npm install -D lint-staged
    yarn add --dev lint-staged

    View Slide

  64. {
    "scripts": {
    "precommit": "lint-staged"
    }
    }

    View Slide

  65. {
    "scripts": {
    "precommit": "lint-staged"
    },
    "lint-staged": {
    "*.js": "eslint"
    }
    }

    View Slide

  66. View Slide

  67. git hooks are
    1. Hard to setup
    2. Hard to manage
    3. Hard to share across the team
    4. Very slow
    5. Displaying irrelevant results
    A WES OME!

    View Slide

  68. There is more!

    View Slide

  69. Automatically
    fix lint errors

    View Slide

  70. {
    "lint-staged": {
    "*.js": "eslint"
    }
    }

    View Slide

  71. {
    "lint-staged": {
    "*.js": [
    "eslint --fix",
    "git add"
    ]
    }
    }

    View Slide

  72. Automatically
    reformat your code

    View Slide

  73. View Slide

  74. {
    "lint-staged": {
    "*.js": [
    "eslint --fix",
    "git add"
    ]
    }
    }

    View Slide

  75. {
    "lint-staged": {
    "*.js": [
    "prettier --write",
    "git add"
    ]
    }
    }

    View Slide

  76. View Slide

  77. lint-staged and prettier
    being used in create-react-app

    View Slide

  78. lint-staged and prettier
    being used in Babel!

    View Slide

  79. How does it work?

    View Slide

  80. #!/bin/bash
    executable=$(npm bin)/staged-files
    linter_name="eslint"
    linter_path=$(npm bin)/eslint
    lint_extensions="**/*.@(js|jsx)"
    if [[ -f "${linter_path}" ]]; then
    echo "Running ${linter_name} on git staged files: $
    {lint_extensions}"
    ${executable} "${lint_extensions}" -- ${linter_path}
    else
    echo "Could not find ${linter_name} at $
    {linter_path}. Is it installed?"
    echo ""
    echo "Try running:"
    echo "npm install --save-dev ${linter_name}"
    fi

    View Slide

  81. View Slide

  82. #!/bin/bash
    executable=$(npm bin)/staged-files
    linter_name="stylelint"
    linter_path=$(npm bin)/stylelint
    lint_extensions="**/*.@(css|scss|less|styl)"
    if [[ -f "${linter_path}" ]]; then
    echo "Running ${linter_name} on git staged files: $
    {lint_extensions}"
    ${executable} "${lint_extensions}" -- ${linter_path}
    else
    echo "Could not find ${linter_name} at $
    {linter_path}. Is it installed?"
    echo ""
    echo "Try running:"
    echo "npm install --save-dev ${linter_name}"
    fi

    View Slide

  83. #!/bin/bash
    executable=$(npm bin)/staged-files
    linter_name="flow"
    linter_path=$(npm bin)/flow
    lint_extensions="**/*.@(js|jsx)"
    if [[ -f "${linter_path}" ]]; then
    echo "Running ${linter_name} on git staged files: $
    {lint_extensions}"
    ${executable} "${lint_extensions}" -- ${linter_path}
    else
    echo "Could not find ${linter_name} at $
    {linter_path}. Is it installed?"
    echo ""
    echo "Try running:"
    echo "npm install ${linter_name}-bin"
    fi

    View Slide

  84. #!/bin/bash
    executable=$(npm bin)/staged-files
    linter_name="jscs"
    linter_path=$(npm bin)/jscs
    lint_extensions="**/*.@(js|jsx)"
    if [[ -f "${linter_path}" ]]; then
    echo "Running ${linter_name} on git staged files: $
    {lint_extensions}"
    ${executable} "${lint_extensions}" -- ${linter_path}
    else
    echo "Could not find ${linter_name} at $
    {linter_path}. Is it installed?"
    echo ""
    echo "Try running:"
    echo "npm install --save-dev ${linter_name}"
    fi

    View Slide

  85. DRY

    View Slide

  86. Present

    View Slide

  87. lint-staged is a tool that
    • Can run any task
    • Easy to install via npm
    • Easy to distribute across the team (.lintstagedrc)
    • Easy to use (DX!)

    View Slide

  88. Future?

    View Slide

  89. View Slide

  90. View Slide

  91. View Slide

  92. View Slide

  93. View Slide

  94. View Slide

  95. Open Source = ❤

    View Slide

  96. https://github.com/okonet/lint-staged

    View Slide

  97. Maintainers ❤

    View Slide

  98. View Slide

  99. Recap

    View Slide

  100. View Slide

  101. Please solve real problems!

    View Slide

  102. Thank You!

    View Slide

  103. Andrey Okonetchnikov
    @okonetchnikov
    http://okonet.ru
    https://github.com/okonet

    View Slide