1 | # eslint-plugin-unicorn [![Build Status](https://github.com/sindresorhus/eslint-plugin-unicorn/workflows/CI/badge.svg?branch=master)](https://github.com/sindresorhus/eslint-plugin-unicorn/actions?query=branch%3Amaster+workflow%3ACI) [![Coverage Status](https://codecov.io/gh/sindresorhus/eslint-plugin-unicorn/branch/master/graph/badge.svg)](https://codecov.io/gh/sindresorhus/eslint-plugin-unicorn/branch/master)
|
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 |
|
7 | You 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 |
|
19 | Configure it in `package.json`.
|
20 |
|
21 | ```json
|
22 | {
|
23 | "name": "my-awesome-project",
|
24 | "eslintConfig": {
|
25 | "env": {
|
26 | "es6": true
|
27 | },
|
28 | "parserOptions": {
|
29 | "ecmaVersion": 2021,
|
30 | "sourceType": "module"
|
31 | },
|
32 | "plugins": [
|
33 | "unicorn"
|
34 | ],
|
35 | "rules": {
|
36 | "unicorn/better-regex": "error",
|
37 | "unicorn/catch-error-name": "error",
|
38 | "unicorn/consistent-function-scoping": "error",
|
39 | "unicorn/custom-error-definition": "off",
|
40 | "unicorn/error-message": "error",
|
41 | "unicorn/escape-case": "error",
|
42 | "unicorn/expiring-todo-comments": "error",
|
43 | "unicorn/explicit-length-check": "error",
|
44 | "unicorn/filename-case": "error",
|
45 | "unicorn/import-index": "error",
|
46 | "unicorn/import-style": "error",
|
47 | "unicorn/new-for-builtins": "error",
|
48 | "unicorn/no-abusive-eslint-disable": "error",
|
49 | "unicorn/no-array-instanceof": "error",
|
50 | "unicorn/no-console-spaces": "error",
|
51 | "unicorn/no-fn-reference-in-iterator": "error",
|
52 | "unicorn/no-for-loop": "error",
|
53 | "unicorn/no-hex-escape": "error",
|
54 | "unicorn/no-keyword-prefix": "off",
|
55 | "no-nested-ternary": "off",
|
56 | "unicorn/no-nested-ternary": "error",
|
57 | "unicorn/no-new-buffer": "error",
|
58 | "unicorn/no-null": "error",
|
59 | "unicorn/no-object-as-default-parameter": "error",
|
60 | "unicorn/no-process-exit": "error",
|
61 | "unicorn/no-reduce": "error",
|
62 | "unicorn/no-unreadable-array-destructuring": "error",
|
63 | "unicorn/no-unsafe-regex": "off",
|
64 | "unicorn/no-unused-properties": "off",
|
65 | "unicorn/no-useless-undefined": "error",
|
66 | "unicorn/no-zero-fractions": "error",
|
67 | "unicorn/number-literal-case": "error",
|
68 | "unicorn/numeric-separators-style": "off",
|
69 | "unicorn/prefer-add-event-listener": "error",
|
70 | "unicorn/prefer-array-find": "error",
|
71 | "unicorn/prefer-dataset": "error",
|
72 | "unicorn/prefer-event-key": "error",
|
73 | "unicorn/prefer-flat-map": "error",
|
74 | "unicorn/prefer-includes": "error",
|
75 | "unicorn/prefer-math-trunc": "error",
|
76 | "unicorn/prefer-modern-dom-apis": "error",
|
77 | "unicorn/prefer-negative-index": "error",
|
78 | "unicorn/prefer-node-append": "error",
|
79 | "unicorn/prefer-node-remove": "error",
|
80 | "unicorn/prefer-number-properties": "error",
|
81 | "unicorn/prefer-optional-catch-binding": "error",
|
82 | "unicorn/prefer-query-selector": "error",
|
83 | "unicorn/prefer-reflect-apply": "error",
|
84 | "unicorn/prefer-replace-all": "off",
|
85 | "unicorn/prefer-set-has": "error",
|
86 | "unicorn/prefer-spread": "error",
|
87 | "unicorn/prefer-starts-ends-with": "error",
|
88 | "unicorn/prefer-string-slice": "error",
|
89 | "unicorn/prefer-ternary": "off",
|
90 | "unicorn/prefer-text-content": "error",
|
91 | "unicorn/prefer-trim-start-end": "error",
|
92 | "unicorn/prefer-type-error": "error",
|
93 | "unicorn/prevent-abbreviations": "error",
|
94 | "unicorn/string-content": "off",
|
95 | "unicorn/throw-new-error": "error"
|
96 | }
|
97 | }
|
98 | }
|
99 | ```
|
100 |
|
101 | ## Rules
|
102 |
|
103 | - [better-regex](docs/rules/better-regex.md) - Improve regexes by making them shorter, consistent, and safer. *(fixable)*
|
104 | - [catch-error-name](docs/rules/catch-error-name.md) - Enforce a specific parameter name in catch clauses. *(fixable)*
|
105 | - [consistent-function-scoping](docs/rules/consistent-function-scoping.md) - Move function definitions to the highest possible scope.
|
106 | - [custom-error-definition](docs/rules/custom-error-definition.md) - Enforce correct `Error` subclassing. *(fixable)*
|
107 | - [error-message](docs/rules/error-message.md) - Enforce passing a `message` value when throwing a built-in error.
|
108 | - [escape-case](docs/rules/escape-case.md) - Require escape sequences to use uppercase values. *(fixable)*
|
109 | - [expiring-todo-comments](docs/rules/expiring-todo-comments.md) - Add expiration conditions to TODO comments.
|
110 | - [explicit-length-check](docs/rules/explicit-length-check.md) - Enforce explicitly comparing the `length` property of a value. *(partly fixable)*
|
111 | - [filename-case](docs/rules/filename-case.md) - Enforce a case style for filenames.
|
112 | - [import-index](docs/rules/import-index.md) - Enforce importing index files with `.`. *(fixable)*
|
113 | - [import-style](docs/rules/import-style.md) - Enforce specific import styles per module.
|
114 | - [new-for-builtins](docs/rules/new-for-builtins.md) - Enforce the use of `new` for all builtins, except `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. *(fixable)*
|
115 | - [no-abusive-eslint-disable](docs/rules/no-abusive-eslint-disable.md) - Enforce specifying rules to disable in `eslint-disable` comments.
|
116 | - [no-array-instanceof](docs/rules/no-array-instanceof.md) - Require `Array.isArray()` instead of `instanceof Array`. *(fixable)*
|
117 | - [no-console-spaces](docs/rules/no-console-spaces.md) - Do not use leading/trailing space between `console.log` parameters. *(fixable)*
|
118 | - [no-fn-reference-in-iterator](docs/rules/no-fn-reference-in-iterator.md) - Prevent passing a function reference directly to iterator methods.
|
119 | - [no-for-loop](docs/rules/no-for-loop.md) - Do not use a `for` loop that can be replaced with a `for-of` loop. *(partly fixable)*
|
120 | - [no-hex-escape](docs/rules/no-hex-escape.md) - Enforce the use of Unicode escapes instead of hexadecimal escapes. *(fixable)*
|
121 | - [no-keyword-prefix](docs/rules/no-keyword-prefix.md) - Disallow identifiers starting with `new` or `class`.
|
122 | - [no-nested-ternary](docs/rules/no-nested-ternary.md) - Disallow nested ternary expressions. *(partly fixable)*
|
123 | - [no-new-buffer](docs/rules/no-new-buffer.md) - Enforce the use of `Buffer.from()` and `Buffer.alloc()` instead of the deprecated `new Buffer()`. *(fixable)*
|
124 | - [no-null](docs/rules/no-null.md) - Disallow the use of the `null` literal.
|
125 | - [no-object-as-default-parameter](docs/rules/no-object-as-default-parameter.md) - Disallow the use of objects as default parameters.
|
126 | - [no-process-exit](docs/rules/no-process-exit.md) - Disallow `process.exit()`.
|
127 | - [no-reduce](docs/rules/no-reduce.md) - Disallow `Array#reduce()` and `Array#reduceRight()`.
|
128 | - [no-unreadable-array-destructuring](docs/rules/no-unreadable-array-destructuring.md) - Disallow unreadable array destructuring.
|
129 | - [no-unsafe-regex](docs/rules/no-unsafe-regex.md) - Disallow unsafe regular expressions.
|
130 | - [no-unused-properties](docs/rules/no-unused-properties.md) - Disallow unused object properties.
|
131 | - [no-useless-undefined](docs/rules/no-useless-undefined.md) - Disallow useless `undefined`. *(fixable)*
|
132 | - [no-zero-fractions](docs/rules/no-zero-fractions.md) - Disallow number literals with zero fractions or dangling dots. *(fixable)*
|
133 | - [number-literal-case](docs/rules/number-literal-case.md) - Enforce proper case for numeric literals. *(fixable)*
|
134 | - [numeric-separators-style](docs/rules/numeric-separators-style.md) - Enforce the style of numeric separators by correctly grouping digits. *(fixable)*
|
135 | - [prefer-add-event-listener](docs/rules/prefer-add-event-listener.md) - Prefer `.addEventListener()` and `.removeEventListener()` over `on`-functions. *(partly fixable)*
|
136 | - [prefer-array-find](docs/rules/prefer-array-find.md) - Prefer `.find(…)` over the first element from `.filter(…)`. *(partly fixable)*
|
137 | - [prefer-dataset](docs/rules/prefer-dataset.md) - Prefer using `.dataset` on DOM elements over `.setAttribute(…)`. *(fixable)*
|
138 | - [prefer-event-key](docs/rules/prefer-event-key.md) - Prefer `KeyboardEvent#key` over `KeyboardEvent#keyCode`. *(partly fixable)*
|
139 | - [prefer-flat-map](docs/rules/prefer-flat-map.md) - Prefer `.flatMap(…)` over `.map(…).flat()`. *(fixable)*
|
140 | - [prefer-includes](docs/rules/prefer-includes.md) - Prefer `.includes()` over `.indexOf()` when checking for existence or non-existence. *(fixable)*
|
141 | - [prefer-math-trunc](docs/rules/prefer-math-trunc.md) - Enforce the use of `Math.trunc` instead of bitwise operators. *(partly fixable)*
|
142 | - [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()`. *(fixable)*
|
143 | - [prefer-negative-index](docs/rules/prefer-negative-index.md) - Prefer negative index over `.length - index` for `{String,Array,TypedArray}#slice()` and `Array#splice()`. *(fixable)*
|
144 | - [prefer-node-append](docs/rules/prefer-node-append.md) - Prefer `Node#append()` over `Node#appendChild()`. *(fixable)*
|
145 | - [prefer-node-remove](docs/rules/prefer-node-remove.md) - Prefer `childNode.remove()` over `parentNode.removeChild(childNode)`. *(fixable)*
|
146 | - [prefer-number-properties](docs/rules/prefer-number-properties.md) - Prefer `Number` static properties over global ones. *(fixable)*
|
147 | - [prefer-optional-catch-binding](docs/rules/prefer-optional-catch-binding.md) - Prefer omitting the `catch` binding parameter. *(fixable)*
|
148 | - [prefer-query-selector](docs/rules/prefer-query-selector.md) - Prefer `.querySelector()` over `.getElementById()`, `.querySelectorAll()` over `.getElementsByClassName()` and `.getElementsByTagName()`. *(partly fixable)*
|
149 | - [prefer-reflect-apply](docs/rules/prefer-reflect-apply.md) - Prefer `Reflect.apply()` over `Function#apply()`. *(fixable)*
|
150 | - [prefer-replace-all](docs/rules/prefer-replace-all.md) - Prefer `String#replaceAll()` over regex searches with the global flag. *(fixable)*
|
151 | - [prefer-set-has](docs/rules/prefer-set-has.md) - Prefer `Set#has()` over `Array#includes()` when checking for existence or non-existence. *(fixable)*
|
152 | - [prefer-spread](docs/rules/prefer-spread.md) - Prefer the spread operator over `Array.from()`. *(fixable)*
|
153 | - [prefer-starts-ends-with](docs/rules/prefer-starts-ends-with.md) - Prefer `String#startsWith()` & `String#endsWith()` over more complex alternatives. *(partly fixable)*
|
154 | - [prefer-string-slice](docs/rules/prefer-string-slice.md) - Prefer `String#slice()` over `String#substr()` and `String#substring()`. *(partly fixable)*
|
155 | - [prefer-ternary](docs/rules/prefer-ternary.md) - Prefer ternary expressions over simple `if-else` statements. *(fixable)*
|
156 | - [prefer-text-content](docs/rules/prefer-text-content.md) - Prefer `.textContent` over `.innerText`. *(fixable)*
|
157 | - [prefer-trim-start-end](docs/rules/prefer-trim-start-end.md) - Prefer `String#trimStart()` / `String#trimEnd()` over `String#trimLeft()` / `String#trimRight()`. *(fixable)*
|
158 | - [prefer-type-error](docs/rules/prefer-type-error.md) - Enforce throwing `TypeError` in type checking conditions. *(fixable)*
|
159 | - [prevent-abbreviations](docs/rules/prevent-abbreviations.md) - Prevent abbreviations. *(partly fixable)*
|
160 | - [string-content](docs/rules/string-content.md) - Enforce better string content. *(fixable)*
|
161 | - [throw-new-error](docs/rules/throw-new-error.md) - Require `new` when throwing an error. *(fixable)*
|
162 |
|
163 | ## Deprecated Rules
|
164 |
|
165 | - [prefer-exponentiation-operator](docs/rules/prefer-exponentiation-operator.md) - Use the built-in ESLint [`prefer-exponentiation-operator`](https://eslint.org/docs/rules/prefer-exponentiation-operator) rule instead.
|
166 | - [regex-shorthand](docs/rules/regex-shorthand.md) - Renamed to [`better-regex`](docs/rules/better-regex.md).
|
167 |
|
168 | ## Recommended config
|
169 |
|
170 | This plugin exports a [`recommended` config](index.js) that enforces good practices.
|
171 |
|
172 | Enable it in your `package.json` with the `extends` option:
|
173 |
|
174 | ```json
|
175 | {
|
176 | "name": "my-awesome-project",
|
177 | "eslintConfig": {
|
178 | "extends": "plugin:unicorn/recommended"
|
179 | }
|
180 | }
|
181 | ```
|
182 |
|
183 | See the [ESLint docs](https://eslint.org/docs/user-guide/configuring#extending-configuration-files) for more information about extending config files.
|
184 |
|
185 | **Note**: This config will also enable the correct [parser options](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) and [environment](https://eslint.org/docs/user-guide/configuring#specifying-environments).
|
186 |
|
187 | ## Maintainers
|
188 |
|
189 | - [Sindre Sorhus](https://github.com/sindresorhus)
|
190 | - [Adam Babcock](https://github.com/MrHen)
|
191 | - [futpib](https://github.com/futpib)
|
192 | - [Fisker Cheung](https://github.com/fisker)
|
193 |
|
194 | ###### Former
|
195 |
|
196 | - [Jeroen Engels](https://github.com/jfmengels)
|
197 | - [Sam Verschueren](https://github.com/SamVerschueren)
|