UNPKG

18.7 kBMarkdownView Raw
1# eslint-plugin-unicorn [![Coverage Status](https://codecov.io/gh/sindresorhus/eslint-plugin-unicorn/branch/main/graph/badge.svg)](https://codecov.io/gh/sindresorhus/eslint-plugin-unicorn/branch/main)
2
3<img src="https://cloud.githubusercontent.com/assets/170270/18659176/1cc373d0-7f33-11e6-890f-0ba35362ee7e.jpg" width="180" align="right">
4
5> Various awesome ESLint rules
6
7You might want to check out [XO](https://github.com/xojs/xo), which includes this plugin.
8
9[**Propose or contribute a new rule ➡**](.github/contributing.md)
10
11## Install
12
13```console
14$ npm install --save-dev eslint eslint-plugin-unicorn
15```
16
17## Usage
18
19Configure it in `package.json`.
20
21<!-- Do not manually modify this table. Run: `npm run generate-usage-example` -->
22<!-- USAGE_EXAMPLE_START -->
23```json
24{
25 "name": "my-awesome-project",
26 "eslintConfig": {
27 "env": {
28 "es6": true
29 },
30 "parserOptions": {
31 "ecmaVersion": 2021,
32 "sourceType": "module"
33 },
34 "plugins": [
35 "unicorn"
36 ],
37 "rules": {
38 "unicorn/better-regex": "error",
39 "unicorn/catch-error-name": "error",
40 "unicorn/consistent-destructuring": "error",
41 "unicorn/consistent-function-scoping": "error",
42 "unicorn/custom-error-definition": "off",
43 "unicorn/empty-brace-spaces": "error",
44 "unicorn/error-message": "error",
45 "unicorn/escape-case": "error",
46 "unicorn/expiring-todo-comments": "error",
47 "unicorn/explicit-length-check": "error",
48 "unicorn/filename-case": "error",
49 "unicorn/import-index": "off",
50 "unicorn/import-style": "error",
51 "unicorn/new-for-builtins": "error",
52 "unicorn/no-abusive-eslint-disable": "error",
53 "unicorn/no-array-callback-reference": "error",
54 "unicorn/no-array-for-each": "error",
55 "unicorn/no-array-method-this-argument": "error",
56 "unicorn/no-array-push-push": "error",
57 "unicorn/no-array-reduce": "error",
58 "unicorn/no-console-spaces": "error",
59 "unicorn/no-document-cookie": "error",
60 "unicorn/no-for-loop": "error",
61 "unicorn/no-hex-escape": "error",
62 "unicorn/no-instanceof-array": "error",
63 "unicorn/no-keyword-prefix": "off",
64 "unicorn/no-lonely-if": "error",
65 "no-nested-ternary": "off",
66 "unicorn/no-nested-ternary": "error",
67 "unicorn/no-new-array": "error",
68 "unicorn/no-new-buffer": "error",
69 "unicorn/no-null": "error",
70 "unicorn/no-object-as-default-parameter": "error",
71 "unicorn/no-process-exit": "error",
72 "unicorn/no-static-only-class": "error",
73 "unicorn/no-this-assignment": "error",
74 "unicorn/no-unreadable-array-destructuring": "error",
75 "unicorn/no-unsafe-regex": "off",
76 "unicorn/no-unused-properties": "off",
77 "unicorn/no-useless-undefined": "error",
78 "unicorn/no-zero-fractions": "error",
79 "unicorn/number-literal-case": "error",
80 "unicorn/numeric-separators-style": "error",
81 "unicorn/prefer-add-event-listener": "error",
82 "unicorn/prefer-array-find": "error",
83 "unicorn/prefer-array-flat": "error",
84 "unicorn/prefer-array-flat-map": "error",
85 "unicorn/prefer-array-index-of": "error",
86 "unicorn/prefer-array-some": "error",
87 "unicorn/prefer-at": "off",
88 "unicorn/prefer-date-now": "error",
89 "unicorn/prefer-default-parameters": "error",
90 "unicorn/prefer-dom-node-append": "error",
91 "unicorn/prefer-dom-node-dataset": "error",
92 "unicorn/prefer-dom-node-remove": "error",
93 "unicorn/prefer-dom-node-text-content": "error",
94 "unicorn/prefer-includes": "error",
95 "unicorn/prefer-keyboard-event-key": "error",
96 "unicorn/prefer-math-trunc": "error",
97 "unicorn/prefer-modern-dom-apis": "error",
98 "unicorn/prefer-module": "error",
99 "unicorn/prefer-negative-index": "error",
100 "unicorn/prefer-node-protocol": "error",
101 "unicorn/prefer-number-properties": "error",
102 "unicorn/prefer-object-has-own": "off",
103 "unicorn/prefer-optional-catch-binding": "error",
104 "unicorn/prefer-prototype-methods": "error",
105 "unicorn/prefer-query-selector": "error",
106 "unicorn/prefer-reflect-apply": "error",
107 "unicorn/prefer-regexp-test": "error",
108 "unicorn/prefer-set-has": "error",
109 "unicorn/prefer-spread": "error",
110 "unicorn/prefer-string-replace-all": "off",
111 "unicorn/prefer-string-slice": "error",
112 "unicorn/prefer-string-starts-ends-with": "error",
113 "unicorn/prefer-string-trim-start-end": "error",
114 "unicorn/prefer-switch": "error",
115 "unicorn/prefer-ternary": "error",
116 "unicorn/prefer-top-level-await": "off",
117 "unicorn/prefer-type-error": "error",
118 "unicorn/prevent-abbreviations": "error",
119 "unicorn/require-array-join-separator": "error",
120 "unicorn/require-number-to-fixed-digits-argument": "error",
121 "unicorn/require-post-message-target-origin": "error",
122 "unicorn/string-content": "off",
123 "unicorn/throw-new-error": "error"
124 }
125 }
126}
127```
128<!-- USAGE_EXAMPLE_END -->
129
130## Rules
131
132Each rule has emojis denoting:
133
134* ✅ if it belongs to the `recommended` configuration
135* 🔧 if some problems reported by the rule are automatically fixable by the `--fix` [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) option
136* 💡 if some problems reported by the rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions)
137
138<!-- Do not manually modify this table. Run: `npm run generate-rules-table` -->
139<!-- RULES_TABLE_START -->
140
141| Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Description | ✅ | 🔧 | 💡 |
142| :-- | :-- | :-- | :-- | :-- |
143| [better-regex](docs/rules/better-regex.md) | Improve regexes by making them shorter, consistent, and safer. | ✅ | 🔧 | |
144| [catch-error-name](docs/rules/catch-error-name.md) | Enforce a specific parameter name in catch clauses. | ✅ | 🔧 | |
145| [consistent-destructuring](docs/rules/consistent-destructuring.md) | Use destructured variables over properties. | ✅ | 🔧 | 💡 |
146| [consistent-function-scoping](docs/rules/consistent-function-scoping.md) | Move function definitions to the highest possible scope. | ✅ | | |
147| [custom-error-definition](docs/rules/custom-error-definition.md) | Enforce correct `Error` subclassing. | | 🔧 | |
148| [empty-brace-spaces](docs/rules/empty-brace-spaces.md) | Enforce no spaces between braces. | ✅ | 🔧 | |
149| [error-message](docs/rules/error-message.md) | Enforce passing a `message` value when creating a built-in error. | ✅ | | |
150| [escape-case](docs/rules/escape-case.md) | Require escape sequences to use uppercase values. | ✅ | 🔧 | |
151| [expiring-todo-comments](docs/rules/expiring-todo-comments.md) | Add expiration conditions to TODO comments. | ✅ | | |
152| [explicit-length-check](docs/rules/explicit-length-check.md) | Enforce explicitly comparing the `length` or `size` property of a value. | ✅ | 🔧 | 💡 |
153| [filename-case](docs/rules/filename-case.md) | Enforce a case style for filenames. | ✅ | | |
154| [import-index](docs/rules/import-index.md) | Enforce importing index files with `.`. | | 🔧 | |
155| [import-style](docs/rules/import-style.md) | Enforce specific import styles per module. | ✅ | | |
156| [new-for-builtins](docs/rules/new-for-builtins.md) | Enforce the use of `new` for all builtins, except `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. | ✅ | 🔧 | |
157| [no-abusive-eslint-disable](docs/rules/no-abusive-eslint-disable.md) | Enforce specifying rules to disable in `eslint-disable` comments. | ✅ | | |
158| [no-array-callback-reference](docs/rules/no-array-callback-reference.md) | Prevent passing a function reference directly to iterator methods. | ✅ | | 💡 |
159| [no-array-for-each](docs/rules/no-array-for-each.md) | Prefer `for…of` over `Array#forEach(…)`. | ✅ | 🔧 | |
160| [no-array-method-this-argument](docs/rules/no-array-method-this-argument.md) | Disallow using the `this` argument in array methods. | ✅ | 🔧 | 💡 |
161| [no-array-push-push](docs/rules/no-array-push-push.md) | Enforce combining multiple `Array#push()` into one call. | ✅ | 🔧 | 💡 |
162| [no-array-reduce](docs/rules/no-array-reduce.md) | Disallow `Array#reduce()` and `Array#reduceRight()`. | ✅ | | |
163| [no-console-spaces](docs/rules/no-console-spaces.md) | Do not use leading/trailing space between `console.log` parameters. | ✅ | 🔧 | |
164| [no-document-cookie](docs/rules/no-document-cookie.md) | Do not use `document.cookie` directly. | ✅ | | |
165| [no-for-loop](docs/rules/no-for-loop.md) | Do not use a `for` loop that can be replaced with a `for-of` loop. | ✅ | 🔧 | |
166| [no-hex-escape](docs/rules/no-hex-escape.md) | Enforce the use of Unicode escapes instead of hexadecimal escapes. | ✅ | 🔧 | |
167| [no-instanceof-array](docs/rules/no-instanceof-array.md) | Require `Array.isArray()` instead of `instanceof Array`. | ✅ | 🔧 | |
168| [no-keyword-prefix](docs/rules/no-keyword-prefix.md) | Disallow identifiers starting with `new` or `class`. | | | |
169| [no-lonely-if](docs/rules/no-lonely-if.md) | Disallow `if` statements as the only statement in `if` blocks without `else`. | ✅ | 🔧 | |
170| [no-nested-ternary](docs/rules/no-nested-ternary.md) | Disallow nested ternary expressions. | ✅ | 🔧 | |
171| [no-new-array](docs/rules/no-new-array.md) | Disallow `new Array()`. | ✅ | 🔧 | 💡 |
172| [no-new-buffer](docs/rules/no-new-buffer.md) | Enforce the use of `Buffer.from()` and `Buffer.alloc()` instead of the deprecated `new Buffer()`. | ✅ | 🔧 | 💡 |
173| [no-null](docs/rules/no-null.md) | Disallow the use of the `null` literal. | ✅ | 🔧 | 💡 |
174| [no-object-as-default-parameter](docs/rules/no-object-as-default-parameter.md) | Disallow the use of objects as default parameters. | ✅ | | |
175| [no-process-exit](docs/rules/no-process-exit.md) | Disallow `process.exit()`. | ✅ | | |
176| [no-static-only-class](docs/rules/no-static-only-class.md) | Forbid classes that only have static members. | ✅ | 🔧 | |
177| [no-this-assignment](docs/rules/no-this-assignment.md) | Disallow assigning `this` to a variable. | ✅ | | |
178| [no-unreadable-array-destructuring](docs/rules/no-unreadable-array-destructuring.md) | Disallow unreadable array destructuring. | ✅ | 🔧 | |
179| [no-unsafe-regex](docs/rules/no-unsafe-regex.md) | Disallow unsafe regular expressions. | | | |
180| [no-unused-properties](docs/rules/no-unused-properties.md) | Disallow unused object properties. | | | |
181| [no-useless-undefined](docs/rules/no-useless-undefined.md) | Disallow useless `undefined`. | ✅ | 🔧 | |
182| [no-zero-fractions](docs/rules/no-zero-fractions.md) | Disallow number literals with zero fractions or dangling dots. | ✅ | 🔧 | |
183| [number-literal-case](docs/rules/number-literal-case.md) | Enforce proper case for numeric literals. | ✅ | 🔧 | |
184| [numeric-separators-style](docs/rules/numeric-separators-style.md) | Enforce the style of numeric separators by correctly grouping digits. | ✅ | 🔧 | |
185| [prefer-add-event-listener](docs/rules/prefer-add-event-listener.md) | Prefer `.addEventListener()` and `.removeEventListener()` over `on`-functions. | ✅ | 🔧 | |
186| [prefer-array-find](docs/rules/prefer-array-find.md) | Prefer `.find(…)` over the first element from `.filter(…)`. | ✅ | 🔧 | 💡 |
187| [prefer-array-flat](docs/rules/prefer-array-flat.md) | Prefer `Array#flat()` over legacy techniques to flatten arrays. | ✅ | 🔧 | |
188| [prefer-array-flat-map](docs/rules/prefer-array-flat-map.md) | Prefer `.flatMap(…)` over `.map(…).flat()`. | ✅ | 🔧 | |
189| [prefer-array-index-of](docs/rules/prefer-array-index-of.md) | Prefer `Array#indexOf()` over `Array#findIndex()` when looking for the index of an item. | ✅ | 🔧 | 💡 |
190| [prefer-array-some](docs/rules/prefer-array-some.md) | Prefer `.some(…)` over `.filter(…).length` check and `.find(…)`. | ✅ | 🔧 | 💡 |
191| [prefer-at](docs/rules/prefer-at.md) | Prefer `.at()` method for index access and `String#charAt()`. | | 🔧 | 💡 |
192| [prefer-date-now](docs/rules/prefer-date-now.md) | Prefer `Date.now()` to get the number of milliseconds since the Unix Epoch. | ✅ | 🔧 | |
193| [prefer-default-parameters](docs/rules/prefer-default-parameters.md) | Prefer default parameters over reassignment. | ✅ | 🔧 | 💡 |
194| [prefer-dom-node-append](docs/rules/prefer-dom-node-append.md) | Prefer `Node#append()` over `Node#appendChild()`. | ✅ | 🔧 | |
195| [prefer-dom-node-dataset](docs/rules/prefer-dom-node-dataset.md) | Prefer using `.dataset` on DOM elements over `.setAttribute(…)`. | ✅ | 🔧 | |
196| [prefer-dom-node-remove](docs/rules/prefer-dom-node-remove.md) | Prefer `childNode.remove()` over `parentNode.removeChild(childNode)`. | ✅ | 🔧 | 💡 |
197| [prefer-dom-node-text-content](docs/rules/prefer-dom-node-text-content.md) | Prefer `.textContent` over `.innerText`. | ✅ | 🔧 | |
198| [prefer-includes](docs/rules/prefer-includes.md) | Prefer `.includes()` over `.indexOf()` and `Array#some()` when checking for existence or non-existence. | ✅ | 🔧 | 💡 |
199| [prefer-keyboard-event-key](docs/rules/prefer-keyboard-event-key.md) | Prefer `KeyboardEvent#key` over `KeyboardEvent#keyCode`. | ✅ | 🔧 | |
200| [prefer-math-trunc](docs/rules/prefer-math-trunc.md) | Enforce the use of `Math.trunc` instead of bitwise operators. | ✅ | 🔧 | 💡 |
201| [prefer-modern-dom-apis](docs/rules/prefer-modern-dom-apis.md) | Prefer `.before()` over `.insertBefore()`, `.replaceWith()` over `.replaceChild()`, prefer one of `.before()`, `.after()`, `.append()` or `.prepend()` over `insertAdjacentText()` and `insertAdjacentElement()`. | ✅ | 🔧 | |
202| [prefer-module](docs/rules/prefer-module.md) | Prefer JavaScript modules (ESM) over CommonJS. | ✅ | 🔧 | 💡 |
203| [prefer-negative-index](docs/rules/prefer-negative-index.md) | Prefer negative index over `.length - index` for `{String,Array,TypedArray}#slice()`, `Array#splice()` and `Array#at()`. | ✅ | 🔧 | |
204| [prefer-node-protocol](docs/rules/prefer-node-protocol.md) | Prefer using the `node:` protocol when importing Node.js builtin modules. | ✅ | 🔧 | |
205| [prefer-number-properties](docs/rules/prefer-number-properties.md) | Prefer `Number` static properties over global ones. | ✅ | 🔧 | 💡 |
206| [prefer-object-has-own](docs/rules/prefer-object-has-own.md) | Prefer `Object.hasOwn(…)` over `Object.prototype.hasOwnProperty.call(…)`. | | 🔧 | |
207| [prefer-optional-catch-binding](docs/rules/prefer-optional-catch-binding.md) | Prefer omitting the `catch` binding parameter. | ✅ | 🔧 | |
208| [prefer-prototype-methods](docs/rules/prefer-prototype-methods.md) | Prefer borrowing methods from the prototype instead of the instance. | ✅ | 🔧 | |
209| [prefer-query-selector](docs/rules/prefer-query-selector.md) | Prefer `.querySelector()` over `.getElementById()`, `.querySelectorAll()` over `.getElementsByClassName()` and `.getElementsByTagName()`. | ✅ | 🔧 | |
210| [prefer-reflect-apply](docs/rules/prefer-reflect-apply.md) | Prefer `Reflect.apply()` over `Function#apply()`. | ✅ | 🔧 | |
211| [prefer-regexp-test](docs/rules/prefer-regexp-test.md) | Prefer `RegExp#test()` over `String#match()` and `RegExp#exec()`. | ✅ | 🔧 | |
212| [prefer-set-has](docs/rules/prefer-set-has.md) | Prefer `Set#has()` over `Array#includes()` when checking for existence or non-existence. | ✅ | 🔧 | 💡 |
213| [prefer-spread](docs/rules/prefer-spread.md) | Prefer the spread operator over `Array.from(…)`, `Array#concat(…)` and `Array#slice()`. | ✅ | 🔧 | 💡 |
214| [prefer-string-replace-all](docs/rules/prefer-string-replace-all.md) | Prefer `String#replaceAll()` over regex searches with the global flag. | | 🔧 | |
215| [prefer-string-slice](docs/rules/prefer-string-slice.md) | Prefer `String#slice()` over `String#substr()` and `String#substring()`. | ✅ | 🔧 | |
216| [prefer-string-starts-ends-with](docs/rules/prefer-string-starts-ends-with.md) | Prefer `String#startsWith()` & `String#endsWith()` over `RegExp#test()`. | ✅ | 🔧 | 💡 |
217| [prefer-string-trim-start-end](docs/rules/prefer-string-trim-start-end.md) | Prefer `String#trimStart()` / `String#trimEnd()` over `String#trimLeft()` / `String#trimRight()`. | ✅ | 🔧 | |
218| [prefer-switch](docs/rules/prefer-switch.md) | Prefer `switch` over multiple `else-if`. | ✅ | 🔧 | |
219| [prefer-ternary](docs/rules/prefer-ternary.md) | Prefer ternary expressions over simple `if-else` statements. | ✅ | 🔧 | |
220| [prefer-top-level-await](docs/rules/prefer-top-level-await.md) | Prefer top-level await over top-level promises and async function calls. | | | 💡 |
221| [prefer-type-error](docs/rules/prefer-type-error.md) | Enforce throwing `TypeError` in type checking conditions. | ✅ | 🔧 | |
222| [prevent-abbreviations](docs/rules/prevent-abbreviations.md) | Prevent abbreviations. | ✅ | 🔧 | |
223| [require-array-join-separator](docs/rules/require-array-join-separator.md) | Enforce using the separator argument with `Array#join()`. | ✅ | 🔧 | |
224| [require-number-to-fixed-digits-argument](docs/rules/require-number-to-fixed-digits-argument.md) | Enforce using the digits argument with `Number#toFixed()`. | ✅ | 🔧 | |
225| [require-post-message-target-origin](docs/rules/require-post-message-target-origin.md) | Enforce using the `targetOrigin` argument with `window.postMessage()`. | ✅ | | 💡 |
226| [string-content](docs/rules/string-content.md) | Enforce better string content. | | 🔧 | 💡 |
227| [throw-new-error](docs/rules/throw-new-error.md) | Require `new` when throwing an error. | ✅ | 🔧 | |
228
229<!-- RULES_TABLE_END -->
230
231## Deprecated Rules
232
233See [docs/deprecated-rules.md](docs/deprecated-rules.md)
234
235## Recommended config
236
237This plugin exports a [`recommended` config](index.js) that enforces good practices.
238
239Enable it in your `package.json` with the `extends` option:
240
241```json
242{
243 "name": "my-awesome-project",
244 "eslintConfig": {
245 "extends": "plugin:unicorn/recommended"
246 }
247}
248```
249
250See the [ESLint docs](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files) for more information about extending config files.
251
252**Note**: This config will also enable the correct [parser options](https://eslint.org/docs/user-guide/configuring/language-options#specifying-parser-options) and [environment](https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments).
253
254## Maintainers
255
256- [Sindre Sorhus](https://github.com/sindresorhus)
257- [Adam Babcock](https://github.com/MrHen)
258- [futpib](https://github.com/futpib)
259- [Fisker Cheung](https://github.com/fisker)
260
261###### Former
262
263- [Jeroen Engels](https://github.com/jfmengels)
264- [Sam Verschueren](https://github.com/SamVerschueren)