|
| 1 | +<!DOCTYPE html> |
| 2 | +<!-- Copyright (C) 2020 Matthew "strager" Glazar --> |
| 3 | +<!-- See end of file for extended copyright information. --> |
| 4 | +<html> |
| 5 | + <head> |
| 6 | + <%- await include("../../common-head.ejs.html") %> |
| 7 | + <title> |
| 8 | + Faster, easier, friendlier: how quick-lint-js will take over ESLint |
| 9 | + </title> |
| 10 | + <link href="../../main.css" rel="stylesheet" /> |
| 11 | + <style> |
| 12 | + figcaption { |
| 13 | + margin: 0.5rem 0; |
| 14 | + text-align: center; |
| 15 | + } |
| 16 | + |
| 17 | + .inline-logo { |
| 18 | + height: 1em; |
| 19 | + width: 1em; |
| 20 | + vertical-align: text-bottom; |
| 21 | + } |
| 22 | + |
| 23 | + .eslint-comparison { |
| 24 | + display: grid; |
| 25 | + grid-template-areas: "eslint qljs"; |
| 26 | + grid-template-columns: 50% 50%; |
| 27 | + grid-gap: 0.5rem; |
| 28 | + } |
| 29 | + .eslint-comparison .example p { |
| 30 | + margin-top: 0.5rem; |
| 31 | + font-size: 0.9em; |
| 32 | + } |
| 33 | + .eslint-comparison .example pre { |
| 34 | + margin: 0; |
| 35 | + border: 1px dashed rgba(0, 0, 0, 0.3); |
| 36 | + background-color: rgba(0, 0, 0, 0.03); |
| 37 | + padding: 0.5rem; |
| 38 | + } |
| 39 | + @media (prefers-color-scheme: dark) { |
| 40 | + .eslint-comparison .example pre { |
| 41 | + border-color: rgba(255, 255, 255, 0.3); |
| 42 | + background-color: rgba(0, 0, 0, 0.1); |
| 43 | + } |
| 44 | + } |
| 45 | + .eslint-comparison code { |
| 46 | + font-size: 1em; |
| 47 | + } |
| 48 | + .eslint-comparison figcaption { |
| 49 | + font-weight: bold; |
| 50 | + } |
| 51 | + </style> |
| 52 | + </head> |
| 53 | + <body> |
| 54 | + <% function callsToAction() { %> |
| 55 | + <ul class="install-options"> |
| 56 | + <li> |
| 57 | + <a href="../../install/" |
| 58 | + ><img |
| 59 | + class="install-logo" |
| 60 | + src="../../favicon-32x32.png" |
| 61 | + alt="" |
| 62 | + width="19" |
| 63 | + height="19" |
| 64 | + /> |
| 65 | + install quick-lint-js</a |
| 66 | + > |
| 67 | + </li> |
| 68 | + <li><a href="../../demo/">🌐 try in your browser</a></li> |
| 69 | + <li> |
| 70 | + <a href="https://github.com/quick-lint/quick-lint-js" |
| 71 | + ><img |
| 72 | + class="install-logo" |
| 73 | + src="../../github.svg" |
| 74 | + alt="" |
| 75 | + width="19" |
| 76 | + height="19" |
| 77 | + /> |
| 78 | + code on GitHub</a |
| 79 | + > |
| 80 | + </li> |
| 81 | + </ul> |
| 82 | + <% } %> |
| 83 | + |
| 84 | + <header><%- await include("../../common-nav.ejs.html") %></header> |
| 85 | + |
| 86 | + <main> |
| 87 | + <h2> |
| 88 | + Faster, easier, friendlier: how quick-lint-js will take over ESLint |
| 89 | + </h2> |
| 90 | + <p><time>2021-12-13</time></p> |
| 91 | + |
| 92 | + <p> |
| 93 | + ESLint finds bugs. Or does it? ESLint is so slow that you don't bother |
| 94 | + until you make a PR. So what's the point? |
| 95 | + </p> |
| 96 | + |
| 97 | + <p> |
| 98 | + quick-lint-js is different. Instantly find bugs in JavaScript, right in |
| 99 | + your editor. Waste less time fiddling with ESLint plugins and configs |
| 100 | + and more time tweaking margins and rounded corners. |
| 101 | + </p> |
| 102 | + |
| 103 | + <p>We are proud to announce version 1.0 of quick-lint-js!</p> |
| 104 | + |
| 105 | + <%- callsToAction() %> |
| 106 | + |
| 107 | + <p>Notable quick-lint-js features:</p> |
| 108 | + <ul> |
| 109 | + <li> |
| 110 | + Over <a href="../../benchmarks/">50× faster</a> than ESLint, Flow, and |
| 111 | + TypeScript |
| 112 | + </li> |
| 113 | + <li> |
| 114 | + <a href="../../install/vscode/" |
| 115 | + ><img |
| 116 | + class="inline-logo" |
| 117 | + src="../../vscode.png" |
| 118 | + alt="" |
| 119 | + width="19" |
| 120 | + height="19" |
| 121 | + /> |
| 122 | + VS Code</a |
| 123 | + >, |
| 124 | + <a href="../../install/emacs/" |
| 125 | + ><img |
| 126 | + class="inline-logo" |
| 127 | + src="../../emacs.svg" |
| 128 | + alt="" |
| 129 | + width="19" |
| 130 | + height="19" |
| 131 | + /> |
| 132 | + Emacs</a |
| 133 | + >, |
| 134 | + <a href="../../install/vim/" |
| 135 | + ><img |
| 136 | + class="inline-logo" |
| 137 | + src="../../vim.gif" |
| 138 | + alt="" |
| 139 | + width="19" |
| 140 | + height="19" |
| 141 | + /> |
| 142 | + Vim</a |
| 143 | + >, and |
| 144 | + <a href="../../install/neovim/" |
| 145 | + ><img |
| 146 | + class="inline-logo" |
| 147 | + src="../../neovim.svg" |
| 148 | + alt="" |
| 149 | + width="19" |
| 150 | + height="19" |
| 151 | + /> |
| 152 | + Neovim</a |
| 153 | + > |
| 154 | + plugins |
| 155 | + </li> |
| 156 | + <li>Documented <a href="../../errors/">errors with examples</a></li> |
| 157 | + <li> |
| 158 | + Instant setup; no config required (no |
| 159 | + <code>npx eslint --init</code> every. single. project) |
| 160 | + </li> |
| 161 | + <li>World's fastest JavaScript editor plugin 🚀🚀🚀</li> |
| 162 | + <li> |
| 163 | + <a href="../syntax-errors-2021/" |
| 164 | + >Better error reporting than ESLint</a |
| 165 | + > |
| 166 | + for syntax errors |
| 167 | + </li> |
| 168 | + </ul> |
| 169 | + |
| 170 | + <figure> |
| 171 | + <picture |
| 172 | + style="width: 100%; height: auto" |
| 173 | + width="1324" |
| 174 | + height="526" |
| 175 | + title="quick-lint-js running in Visual Studio Code" |
| 176 | + > |
| 177 | + <source srcset="../../vscode-demo.webp" type="image/webp" /> |
| 178 | + <img |
| 179 | + src="../../vscode-demo.png" |
| 180 | + style="width: 100%; height: auto" |
| 181 | + alt="quick-lint-js running in Visual Studio Code" |
| 182 | + width="1324" |
| 183 | + height="526" |
| 184 | + /> |
| 185 | + </picture> |
| 186 | + </figure> |
| 187 | + |
| 188 | + <p>How does quick-lint-js compare to ESLint? See for yourself:</p> |
| 189 | + <div class="eslint-comparison"> |
| 190 | + <figure style="grid-area: eslint"> |
| 191 | + <figcaption>ESLint</figcaption> |
| 192 | + <div class="example"> |
| 193 | + <pre><code class="javascript">function getDefaultConfig() { |
| 194 | + return |
| 195 | + { |
| 196 | + dbHost: "localhost", |
| 197 | + <mark data-message="Parsing error: Unexpected token }" data-severity="error">}</mark>; |
| 198 | +}</code></pre> |
| 199 | + <p>Parsing error: Unexpected token }</p> |
| 200 | + </div> |
| 201 | + </figure> |
| 202 | + <figure style="grid-area: qljs"> |
| 203 | + <figcaption>quick-lint-js</figcaption> |
| 204 | + <div class="example"> |
| 205 | + <pre><code class="javascript">function getDefaultConfig() { |
| 206 | + <mark data-code="E0179" data-message="return statement returns nothing (undefined)" data-severity="error">return</mark> |
| 207 | + { |
| 208 | + dbHost: "localhost", |
| 209 | + }; |
| 210 | +}</code></pre> |
| 211 | + <p> |
| 212 | + return statement returns nothing (undefined) [<a |
| 213 | + href="../../errors/#E0179" |
| 214 | + >E0179</a |
| 215 | + >] |
| 216 | + </p> |
| 217 | + </div> |
| 218 | + </figure> |
| 219 | + </div> |
| 220 | + |
| 221 | + <div class="eslint-comparison"> |
| 222 | + <figure style="grid-area: eslint"> |
| 223 | + <figcaption>ESLint</figcaption> |
| 224 | + <div class="example"> |
| 225 | + <pre><code class="javascript">app.get("/", await (req, res) <mark data-message="Parsing error: Unexpected token =>" data-severity="error">=</mark>> { |
| 226 | + await doHomePage(req, res); |
| 227 | +});</code></pre> |
| 228 | + <p>Parsing error: Unexpected token =></p> |
| 229 | + </div> |
| 230 | + </figure> |
| 231 | + <figure style="grid-area: qljs"> |
| 232 | + <figcaption>quick-lint-js</figcaption> |
| 233 | + <div class="example"> |
| 234 | + <pre><code class="javascript">app.get("/", <mark data-code="E0178" data-message="'await' cannot be followed by an arrow function; use 'async' instead" data-severity="error">await</mark> (req, res) => { |
| 235 | + await doHomePage(req, res); |
| 236 | +});</code></pre> |
| 237 | + <p> |
| 238 | + 'await' cannot be followed by an arrow function; use 'async' |
| 239 | + instead [<a href="../../errors/#E0178">E0178</a>] |
| 240 | + </p> |
| 241 | + </div> |
| 242 | + </figure> |
| 243 | + </div> |
| 244 | + |
| 245 | + <div class="eslint-comparison"> |
| 246 | + <figure style="grid-area: eslint"> |
| 247 | + <figcaption>ESLint</figcaption> |
| 248 | + <div class="example"> |
| 249 | + <pre><code class="javascript">function readConfig(configFilePath) { |
| 250 | + let data = await <mark data-message="Parsing error: Unexpected token readFile" data-severity="error">readFile</mark>(configFilePath); |
| 251 | + return parseConfig(data); |
| 252 | +}</code></pre> |
| 253 | + <p>Parsing error: Unexpected token readFile</p> |
| 254 | + </div> |
| 255 | + </figure> |
| 256 | + <figure style="grid-area: qljs"> |
| 257 | + <figcaption>quick-lint-js</figcaption> |
| 258 | + <div class="example"> |
| 259 | + <pre><code class="javascript">function readConfig(configFilePath) { |
| 260 | + let data = <mark data-code="E0162" data-message="'await' is only allowed in async functions" data-severity="error">await</mark> readFile(configFilePath); |
| 261 | + return parseConfig(data); |
| 262 | +}</code></pre> |
| 263 | + <p> |
| 264 | + 'await' is only allowed in async functions [<a |
| 265 | + href="../../errors/#E0162" |
| 266 | + >E0162</a |
| 267 | + >] |
| 268 | + </p> |
| 269 | + </div> |
| 270 | + </figure> |
| 271 | + </div> |
| 272 | + |
| 273 | + <p> |
| 274 | + What should we work on next? |
| 275 | + <a href="https://github.com/quick-lint/quick-lint-js/issues/327" |
| 276 | + >Suggest features for quick-lint-js.</a |
| 277 | + > |
| 278 | + </p> |
| 279 | + |
| 280 | + <p> |
| 281 | + quick-lint-js was born on <time>March 31, 2020</time>, after |
| 282 | + frustrations with ESLint and Flow. 20 months and 2700 patches later, |
| 283 | + quick-lint-js is finally ready for beginners and experts alike. Through |
| 284 | + our <a href="../../hiring/">hiring program</a>, we have paid |
| 285 | + <strong>311 USD</strong> to contributors. |
| 286 | + </p> |
| 287 | + |
| 288 | + <%- callsToAction() %> |
| 289 | + |
| 290 | + <p> |
| 291 | + Written by <a href="https://strager.net/contact.html">strager</a>, lead |
| 292 | + developer of quick-lint-js. |
| 293 | + </p> |
| 294 | + |
| 295 | + <script src="../../error-box.bundled.js"></script> |
| 296 | + </main> |
| 297 | + </body> |
| 298 | +</html> |
| 299 | + |
| 300 | +<!-- |
| 301 | +quick-lint-js finds bugs in JavaScript programs. |
| 302 | +Copyright (C) 2020 Matthew "strager" Glazar |
| 303 | +
|
| 304 | +This file is part of quick-lint-js. |
| 305 | +
|
| 306 | +quick-lint-js is free software: you can redistribute it and/or modify |
| 307 | +it under the terms of the GNU General Public License as published by |
| 308 | +the Free Software Foundation, either version 3 of the License, or |
| 309 | +(at your option) any later version. |
| 310 | +
|
| 311 | +quick-lint-js is distributed in the hope that it will be useful, |
| 312 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 313 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 314 | +GNU General Public License for more details. |
| 315 | +
|
| 316 | +You should have received a copy of the GNU General Public License |
| 317 | +along with quick-lint-js. If not, see <https://www.gnu.org/licenses/>. |
| 318 | +--> |
0 commit comments