diff --git a/.typos.toml b/.typos.toml index cf2e99e762..0aea7138b4 100644 --- a/.typos.toml +++ b/.typos.toml @@ -5,3 +5,6 @@ [default.extend-words] trivias = "trivias" trivia = "trivia" + +[files] +extend-exclude = ["src/docs/guide/usage/linter/rules/**/*.md"] diff --git a/.vitepress/theme/components/Alert.vue b/.vitepress/theme/components/Alert.vue new file mode 100644 index 0000000000..196390970c --- /dev/null +++ b/.vitepress/theme/components/Alert.vue @@ -0,0 +1,77 @@ + + + + + + + diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts index f03679347e..eb5b07bafa 100644 --- a/.vitepress/theme/index.ts +++ b/.vitepress/theme/index.ts @@ -3,12 +3,14 @@ import type { Theme } from "vitepress"; import DefaultTheme from "vitepress/theme"; import AppBadgeList from "./components/AppBadgeList.vue"; import AppBlogPostHeader from "./components/AppBlogPostHeader.vue"; +import Alert from "./components/Alert.vue"; export default { extends: DefaultTheme, async enhanceApp({ app }) { app.component("AppBadgeList", AppBadgeList); app.component("AppBlogPostHeader", AppBlogPostHeader); + app.component("Alert", Alert); }, // Layout() { // return h(DefaultTheme.Layout, null, { diff --git a/src/branding.md b/src/branding.md index 0c3a9da685..4b1f0dfae5 100644 --- a/src/branding.md +++ b/src/branding.md @@ -1,8 +1,8 @@ # Branding -* Designed by: [@tongtong-lu](https://github.com/tongtong-lu) and [@guan-wy](https://github.com/guan-wy) -* [GitHub Repository](https://github.com/oxc-project/oxc-assets) -* Font: https://fonts.google.com/specimen/IBM+Plex+Mono +- Designed by: [@tongtong-lu](https://github.com/tongtong-lu) and [@guan-wy](https://github.com/guan-wy) +- [GitHub Repository](https://github.com/oxc-project/oxc-assets) +- Font: https://fonts.google.com/specimen/IBM+Plex+Mono ## Icons diff --git a/src/docs/guide/usage/linter/generated-cli.md b/src/docs/guide/usage/linter/generated-cli.md index 42dfdb64d1..92c9644ccc 100644 --- a/src/docs/guide/usage/linter/generated-cli.md +++ b/src/docs/guide/usage/linter/generated-cli.md @@ -1,127 +1,137 @@ + -## Usage -**`oxlint`** \[**`-c`**=_`<./oxlintrc.json>`_\] \[**`--fix`**\] \[**`--fix-suggestions`**\] \[**`--fix-dangerously`**\] \[_`PATH`_\]... +## Usage + **`oxlint`** \[**`-c`**=_`<./oxlintrc.json>`_\] \[**`--fix`**\] \[**`--fix-suggestions`**\] \[**`--fix-dangerously`**\] \[_`PATH`_\]... ## Basic Configuration - -- **`-c`**, **`--config`**=_`<./oxlintrc.json>`_ — +- **`-c`**, **`--config`**=_`<./oxlintrc.json>`_ — Oxlint configuration file (experimental) - * only `.json` extension is supported * tries to be compatible with the ESLint v8's format - -- **` --tsconfig`**=_`<./tsconfig.json>`_ — +- **` --tsconfig`**=_`<./tsconfig.json>`_ — TypeScript `tsconfig.json` path for reading path alias and project references for import plugin -## Allowing / Denying Multiple Lints + +## Allowing / Denying Multiple Lints Accumulate rules and categories from left to right on the command-line. -For example `-D correctness -A no-debugger` or `-A all -D no-debugger`. -The categories are: -- `correctness` - code that is outright wrong or useless (default) -- `suspicious` - code that is most likely wrong or useless -- `pedantic` - lints which are rather strict or have occasional false positives -- `style` - code that should be written in a more idiomatic way -- `nursery` - new lints that are still under development -- `restriction` - lints which prevent the use of language and library features -- `all` - all the categories listed above except nursery + For example `-D correctness -A no-debugger` or `-A all -D no-debugger`. + The categories are: + * `correctness` - code that is outright wrong or useless (default) + * `suspicious` - code that is most likely wrong or useless + * `pedantic` - lints which are rather strict or have occasional false positives + * `style` - code that should be written in a more idiomatic way + * `nursery` - new lints that are still under development + * `restriction` - lints which prevent the use of language and library features + * `all` - all the categories listed above except nursery Arguments: -- **`-A`**, **`--allow`**=_`NAME`_ — +- **`-A`**, **`--allow`**=_`NAME`_ — Allow the rule or category (suppress the lint) -- **`-W`**, **`--warn`**=_`NAME`_ — +- **`-W`**, **`--warn`**=_`NAME`_ — Deny the rule or category (emit a warning) -- **`-D`**, **`--deny`**=_`NAME`_ — +- **`-D`**, **`--deny`**=_`NAME`_ — Deny the rule or category (emit an error) -## Enable Plugins -- **` --disable-react-plugin`** — + +## Enable Plugins +- **` --disable-react-plugin`** — Disable react plugin, which is turned on by default -- **` --disable-unicorn-plugin`** — +- **` --disable-unicorn-plugin`** — Disable unicorn plugin, which is turned on by default -- **` --disable-oxc-plugin`** — +- **` --disable-oxc-plugin`** — Disable oxc unique rules, which is turned on by default -- **` --disable-typescript-plugin`** — +- **` --disable-typescript-plugin`** — Disable TypeScript plugin, which is turned on by default -- **` --import-plugin`** — +- **` --import-plugin`** — Enable the experimental import plugin and detect ESM problems. It is recommended to use along side with the `--tsconfig` option. -- **` --jsdoc-plugin`** — +- **` --jsdoc-plugin`** — Enable the experimental jsdoc plugin and detect JSDoc problems -- **` --jest-plugin`** — +- **` --jest-plugin`** — Enable the Jest plugin and detect test problems -- **` --vitest-plugin`** — +- **` --vitest-plugin`** — Enable the Vitest plugin and detect test problems -- **` --jsx-a11y-plugin`** — +- **` --jsx-a11y-plugin`** — Enable the JSX-a11y plugin and detect accessibility problems -- **` --nextjs-plugin`** — +- **` --nextjs-plugin`** — Enable the Next.js plugin and detect Next.js problems -- **` --react-perf-plugin`** — +- **` --react-perf-plugin`** — Enable the React performance plugin and detect rendering performance problems -- **` --promise-plugin`** — +- **` --promise-plugin`** — Enable the promise plugin and detect promise usage problems -## Fix Problems -- **` --fix`** — + +## Fix Problems +- **` --fix`** — Fix as many issues as possible. Only unfixed issues are reported in the output -- **` --fix-suggestions`** — +- **` --fix-suggestions`** — Apply auto-fixable suggestions. May change program behavior. -- **` --fix-dangerously`** — +- **` --fix-dangerously`** — Apply dangerous fixes and suggestions. -## Ignore Files -- **` --ignore-path`**=_`PATH`_ — + +## Ignore Files +- **` --ignore-path`**=_`PATH`_ — Specify the file to use as your .eslintignore -- **` --ignore-pattern`**=_`PAT`_ — +- **` --ignore-pattern`**=_`PAT`_ — Specify patterns of files to ignore (in addition to those in .eslintignore) The supported syntax is the same as for .eslintignore and .gitignore files You should quote your patterns in order to avoid shell interpretation of glob patterns - -- **` --no-ignore`** — +- **` --no-ignore`** — Disables excluding of files from .eslintignore files, **`--ignore-path`** flags and **`--ignore-pattern`** flags -- **` --symlinks`** — +- **` --symlinks`** — Follow symbolic links. Oxlint ignores symbolic links by default. -## Handle Warnings -- **` --quiet`** — + +## Handle Warnings +- **` --quiet`** — Disable reporting on warnings, only errors are reported -- **` --deny-warnings`** — +- **` --deny-warnings`** — Ensure warnings produce a non-zero exit code -- **` --max-warnings`**=_`INT`_ — +- **` --max-warnings`**=_`INT`_ — Specify a warning threshold, which can be used to force exit with an error status if there are too many warning-level rule violations in your project -## Output -- **`-f`**, **`--format`**=_`ARG`_ — + +## Output +- **`-f`**, **`--format`**=_`ARG`_ — Use a specific output format (default, json, unix, checkstyle, github) -## Miscellaneous -- **` --silent`** — + +## Miscellaneous +- **` --silent`** — Do not display any diagnostics -- **` --threads`**=_`INT`_ — +- **` --threads`**=_`INT`_ — Number of threads to use. Set to 1 for using only 1 CPU core -## Available positional items: -- _`PATH`_ — + +## Available positional items: +- _`PATH`_ — Single file, single path or list of paths -## Available options: -- **` --rules`** — + +## Available options: +- **` --rules`** — list all the rules that are currently registered -- **`-h`**, **`--help`** — +- **`-h`**, **`--help`** — Prints help information -- **`-V`**, **`--version`** — +- **`-V`**, **`--version`** — Prints version information + + + + diff --git a/src/docs/guide/usage/linter/generated-config.md b/src/docs/guide/usage/linter/generated-config.md index 3cc9b2937a..9cd44d5991 100644 --- a/src/docs/guide/usage/linter/generated-config.md +++ b/src/docs/guide/usage/linter/generated-config.md @@ -1,3 +1,4 @@ + # Oxlint Configuration File This configuration is aligned with ESLint v8's configuration schema (`eslintrc.json`). @@ -29,86 +30,124 @@ Example } ``` + ## env type: `object` Predefine global variables. + + ## globals type: `object` Add or remove global variables. + + ## rules + See [Oxlint Rules](./rules) + + ## settings type: `object` Shared settings for plugins + ### settings.jsdoc type: `object` + + + #### settings.jsdoc.augmentsExtendsReplacesDocs type: `boolean` Only for `require-(yields|returns|description|example|param|throws)` rule + + #### settings.jsdoc.exemptDestructuredRootsFromChecks type: `boolean` Only for `require-param-type` and `require-param-description` rule + + #### settings.jsdoc.ignoreInternal type: `boolean` For all rules but NOT apply to `empty-tags` rule + + #### settings.jsdoc.ignorePrivate type: `boolean` For all rules but NOT apply to `check-access` and `empty-tags` rule + + #### settings.jsdoc.ignoreReplacesDocs type: `boolean` Only for `require-(yields|returns|description|example|param|throws)` rule + + #### settings.jsdoc.implementsReplacesDocs type: `boolean` Only for `require-(yields|returns|description|example|param|throws)` rule + + #### settings.jsdoc.overrideReplacesDocs type: `boolean` Only for `require-(yields|returns|description|example|param|throws)` rule + + #### settings.jsdoc.tagNamePreference type: `object` + + + + + ### settings.jsx-a11y type: `object` + + + #### settings.jsx-a11y.components type: `object` + + + + #### settings.jsx-a11y.polymorphicPropName type: `[ @@ -116,24 +155,63 @@ type: `[ null ]` + + + + + ### settings.next type: `object` + + + #### settings.next.rootDir + + + + + + ### settings.react type: `object` + + + #### settings.react.formComponents type: `array` + + + ##### settings.react.formComponents[n] + + + + + + #### settings.react.linkComponents type: `array` + + + ##### settings.react.linkComponents[n] + + + + + + + + + + diff --git a/src/docs/guide/usage/linter/generated-rules.md b/src/docs/guide/usage/linter/generated-rules.md index 1174998406..69d75142f0 100644 --- a/src/docs/guide/usage/linter/generated-rules.md +++ b/src/docs/guide/usage/linter/generated-rules.md @@ -1,452 +1,453 @@ + # Rules The progress of all rule implementations is tracked [here](https://github.com/oxc-project/oxc/issues/481). -- Total number of rules: 400 +- Total number of rules: 405 - Rules turned on by default: 90 -## Correctness (159): - +## Correctness (160): Code that is outright wrong or useless. -| Rule name | Source | Default | -| --------------------------------------------- | ---------- | ------- | -| for-direction | eslint | ✅ | -| no-async-promise-executor | eslint | ✅ | -| no-caller | eslint | ✅ | -| no-class-assign | eslint | ✅ | -| no-compare-neg-zero | eslint | ✅ | -| no-cond-assign | eslint | ✅ | -| no-const-assign | eslint | ✅ | -| no-constant-binary-expression | eslint | ✅ | -| no-constant-condition | eslint | ✅ | -| no-control-regex | eslint | ✅ | -| no-debugger | eslint | ✅ | -| no-delete-var | eslint | ✅ | -| no-dupe-class-members | eslint | ✅ | -| no-dupe-else-if | eslint | ✅ | -| no-dupe-keys | eslint | ✅ | -| no-duplicate-case | eslint | ✅ | -| no-empty-character-class | eslint | ✅ | -| no-empty-pattern | eslint | ✅ | -| no-empty-static-block | eslint | ✅ | -| no-ex-assign | eslint | ✅ | -| no-extra-boolean-cast | eslint | ✅ | -| no-func-assign | eslint | ✅ | -| no-global-assign | eslint | ✅ | -| no-import-assign | eslint | ✅ | -| no-irregular-whitespace | eslint | ✅ | -| no-loss-of-precision | eslint | ✅ | -| no-new-native-nonconstructor | eslint | ✅ | -| no-nonoctal-decimal-escape | eslint | ✅ | -| no-obj-calls | eslint | ✅ | -| no-self-assign | eslint | ✅ | -| no-setter-return | eslint | ✅ | -| no-shadow-restricted-names | eslint | ✅ | -| no-sparse-arrays | eslint | ✅ | -| no-this-before-super | eslint | ✅ | -| no-unsafe-finally | eslint | ✅ | -| no-unsafe-negation | eslint | ✅ | -| no-unused-labels | eslint | ✅ | -| no-unused-private-class-members | eslint | ✅ | -| no-useless-catch | eslint | ✅ | -| no-useless-escape | eslint | ✅ | -| no-useless-rename | eslint | ✅ | -| no-with | eslint | ✅ | -| require-yield | eslint | ✅ | -| use-isnan | eslint | ✅ | -| valid-typeof | eslint | ✅ | -| default | import | | -| named | import | | -| namespace | import | | -| expect-expect | jest | | -| no-conditional-expect | jest | | -| no-disabled-tests | jest | | -| no-export | jest | | -| no-focused-tests | jest | | -| no-standalone-expect | jest | | -| require-to-throw-message | jest | | -| valid-describe-callback | jest | | -| valid-expect | jest | | -| valid-title | jest | | -| check-property-names | jsdoc | | -| check-tag-names | jsdoc | | -| implements-on-classes | jsdoc | | -| no-defaults | jsdoc | | -| require-property | jsdoc | | -| require-property-description | jsdoc | | -| require-property-name | jsdoc | | -| require-property-type | jsdoc | | -| require-yields | jsdoc | | -| alt-text | jsx_a11y | | -| anchor-has-content | jsx_a11y | | -| anchor-is-valid | jsx_a11y | | -| aria-activedescendant-has-tabindex | jsx_a11y | | -| aria-props | jsx_a11y | | -| aria-role | jsx_a11y | | -| aria-unsupported-elements | jsx_a11y | | -| autocomplete-valid | jsx_a11y | | -| click-events-have-key-events | jsx_a11y | | -| heading-has-content | jsx_a11y | | -| html-has-lang | jsx_a11y | | -| iframe-has-title | jsx_a11y | | -| img-redundant-alt | jsx_a11y | | -| lang | jsx_a11y | | -| media-has-caption | jsx_a11y | | -| mouse-events-have-key-events | jsx_a11y | | -| no-access-key | jsx_a11y | | -| no-aria-hidden-on-focusable | jsx_a11y | | -| no-autofocus | jsx_a11y | | -| no-distracting-elements | jsx_a11y | | -| no-redundant-roles | jsx_a11y | | -| prefer-tag-over-role | jsx_a11y | | -| role-has-required-aria-props | jsx_a11y | | -| role-supports-aria-props | jsx_a11y | | -| scope | jsx_a11y | | -| tabindex-no-positive | jsx_a11y | | -| google-font-display | nextjs | | -| google-font-preconnect | nextjs | | -| inline-script-id | nextjs | | -| next-script-for-ga | nextjs | | -| no-assign-module-variable | nextjs | | -| no-async-client-component | nextjs | | -| no-before-interactive-script-outside-document | nextjs | | -| no-css-tags | nextjs | | -| no-document-import-in-page | nextjs | | -| no-duplicate-head | nextjs | | -| no-head-element | nextjs | | -| no-head-import-in-document | nextjs | | -| no-img-element | nextjs | | -| no-page-custom-font | nextjs | | -| no-script-component-in-head | nextjs | | -| no-styled-jsx-in-document | nextjs | | -| no-sync-scripts | nextjs | | -| no-title-in-document-head | nextjs | | -| no-typos | nextjs | | -| no-unwanted-polyfillio | nextjs | | -| bad-array-method-on-arguments | oxc | ✅ | -| bad-char-at-comparison | oxc | ✅ | -| bad-comparison-sequence | oxc | ✅ | -| bad-min-max-func | oxc | ✅ | -| bad-object-literal-comparison | oxc | ✅ | -| bad-replace-all-arg | oxc | ✅ | -| const-comparisons | oxc | ✅ | -| double-comparisons | oxc | ✅ | -| erasing-op | oxc | ✅ | -| missing-throw | oxc | ✅ | -| number-arg-out-of-range | oxc | ✅ | -| only-used-in-recursion | oxc | ✅ | -| uninvoked-array-callback | oxc | ✅ | -| no-new-statics | promise | | -| jsx-key | react | ✅ | -| jsx-no-duplicate-props | react | ✅ | -| jsx-no-target-blank | react | ✅ | -| jsx-no-undef | react | ✅ | -| no-children-prop | react | ✅ | -| no-direct-mutation-state | react | ✅ | -| no-find-dom-node | react | ✅ | -| no-is-mounted | react | ✅ | -| no-render-return-value | react | ✅ | -| no-string-refs | react | ✅ | -| void-dom-elements-no-children | react | ✅ | -| no-extra-non-null-assertion | typescript | ✅ | -| no-misused-new | typescript | ✅ | -| no-non-null-asserted-optional-chain | typescript | ✅ | -| no-this-alias | typescript | ✅ | -| no-unsafe-declaration-merging | typescript | ✅ | -| no-useless-empty-export | typescript | ✅ | -| prefer-as-const | typescript | ✅ | -| triple-slash-reference | typescript | ✅ | -| no-await-in-promise-methods | unicorn | ✅ | -| no-document-cookie | unicorn | ✅ | -| no-empty-file | unicorn | ✅ | -| no-invalid-remove-event-listener | unicorn | ✅ | -| no-new-array | unicorn | ✅ | -| no-single-promise-in-promise-methods | unicorn | ✅ | -| no-thenable | unicorn | ✅ | -| no-unnecessary-await | unicorn | ✅ | -| no-useless-fallback-in-spread | unicorn | ✅ | -| no-useless-length-check | unicorn | ✅ | -| no-useless-spread | unicorn | ✅ | -| prefer-set-size | unicorn | ✅ | -| prefer-string-starts-ends-with | unicorn | ✅ | +| Rule name | Source | Default | Fixable? | +| --------------------------------------------- | ---------- | ------- | -------- | +| [for-direction](/docs/guide/usage/linter/rules/eslint/for-direction.html) | eslint | ✅ | ⚠️🛠️️ | +| [no-async-promise-executor](/docs/guide/usage/linter/rules/eslint/no-async-promise-executor.html) | eslint | ✅ | | +| [no-caller](/docs/guide/usage/linter/rules/eslint/no-caller.html) | eslint | ✅ | | +| [no-class-assign](/docs/guide/usage/linter/rules/eslint/no-class-assign.html) | eslint | ✅ | | +| [no-compare-neg-zero](/docs/guide/usage/linter/rules/eslint/no-compare-neg-zero.html) | eslint | ✅ | 🛠️💡 | +| [no-cond-assign](/docs/guide/usage/linter/rules/eslint/no-cond-assign.html) | eslint | ✅ | | +| [no-const-assign](/docs/guide/usage/linter/rules/eslint/no-const-assign.html) | eslint | ✅ | | +| [no-constant-binary-expression](/docs/guide/usage/linter/rules/eslint/no-constant-binary-expression.html) | eslint | ✅ | | +| [no-constant-condition](/docs/guide/usage/linter/rules/eslint/no-constant-condition.html) | eslint | ✅ | | +| [no-control-regex](/docs/guide/usage/linter/rules/eslint/no-control-regex.html) | eslint | ✅ | | +| [no-debugger](/docs/guide/usage/linter/rules/eslint/no-debugger.html) | eslint | ✅ | 🛠️ | +| [no-delete-var](/docs/guide/usage/linter/rules/eslint/no-delete-var.html) | eslint | ✅ | | +| [no-dupe-class-members](/docs/guide/usage/linter/rules/eslint/no-dupe-class-members.html) | eslint | ✅ | | +| [no-dupe-else-if](/docs/guide/usage/linter/rules/eslint/no-dupe-else-if.html) | eslint | ✅ | | +| [no-dupe-keys](/docs/guide/usage/linter/rules/eslint/no-dupe-keys.html) | eslint | ✅ | | +| [no-duplicate-case](/docs/guide/usage/linter/rules/eslint/no-duplicate-case.html) | eslint | ✅ | | +| [no-empty-character-class](/docs/guide/usage/linter/rules/eslint/no-empty-character-class.html) | eslint | ✅ | | +| [no-empty-pattern](/docs/guide/usage/linter/rules/eslint/no-empty-pattern.html) | eslint | ✅ | | +| [no-empty-static-block](/docs/guide/usage/linter/rules/eslint/no-empty-static-block.html) | eslint | ✅ | | +| [no-ex-assign](/docs/guide/usage/linter/rules/eslint/no-ex-assign.html) | eslint | ✅ | | +| [no-extra-boolean-cast](/docs/guide/usage/linter/rules/eslint/no-extra-boolean-cast.html) | eslint | ✅ | 🚧 | +| [no-func-assign](/docs/guide/usage/linter/rules/eslint/no-func-assign.html) | eslint | ✅ | | +| [no-global-assign](/docs/guide/usage/linter/rules/eslint/no-global-assign.html) | eslint | ✅ | | +| [no-import-assign](/docs/guide/usage/linter/rules/eslint/no-import-assign.html) | eslint | ✅ | | +| [no-irregular-whitespace](/docs/guide/usage/linter/rules/eslint/no-irregular-whitespace.html) | eslint | ✅ | | +| [no-loss-of-precision](/docs/guide/usage/linter/rules/eslint/no-loss-of-precision.html) | eslint | ✅ | | +| [no-new-native-nonconstructor](/docs/guide/usage/linter/rules/eslint/no-new-native-nonconstructor.html) | eslint | ✅ | | +| [no-nonoctal-decimal-escape](/docs/guide/usage/linter/rules/eslint/no-nonoctal-decimal-escape.html) | eslint | ✅ | | +| [no-obj-calls](/docs/guide/usage/linter/rules/eslint/no-obj-calls.html) | eslint | ✅ | | +| [no-self-assign](/docs/guide/usage/linter/rules/eslint/no-self-assign.html) | eslint | ✅ | | +| [no-setter-return](/docs/guide/usage/linter/rules/eslint/no-setter-return.html) | eslint | ✅ | | +| [no-shadow-restricted-names](/docs/guide/usage/linter/rules/eslint/no-shadow-restricted-names.html) | eslint | ✅ | | +| [no-sparse-arrays](/docs/guide/usage/linter/rules/eslint/no-sparse-arrays.html) | eslint | ✅ | | +| [no-this-before-super](/docs/guide/usage/linter/rules/eslint/no-this-before-super.html) | eslint | ✅ | | +| [no-unsafe-finally](/docs/guide/usage/linter/rules/eslint/no-unsafe-finally.html) | eslint | ✅ | | +| [no-unsafe-negation](/docs/guide/usage/linter/rules/eslint/no-unsafe-negation.html) | eslint | ✅ | 🛠️ | +| [no-unused-labels](/docs/guide/usage/linter/rules/eslint/no-unused-labels.html) | eslint | ✅ | 🛠️ | +| [no-unused-private-class-members](/docs/guide/usage/linter/rules/eslint/no-unused-private-class-members.html) | eslint | ✅ | | +| [no-useless-catch](/docs/guide/usage/linter/rules/eslint/no-useless-catch.html) | eslint | ✅ | | +| [no-useless-escape](/docs/guide/usage/linter/rules/eslint/no-useless-escape.html) | eslint | ✅ | 🛠️ | +| [no-useless-rename](/docs/guide/usage/linter/rules/eslint/no-useless-rename.html) | eslint | ✅ | | +| [no-with](/docs/guide/usage/linter/rules/eslint/no-with.html) | eslint | ✅ | | +| [require-yield](/docs/guide/usage/linter/rules/eslint/require-yield.html) | eslint | ✅ | | +| [use-isnan](/docs/guide/usage/linter/rules/eslint/use-isnan.html) | eslint | ✅ | 🛠️ | +| [valid-typeof](/docs/guide/usage/linter/rules/eslint/valid-typeof.html) | eslint | ✅ | 🛠️ | +| [default](/docs/guide/usage/linter/rules/import/default.html) | import | | | +| [named](/docs/guide/usage/linter/rules/import/named.html) | import | | | +| [namespace](/docs/guide/usage/linter/rules/import/namespace.html) | import | | | +| [expect-expect](/docs/guide/usage/linter/rules/jest/expect-expect.html) | jest | | | +| [no-conditional-expect](/docs/guide/usage/linter/rules/jest/no-conditional-expect.html) | jest | | | +| [no-disabled-tests](/docs/guide/usage/linter/rules/jest/no-disabled-tests.html) | jest | | | +| [no-export](/docs/guide/usage/linter/rules/jest/no-export.html) | jest | | | +| [no-focused-tests](/docs/guide/usage/linter/rules/jest/no-focused-tests.html) | jest | | 🛠️ | +| [no-standalone-expect](/docs/guide/usage/linter/rules/jest/no-standalone-expect.html) | jest | | | +| [require-to-throw-message](/docs/guide/usage/linter/rules/jest/require-to-throw-message.html) | jest | | | +| [valid-describe-callback](/docs/guide/usage/linter/rules/jest/valid-describe-callback.html) | jest | | | +| [valid-expect](/docs/guide/usage/linter/rules/jest/valid-expect.html) | jest | | | +| [valid-title](/docs/guide/usage/linter/rules/jest/valid-title.html) | jest | | | +| [check-property-names](/docs/guide/usage/linter/rules/jsdoc/check-property-names.html) | jsdoc | | | +| [check-tag-names](/docs/guide/usage/linter/rules/jsdoc/check-tag-names.html) | jsdoc | | | +| [implements-on-classes](/docs/guide/usage/linter/rules/jsdoc/implements-on-classes.html) | jsdoc | | | +| [no-defaults](/docs/guide/usage/linter/rules/jsdoc/no-defaults.html) | jsdoc | | | +| [require-property](/docs/guide/usage/linter/rules/jsdoc/require-property.html) | jsdoc | | | +| [require-property-description](/docs/guide/usage/linter/rules/jsdoc/require-property-description.html) | jsdoc | | | +| [require-property-name](/docs/guide/usage/linter/rules/jsdoc/require-property-name.html) | jsdoc | | | +| [require-property-type](/docs/guide/usage/linter/rules/jsdoc/require-property-type.html) | jsdoc | | | +| [require-yields](/docs/guide/usage/linter/rules/jsdoc/require-yields.html) | jsdoc | | | +| [alt-text](/docs/guide/usage/linter/rules/jsx_a11y/alt-text.html) | jsx_a11y | | | +| [anchor-has-content](/docs/guide/usage/linter/rules/jsx_a11y/anchor-has-content.html) | jsx_a11y | | | +| [anchor-is-valid](/docs/guide/usage/linter/rules/jsx_a11y/anchor-is-valid.html) | jsx_a11y | | | +| [aria-activedescendant-has-tabindex](/docs/guide/usage/linter/rules/jsx_a11y/aria-activedescendant-has-tabindex.html) | jsx_a11y | | | +| [aria-props](/docs/guide/usage/linter/rules/jsx_a11y/aria-props.html) | jsx_a11y | | 🛠️ | +| [aria-role](/docs/guide/usage/linter/rules/jsx_a11y/aria-role.html) | jsx_a11y | | | +| [aria-unsupported-elements](/docs/guide/usage/linter/rules/jsx_a11y/aria-unsupported-elements.html) | jsx_a11y | | | +| [autocomplete-valid](/docs/guide/usage/linter/rules/jsx_a11y/autocomplete-valid.html) | jsx_a11y | | | +| [click-events-have-key-events](/docs/guide/usage/linter/rules/jsx_a11y/click-events-have-key-events.html) | jsx_a11y | | | +| [heading-has-content](/docs/guide/usage/linter/rules/jsx_a11y/heading-has-content.html) | jsx_a11y | | | +| [html-has-lang](/docs/guide/usage/linter/rules/jsx_a11y/html-has-lang.html) | jsx_a11y | | | +| [iframe-has-title](/docs/guide/usage/linter/rules/jsx_a11y/iframe-has-title.html) | jsx_a11y | | | +| [img-redundant-alt](/docs/guide/usage/linter/rules/jsx_a11y/img-redundant-alt.html) | jsx_a11y | | | +| [lang](/docs/guide/usage/linter/rules/jsx_a11y/lang.html) | jsx_a11y | | | +| [media-has-caption](/docs/guide/usage/linter/rules/jsx_a11y/media-has-caption.html) | jsx_a11y | | | +| [mouse-events-have-key-events](/docs/guide/usage/linter/rules/jsx_a11y/mouse-events-have-key-events.html) | jsx_a11y | | | +| [no-access-key](/docs/guide/usage/linter/rules/jsx_a11y/no-access-key.html) | jsx_a11y | | | +| [no-aria-hidden-on-focusable](/docs/guide/usage/linter/rules/jsx_a11y/no-aria-hidden-on-focusable.html) | jsx_a11y | | 🛠️ | +| [no-autofocus](/docs/guide/usage/linter/rules/jsx_a11y/no-autofocus.html) | jsx_a11y | | 🛠️ | +| [no-distracting-elements](/docs/guide/usage/linter/rules/jsx_a11y/no-distracting-elements.html) | jsx_a11y | | | +| [no-redundant-roles](/docs/guide/usage/linter/rules/jsx_a11y/no-redundant-roles.html) | jsx_a11y | | | +| [prefer-tag-over-role](/docs/guide/usage/linter/rules/jsx_a11y/prefer-tag-over-role.html) | jsx_a11y | | | +| [role-has-required-aria-props](/docs/guide/usage/linter/rules/jsx_a11y/role-has-required-aria-props.html) | jsx_a11y | | | +| [role-supports-aria-props](/docs/guide/usage/linter/rules/jsx_a11y/role-supports-aria-props.html) | jsx_a11y | | | +| [scope](/docs/guide/usage/linter/rules/jsx_a11y/scope.html) | jsx_a11y | | | +| [tabindex-no-positive](/docs/guide/usage/linter/rules/jsx_a11y/tabindex-no-positive.html) | jsx_a11y | | | +| [google-font-display](/docs/guide/usage/linter/rules/nextjs/google-font-display.html) | nextjs | | | +| [google-font-preconnect](/docs/guide/usage/linter/rules/nextjs/google-font-preconnect.html) | nextjs | | | +| [inline-script-id](/docs/guide/usage/linter/rules/nextjs/inline-script-id.html) | nextjs | | | +| [next-script-for-ga](/docs/guide/usage/linter/rules/nextjs/next-script-for-ga.html) | nextjs | | | +| [no-assign-module-variable](/docs/guide/usage/linter/rules/nextjs/no-assign-module-variable.html) | nextjs | | | +| [no-async-client-component](/docs/guide/usage/linter/rules/nextjs/no-async-client-component.html) | nextjs | | | +| [no-before-interactive-script-outside-document](/docs/guide/usage/linter/rules/nextjs/no-before-interactive-script-outside-document.html) | nextjs | | | +| [no-css-tags](/docs/guide/usage/linter/rules/nextjs/no-css-tags.html) | nextjs | | | +| [no-document-import-in-page](/docs/guide/usage/linter/rules/nextjs/no-document-import-in-page.html) | nextjs | | | +| [no-duplicate-head](/docs/guide/usage/linter/rules/nextjs/no-duplicate-head.html) | nextjs | | | +| [no-head-element](/docs/guide/usage/linter/rules/nextjs/no-head-element.html) | nextjs | | | +| [no-head-import-in-document](/docs/guide/usage/linter/rules/nextjs/no-head-import-in-document.html) | nextjs | | | +| [no-img-element](/docs/guide/usage/linter/rules/nextjs/no-img-element.html) | nextjs | | | +| [no-page-custom-font](/docs/guide/usage/linter/rules/nextjs/no-page-custom-font.html) | nextjs | | | +| [no-script-component-in-head](/docs/guide/usage/linter/rules/nextjs/no-script-component-in-head.html) | nextjs | | | +| [no-styled-jsx-in-document](/docs/guide/usage/linter/rules/nextjs/no-styled-jsx-in-document.html) | nextjs | | | +| [no-sync-scripts](/docs/guide/usage/linter/rules/nextjs/no-sync-scripts.html) | nextjs | | | +| [no-title-in-document-head](/docs/guide/usage/linter/rules/nextjs/no-title-in-document-head.html) | nextjs | | | +| [no-typos](/docs/guide/usage/linter/rules/nextjs/no-typos.html) | nextjs | | | +| [no-unwanted-polyfillio](/docs/guide/usage/linter/rules/nextjs/no-unwanted-polyfillio.html) | nextjs | | | +| [bad-array-method-on-arguments](/docs/guide/usage/linter/rules/oxc/bad-array-method-on-arguments.html) | oxc | ✅ | | +| [bad-char-at-comparison](/docs/guide/usage/linter/rules/oxc/bad-char-at-comparison.html) | oxc | ✅ | | +| [bad-comparison-sequence](/docs/guide/usage/linter/rules/oxc/bad-comparison-sequence.html) | oxc | ✅ | | +| [bad-min-max-func](/docs/guide/usage/linter/rules/oxc/bad-min-max-func.html) | oxc | ✅ | | +| [bad-object-literal-comparison](/docs/guide/usage/linter/rules/oxc/bad-object-literal-comparison.html) | oxc | ✅ | | +| [bad-replace-all-arg](/docs/guide/usage/linter/rules/oxc/bad-replace-all-arg.html) | oxc | ✅ | | +| [const-comparisons](/docs/guide/usage/linter/rules/oxc/const-comparisons.html) | oxc | ✅ | | +| [double-comparisons](/docs/guide/usage/linter/rules/oxc/double-comparisons.html) | oxc | ✅ | | +| [erasing-op](/docs/guide/usage/linter/rules/oxc/erasing-op.html) | oxc | ✅ | | +| [missing-throw](/docs/guide/usage/linter/rules/oxc/missing-throw.html) | oxc | ✅ | 💡 | +| [number-arg-out-of-range](/docs/guide/usage/linter/rules/oxc/number-arg-out-of-range.html) | oxc | ✅ | | +| [only-used-in-recursion](/docs/guide/usage/linter/rules/oxc/only-used-in-recursion.html) | oxc | ✅ | | +| [uninvoked-array-callback](/docs/guide/usage/linter/rules/oxc/uninvoked-array-callback.html) | oxc | ✅ | | +| [no-new-statics](/docs/guide/usage/linter/rules/promise/no-new-statics.html) | promise | | 🛠️ | +| [valid-params](/docs/guide/usage/linter/rules/promise/valid-params.html) | promise | | | +| [jsx-key](/docs/guide/usage/linter/rules/react/jsx-key.html) | react | ✅ | | +| [jsx-no-duplicate-props](/docs/guide/usage/linter/rules/react/jsx-no-duplicate-props.html) | react | ✅ | | +| [jsx-no-target-blank](/docs/guide/usage/linter/rules/react/jsx-no-target-blank.html) | react | ✅ | | +| [jsx-no-undef](/docs/guide/usage/linter/rules/react/jsx-no-undef.html) | react | ✅ | | +| [no-children-prop](/docs/guide/usage/linter/rules/react/no-children-prop.html) | react | ✅ | | +| [no-direct-mutation-state](/docs/guide/usage/linter/rules/react/no-direct-mutation-state.html) | react | ✅ | | +| [no-find-dom-node](/docs/guide/usage/linter/rules/react/no-find-dom-node.html) | react | ✅ | | +| [no-is-mounted](/docs/guide/usage/linter/rules/react/no-is-mounted.html) | react | ✅ | | +| [no-render-return-value](/docs/guide/usage/linter/rules/react/no-render-return-value.html) | react | ✅ | | +| [no-string-refs](/docs/guide/usage/linter/rules/react/no-string-refs.html) | react | ✅ | | +| [void-dom-elements-no-children](/docs/guide/usage/linter/rules/react/void-dom-elements-no-children.html) | react | ✅ | | +| [no-extra-non-null-assertion](/docs/guide/usage/linter/rules/typescript/no-extra-non-null-assertion.html) | typescript | ✅ | | +| [no-misused-new](/docs/guide/usage/linter/rules/typescript/no-misused-new.html) | typescript | ✅ | | +| [no-non-null-asserted-optional-chain](/docs/guide/usage/linter/rules/typescript/no-non-null-asserted-optional-chain.html) | typescript | ✅ | | +| [no-this-alias](/docs/guide/usage/linter/rules/typescript/no-this-alias.html) | typescript | ✅ | | +| [no-unsafe-declaration-merging](/docs/guide/usage/linter/rules/typescript/no-unsafe-declaration-merging.html) | typescript | ✅ | | +| [no-useless-empty-export](/docs/guide/usage/linter/rules/typescript/no-useless-empty-export.html) | typescript | ✅ | 🛠️ | +| [prefer-as-const](/docs/guide/usage/linter/rules/typescript/prefer-as-const.html) | typescript | ✅ | 🛠️ | +| [triple-slash-reference](/docs/guide/usage/linter/rules/typescript/triple-slash-reference.html) | typescript | ✅ | | +| [no-await-in-promise-methods](/docs/guide/usage/linter/rules/unicorn/no-await-in-promise-methods.html) | unicorn | ✅ | | +| [no-document-cookie](/docs/guide/usage/linter/rules/unicorn/no-document-cookie.html) | unicorn | ✅ | | +| [no-empty-file](/docs/guide/usage/linter/rules/unicorn/no-empty-file.html) | unicorn | ✅ | | +| [no-invalid-remove-event-listener](/docs/guide/usage/linter/rules/unicorn/no-invalid-remove-event-listener.html) | unicorn | ✅ | | +| [no-new-array](/docs/guide/usage/linter/rules/unicorn/no-new-array.html) | unicorn | ✅ | | +| [no-single-promise-in-promise-methods](/docs/guide/usage/linter/rules/unicorn/no-single-promise-in-promise-methods.html) | unicorn | ✅ | 🛠️ | +| [no-thenable](/docs/guide/usage/linter/rules/unicorn/no-thenable.html) | unicorn | ✅ | | +| [no-unnecessary-await](/docs/guide/usage/linter/rules/unicorn/no-unnecessary-await.html) | unicorn | ✅ | 🛠️ | +| [no-useless-fallback-in-spread](/docs/guide/usage/linter/rules/unicorn/no-useless-fallback-in-spread.html) | unicorn | ✅ | 🛠️ | +| [no-useless-length-check](/docs/guide/usage/linter/rules/unicorn/no-useless-length-check.html) | unicorn | ✅ | | +| [no-useless-spread](/docs/guide/usage/linter/rules/unicorn/no-useless-spread.html) | unicorn | ✅ | 🛠️ | +| [prefer-set-size](/docs/guide/usage/linter/rules/unicorn/prefer-set-size.html) | unicorn | ✅ | 🚧 | +| [prefer-string-starts-ends-with](/docs/guide/usage/linter/rules/unicorn/prefer-string-starts-ends-with.html) | unicorn | ✅ | 🛠️ | ## Perf (6): - Code that can be written to run faster. -| Rule name | Source | Default | -| --------------------------- | ---------- | ------- | -| no-await-in-loop | eslint | | -| no-accumulating-spread | oxc | | -| jsx-no-jsx-as-prop | react_perf | | -| jsx-no-new-array-as-prop | react_perf | | -| jsx-no-new-function-as-prop | react_perf | | -| jsx-no-new-object-as-prop | react_perf | | +| Rule name | Source | Default | Fixable? | +| --------------------------- | ---------- | ------- | -------- | +| [no-await-in-loop](/docs/guide/usage/linter/rules/eslint/no-await-in-loop.html) | eslint | | | +| [no-accumulating-spread](/docs/guide/usage/linter/rules/oxc/no-accumulating-spread.html) | oxc | | | +| [jsx-no-jsx-as-prop](/docs/guide/usage/linter/rules/react_perf/jsx-no-jsx-as-prop.html) | react_perf | | | +| [jsx-no-new-array-as-prop](/docs/guide/usage/linter/rules/react_perf/jsx-no-new-array-as-prop.html) | react_perf | | | +| [jsx-no-new-function-as-prop](/docs/guide/usage/linter/rules/react_perf/jsx-no-new-function-as-prop.html) | react_perf | | | +| [jsx-no-new-object-as-prop](/docs/guide/usage/linter/rules/react_perf/jsx-no-new-object-as-prop.html) | react_perf | | | ## Restriction (53): - Lints which prevent the use of language and library features. Must not be enabled as a whole, should be considered on a case-by-case basis before enabling. -| Rule name | Source | Default | -| --------------------------------------- | ---------- | ------- | -| default-case | eslint | | -| no-bitwise | eslint | | -| no-console | eslint | | -| no-div-regex | eslint | | -| no-empty | eslint | | -| no-empty-function | eslint | | -| no-eq-null | eslint | | -| no-eval | eslint | | -| no-iterator | eslint | | -| no-proto | eslint | | -| no-regex-spaces | eslint | | -| no-restricted-globals | eslint | | -| no-undefined | eslint | | -| no-unsafe-optional-chaining | eslint | | -| no-var | eslint | | -| no-void | eslint | | -| unicode-bom | eslint | | -| no-amd | import | | -| no-cycle | import | | -| no-default-export | import | | -| no-webpack-loader-syntax | import | | -| check-access | jsdoc | | -| empty-tags | jsdoc | | -| bad-bitwise-operator | oxc | | -| no-async-await | oxc | | -| no-barrel-file | oxc | | -| no-const-enum | oxc | | -| no-optional-chaining | oxc | | -| no-rest-spread-properties | oxc | | -| avoid-new | promise | | -| button-has-type | react | | -| no-danger | react | | -| no-unknown-property | react | | -| explicit-function-return-type | typescript | | -| no-dynamic-delete | typescript | | -| no-explicit-any | typescript | | -| no-import-type-side-effects | typescript | | -| no-namespace | typescript | | -| no-non-null-asserted-nullish-coalescing | typescript | | -| no-non-null-assertion | typescript | | -| no-var-requires | typescript | | -| prefer-literal-enum-member | typescript | | -| no-abusive-eslint-disable | unicorn | | -| no-anonymous-default-export | unicorn | | -| no-array-for-each | unicorn | | -| no-array-reduce | unicorn | | -| no-length-as-slice-end | unicorn | | -| no-magic-array-flat-depth | unicorn | | -| no-nested-ternary | unicorn | | -| no-process-exit | unicorn | | -| prefer-modern-math-apis | unicorn | | -| prefer-node-protocol | unicorn | | -| prefer-number-properties | unicorn | | +| Rule name | Source | Default | Fixable? | +| --------------------------------------- | ---------- | ------- | -------- | +| [default-case](/docs/guide/usage/linter/rules/eslint/default-case.html) | eslint | | | +| [no-bitwise](/docs/guide/usage/linter/rules/eslint/no-bitwise.html) | eslint | | | +| [no-console](/docs/guide/usage/linter/rules/eslint/no-console.html) | eslint | | | +| [no-div-regex](/docs/guide/usage/linter/rules/eslint/no-div-regex.html) | eslint | | 🛠️ | +| [no-empty](/docs/guide/usage/linter/rules/eslint/no-empty.html) | eslint | | 🚧 | +| [no-empty-function](/docs/guide/usage/linter/rules/eslint/no-empty-function.html) | eslint | | | +| [no-eq-null](/docs/guide/usage/linter/rules/eslint/no-eq-null.html) | eslint | | ⚠️🛠️️ | +| [no-eval](/docs/guide/usage/linter/rules/eslint/no-eval.html) | eslint | | | +| [no-iterator](/docs/guide/usage/linter/rules/eslint/no-iterator.html) | eslint | | | +| [no-proto](/docs/guide/usage/linter/rules/eslint/no-proto.html) | eslint | | | +| [no-regex-spaces](/docs/guide/usage/linter/rules/eslint/no-regex-spaces.html) | eslint | | | +| [no-restricted-globals](/docs/guide/usage/linter/rules/eslint/no-restricted-globals.html) | eslint | | | +| [no-undefined](/docs/guide/usage/linter/rules/eslint/no-undefined.html) | eslint | | | +| [no-unsafe-optional-chaining](/docs/guide/usage/linter/rules/eslint/no-unsafe-optional-chaining.html) | eslint | | | +| [no-var](/docs/guide/usage/linter/rules/eslint/no-var.html) | eslint | | 🚧 | +| [no-void](/docs/guide/usage/linter/rules/eslint/no-void.html) | eslint | | | +| [unicode-bom](/docs/guide/usage/linter/rules/eslint/unicode-bom.html) | eslint | | 🛠️ | +| [no-amd](/docs/guide/usage/linter/rules/import/no-amd.html) | import | | | +| [no-cycle](/docs/guide/usage/linter/rules/import/no-cycle.html) | import | | | +| [no-default-export](/docs/guide/usage/linter/rules/import/no-default-export.html) | import | | | +| [no-webpack-loader-syntax](/docs/guide/usage/linter/rules/import/no-webpack-loader-syntax.html) | import | | | +| [check-access](/docs/guide/usage/linter/rules/jsdoc/check-access.html) | jsdoc | | | +| [empty-tags](/docs/guide/usage/linter/rules/jsdoc/empty-tags.html) | jsdoc | | | +| [bad-bitwise-operator](/docs/guide/usage/linter/rules/oxc/bad-bitwise-operator.html) | oxc | | | +| [no-async-await](/docs/guide/usage/linter/rules/oxc/no-async-await.html) | oxc | | | +| [no-barrel-file](/docs/guide/usage/linter/rules/oxc/no-barrel-file.html) | oxc | | | +| [no-const-enum](/docs/guide/usage/linter/rules/oxc/no-const-enum.html) | oxc | | 🛠️ | +| [no-optional-chaining](/docs/guide/usage/linter/rules/oxc/no-optional-chaining.html) | oxc | | | +| [no-rest-spread-properties](/docs/guide/usage/linter/rules/oxc/no-rest-spread-properties.html) | oxc | | | +| [avoid-new](/docs/guide/usage/linter/rules/promise/avoid-new.html) | promise | | | +| [button-has-type](/docs/guide/usage/linter/rules/react/button-has-type.html) | react | | | +| [no-danger](/docs/guide/usage/linter/rules/react/no-danger.html) | react | | | +| [no-unknown-property](/docs/guide/usage/linter/rules/react/no-unknown-property.html) | react | | | +| [explicit-function-return-type](/docs/guide/usage/linter/rules/typescript/explicit-function-return-type.html) | typescript | | | +| [no-dynamic-delete](/docs/guide/usage/linter/rules/typescript/no-dynamic-delete.html) | typescript | | | +| [no-explicit-any](/docs/guide/usage/linter/rules/typescript/no-explicit-any.html) | typescript | | 🛠️ | +| [no-import-type-side-effects](/docs/guide/usage/linter/rules/typescript/no-import-type-side-effects.html) | typescript | | 🛠️ | +| [no-namespace](/docs/guide/usage/linter/rules/typescript/no-namespace.html) | typescript | | | +| [no-non-null-asserted-nullish-coalescing](/docs/guide/usage/linter/rules/typescript/no-non-null-asserted-nullish-coalescing.html) | typescript | | | +| [no-non-null-assertion](/docs/guide/usage/linter/rules/typescript/no-non-null-assertion.html) | typescript | | | +| [no-var-requires](/docs/guide/usage/linter/rules/typescript/no-var-requires.html) | typescript | | | +| [prefer-literal-enum-member](/docs/guide/usage/linter/rules/typescript/prefer-literal-enum-member.html) | typescript | | | +| [no-abusive-eslint-disable](/docs/guide/usage/linter/rules/unicorn/no-abusive-eslint-disable.html) | unicorn | | | +| [no-anonymous-default-export](/docs/guide/usage/linter/rules/unicorn/no-anonymous-default-export.html) | unicorn | | | +| [no-array-for-each](/docs/guide/usage/linter/rules/unicorn/no-array-for-each.html) | unicorn | | | +| [no-array-reduce](/docs/guide/usage/linter/rules/unicorn/no-array-reduce.html) | unicorn | | | +| [no-length-as-slice-end](/docs/guide/usage/linter/rules/unicorn/no-length-as-slice-end.html) | unicorn | | 🛠️ | +| [no-magic-array-flat-depth](/docs/guide/usage/linter/rules/unicorn/no-magic-array-flat-depth.html) | unicorn | | | +| [no-nested-ternary](/docs/guide/usage/linter/rules/unicorn/no-nested-ternary.html) | unicorn | | 🛠️ | +| [no-process-exit](/docs/guide/usage/linter/rules/unicorn/no-process-exit.html) | unicorn | | | +| [prefer-modern-math-apis](/docs/guide/usage/linter/rules/unicorn/prefer-modern-math-apis.html) | unicorn | | 🚧 | +| [prefer-node-protocol](/docs/guide/usage/linter/rules/unicorn/prefer-node-protocol.html) | unicorn | | 🛠️ | +| [prefer-number-properties](/docs/guide/usage/linter/rules/unicorn/prefer-number-properties.html) | unicorn | | | ## Suspicious (16): - code that is most likely wrong or useless. -| Rule name | Source | Default | -| ------------------------------- | ---------- | ------- | -| no-new | eslint | | -| no-useless-concat | eslint | | -| no-useless-constructor | eslint | | -| no-duplicates | import | | -| no-named-as-default | import | | -| no-named-as-default-member | import | | -| no-self-import | import | | -| no-commented-out-tests | jest | | -| approx-constant | oxc | | -| misrefactored-assign-op | oxc | | -| jsx-no-comment-textnodes | react | | -| react-in-jsx-scope | react | | -| no-confusing-non-null-assertion | typescript | | -| no-extraneous-class | typescript | | -| no-unnecessary-type-constraint | typescript | | -| prefer-add-event-listener | unicorn | | +| Rule name | Source | Default | Fixable? | +| ------------------------------- | ---------- | ------- | -------- | +| [no-new](/docs/guide/usage/linter/rules/eslint/no-new.html) | eslint | | | +| [no-useless-concat](/docs/guide/usage/linter/rules/eslint/no-useless-concat.html) | eslint | | | +| [no-useless-constructor](/docs/guide/usage/linter/rules/eslint/no-useless-constructor.html) | eslint | | 🛠️ | +| [no-duplicates](/docs/guide/usage/linter/rules/import/no-duplicates.html) | import | | | +| [no-named-as-default](/docs/guide/usage/linter/rules/import/no-named-as-default.html) | import | | | +| [no-named-as-default-member](/docs/guide/usage/linter/rules/import/no-named-as-default-member.html) | import | | | +| [no-self-import](/docs/guide/usage/linter/rules/import/no-self-import.html) | import | | | +| [no-commented-out-tests](/docs/guide/usage/linter/rules/jest/no-commented-out-tests.html) | jest | | | +| [approx-constant](/docs/guide/usage/linter/rules/oxc/approx-constant.html) | oxc | | | +| [misrefactored-assign-op](/docs/guide/usage/linter/rules/oxc/misrefactored-assign-op.html) | oxc | | | +| [jsx-no-comment-textnodes](/docs/guide/usage/linter/rules/react/jsx-no-comment-textnodes.html) | react | | | +| [react-in-jsx-scope](/docs/guide/usage/linter/rules/react/react-in-jsx-scope.html) | react | | | +| [no-confusing-non-null-assertion](/docs/guide/usage/linter/rules/typescript/no-confusing-non-null-assertion.html) | typescript | | | +| [no-extraneous-class](/docs/guide/usage/linter/rules/typescript/no-extraneous-class.html) | typescript | | | +| [no-unnecessary-type-constraint](/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-constraint.html) | typescript | | | +| [prefer-add-event-listener](/docs/guide/usage/linter/rules/unicorn/prefer-add-event-listener.html) | unicorn | | | ## Pedantic (67): - Lints which are rather strict or have occasional false positives. -| Rule name | Source | Default | -| --------------------------------------- | ---------- | ------- | -| array-callback-return | eslint | | -| eqeqeq | eslint | | -| max-classes-per-file | eslint | | -| max-lines | eslint | | -| no-array-constructor | eslint | | -| no-case-declarations | eslint | | -| no-constructor-return | eslint | | -| no-fallthrough | eslint | | -| no-inner-declarations | eslint | | -| no-new-wrappers | eslint | | -| no-prototype-builtins | eslint | | -| no-redeclare | eslint | | -| no-self-compare | eslint | | -| radix | eslint | | -| require-await | eslint | | -| symbol-description | eslint | | -| max-dependencies | import | | -| require-param | jsdoc | | -| require-param-description | jsdoc | | -| require-param-name | jsdoc | | -| require-param-type | jsdoc | | -| require-returns | jsdoc | | -| require-returns-description | jsdoc | | -| require-returns-type | jsdoc | | -| checked-requires-onchange-or-readonly | react | | -| jsx-no-useless-fragment | react | | -| no-unescaped-entities | react | | -| ban-ts-comment | typescript | | -| ban-types | typescript | | -| no-duplicate-enum-values | typescript | | -| prefer-enum-initializers | typescript | | -| prefer-ts-expect-error | typescript | | -| escape-case | unicorn | | -| explicit-length-check | unicorn | | -| new-for-builtins | unicorn | | -| no-hex-escape | unicorn | | -| no-instanceof-array | unicorn | | -| no-lonely-if | unicorn | | -| no-negated-condition | unicorn | | -| no-negation-in-equality-check | unicorn | | -| no-new-buffer | unicorn | | -| no-object-as-default-parameter | unicorn | | -| no-static-only-class | unicorn | | -| no-this-assignment | unicorn | | -| no-typeof-undefined | unicorn | | -| no-unreadable-iife | unicorn | | -| no-useless-promise-resolve-reject | unicorn | | -| no-useless-switch-case | unicorn | | -| no-useless-undefined | unicorn | | -| prefer-array-flat | unicorn | | -| prefer-array-some | unicorn | | -| prefer-blob-reading-methods | unicorn | | -| prefer-code-point | unicorn | | -| prefer-date-now | unicorn | | -| prefer-dom-node-append | unicorn | | -| prefer-dom-node-dataset | unicorn | | -| prefer-dom-node-remove | unicorn | | -| prefer-event-target | unicorn | | -| prefer-math-trunc | unicorn | | -| prefer-native-coercion-functions | unicorn | | -| prefer-prototype-methods | unicorn | | -| prefer-query-selector | unicorn | | -| prefer-regexp-test | unicorn | | -| prefer-string-replace-all | unicorn | | -| prefer-string-slice | unicorn | | -| prefer-type-error | unicorn | | -| require-number-to-fixed-digits-argument | unicorn | | - -## Style (89): +| Rule name | Source | Default | Fixable? | +| --------------------------------------- | ---------- | ------- | -------- | +| [array-callback-return](/docs/guide/usage/linter/rules/eslint/array-callback-return.html) | eslint | | | +| [eqeqeq](/docs/guide/usage/linter/rules/eslint/eqeqeq.html) | eslint | | 🛠️ | +| [max-classes-per-file](/docs/guide/usage/linter/rules/eslint/max-classes-per-file.html) | eslint | | | +| [max-lines](/docs/guide/usage/linter/rules/eslint/max-lines.html) | eslint | | | +| [no-array-constructor](/docs/guide/usage/linter/rules/eslint/no-array-constructor.html) | eslint | | | +| [no-case-declarations](/docs/guide/usage/linter/rules/eslint/no-case-declarations.html) | eslint | | | +| [no-constructor-return](/docs/guide/usage/linter/rules/eslint/no-constructor-return.html) | eslint | | | +| [no-fallthrough](/docs/guide/usage/linter/rules/eslint/no-fallthrough.html) | eslint | | 🚧 | +| [no-inner-declarations](/docs/guide/usage/linter/rules/eslint/no-inner-declarations.html) | eslint | | | +| [no-new-wrappers](/docs/guide/usage/linter/rules/eslint/no-new-wrappers.html) | eslint | | | +| [no-prototype-builtins](/docs/guide/usage/linter/rules/eslint/no-prototype-builtins.html) | eslint | | | +| [no-redeclare](/docs/guide/usage/linter/rules/eslint/no-redeclare.html) | eslint | | | +| [no-self-compare](/docs/guide/usage/linter/rules/eslint/no-self-compare.html) | eslint | | | +| [radix](/docs/guide/usage/linter/rules/eslint/radix.html) | eslint | | | +| [require-await](/docs/guide/usage/linter/rules/eslint/require-await.html) | eslint | | | +| [symbol-description](/docs/guide/usage/linter/rules/eslint/symbol-description.html) | eslint | | | +| [max-dependencies](/docs/guide/usage/linter/rules/import/max-dependencies.html) | import | | | +| [require-param](/docs/guide/usage/linter/rules/jsdoc/require-param.html) | jsdoc | | | +| [require-param-description](/docs/guide/usage/linter/rules/jsdoc/require-param-description.html) | jsdoc | | | +| [require-param-name](/docs/guide/usage/linter/rules/jsdoc/require-param-name.html) | jsdoc | | | +| [require-param-type](/docs/guide/usage/linter/rules/jsdoc/require-param-type.html) | jsdoc | | | +| [require-returns](/docs/guide/usage/linter/rules/jsdoc/require-returns.html) | jsdoc | | | +| [require-returns-description](/docs/guide/usage/linter/rules/jsdoc/require-returns-description.html) | jsdoc | | | +| [require-returns-type](/docs/guide/usage/linter/rules/jsdoc/require-returns-type.html) | jsdoc | | | +| [checked-requires-onchange-or-readonly](/docs/guide/usage/linter/rules/react/checked-requires-onchange-or-readonly.html) | react | | | +| [jsx-no-useless-fragment](/docs/guide/usage/linter/rules/react/jsx-no-useless-fragment.html) | react | | | +| [no-unescaped-entities](/docs/guide/usage/linter/rules/react/no-unescaped-entities.html) | react | | | +| [ban-ts-comment](/docs/guide/usage/linter/rules/typescript/ban-ts-comment.html) | typescript | | 🛠️ | +| [ban-types](/docs/guide/usage/linter/rules/typescript/ban-types.html) | typescript | | | +| [no-duplicate-enum-values](/docs/guide/usage/linter/rules/typescript/no-duplicate-enum-values.html) | typescript | | | +| [prefer-enum-initializers](/docs/guide/usage/linter/rules/typescript/prefer-enum-initializers.html) | typescript | | | +| [prefer-ts-expect-error](/docs/guide/usage/linter/rules/typescript/prefer-ts-expect-error.html) | typescript | | 🛠️ | +| [escape-case](/docs/guide/usage/linter/rules/unicorn/escape-case.html) | unicorn | | 🛠️ | +| [explicit-length-check](/docs/guide/usage/linter/rules/unicorn/explicit-length-check.html) | unicorn | | 🛠️ | +| [new-for-builtins](/docs/guide/usage/linter/rules/unicorn/new-for-builtins.html) | unicorn | | | +| [no-hex-escape](/docs/guide/usage/linter/rules/unicorn/no-hex-escape.html) | unicorn | | 🛠️ | +| [no-instanceof-array](/docs/guide/usage/linter/rules/unicorn/no-instanceof-array.html) | unicorn | | 🛠️ | +| [no-lonely-if](/docs/guide/usage/linter/rules/unicorn/no-lonely-if.html) | unicorn | | | +| [no-negated-condition](/docs/guide/usage/linter/rules/unicorn/no-negated-condition.html) | unicorn | | | +| [no-negation-in-equality-check](/docs/guide/usage/linter/rules/unicorn/no-negation-in-equality-check.html) | unicorn | | | +| [no-new-buffer](/docs/guide/usage/linter/rules/unicorn/no-new-buffer.html) | unicorn | | | +| [no-object-as-default-parameter](/docs/guide/usage/linter/rules/unicorn/no-object-as-default-parameter.html) | unicorn | | | +| [no-static-only-class](/docs/guide/usage/linter/rules/unicorn/no-static-only-class.html) | unicorn | | | +| [no-this-assignment](/docs/guide/usage/linter/rules/unicorn/no-this-assignment.html) | unicorn | | | +| [no-typeof-undefined](/docs/guide/usage/linter/rules/unicorn/no-typeof-undefined.html) | unicorn | | | +| [no-unreadable-iife](/docs/guide/usage/linter/rules/unicorn/no-unreadable-iife.html) | unicorn | | | +| [no-useless-promise-resolve-reject](/docs/guide/usage/linter/rules/unicorn/no-useless-promise-resolve-reject.html) | unicorn | | 🛠️ | +| [no-useless-switch-case](/docs/guide/usage/linter/rules/unicorn/no-useless-switch-case.html) | unicorn | | | +| [no-useless-undefined](/docs/guide/usage/linter/rules/unicorn/no-useless-undefined.html) | unicorn | | 🛠️ | +| [prefer-array-flat](/docs/guide/usage/linter/rules/unicorn/prefer-array-flat.html) | unicorn | | 🚧 | +| [prefer-array-some](/docs/guide/usage/linter/rules/unicorn/prefer-array-some.html) | unicorn | | 🚧 | +| [prefer-blob-reading-methods](/docs/guide/usage/linter/rules/unicorn/prefer-blob-reading-methods.html) | unicorn | | | +| [prefer-code-point](/docs/guide/usage/linter/rules/unicorn/prefer-code-point.html) | unicorn | | 🛠️ | +| [prefer-date-now](/docs/guide/usage/linter/rules/unicorn/prefer-date-now.html) | unicorn | | 🚧 | +| [prefer-dom-node-append](/docs/guide/usage/linter/rules/unicorn/prefer-dom-node-append.html) | unicorn | | 🛠️ | +| [prefer-dom-node-dataset](/docs/guide/usage/linter/rules/unicorn/prefer-dom-node-dataset.html) | unicorn | | | +| [prefer-dom-node-remove](/docs/guide/usage/linter/rules/unicorn/prefer-dom-node-remove.html) | unicorn | | | +| [prefer-event-target](/docs/guide/usage/linter/rules/unicorn/prefer-event-target.html) | unicorn | | | +| [prefer-math-trunc](/docs/guide/usage/linter/rules/unicorn/prefer-math-trunc.html) | unicorn | | | +| [prefer-native-coercion-functions](/docs/guide/usage/linter/rules/unicorn/prefer-native-coercion-functions.html) | unicorn | | 🚧 | +| [prefer-prototype-methods](/docs/guide/usage/linter/rules/unicorn/prefer-prototype-methods.html) | unicorn | | 🛠️ | +| [prefer-query-selector](/docs/guide/usage/linter/rules/unicorn/prefer-query-selector.html) | unicorn | | 🛠️ | +| [prefer-regexp-test](/docs/guide/usage/linter/rules/unicorn/prefer-regexp-test.html) | unicorn | | 🚧 | +| [prefer-string-replace-all](/docs/guide/usage/linter/rules/unicorn/prefer-string-replace-all.html) | unicorn | | 🛠️ | +| [prefer-string-slice](/docs/guide/usage/linter/rules/unicorn/prefer-string-slice.html) | unicorn | | 🚧 | +| [prefer-type-error](/docs/guide/usage/linter/rules/unicorn/prefer-type-error.html) | unicorn | | 🚧 | +| [require-number-to-fixed-digits-argument](/docs/guide/usage/linter/rules/unicorn/require-number-to-fixed-digits-argument.html) | unicorn | | 🛠️ | +## Style (92): Code that should be written in a more idiomatic way. -| Rule name | Source | Default | -| ------------------------------------ | ---------- | ------- | -| default-case-last | eslint | | -| default-param-last | eslint | | -| func-names | eslint | | -| guard-for-in | eslint | | -| max-params | eslint | | -| no-continue | eslint | | -| no-label-var | eslint | | -| no-multi-str | eslint | | -| no-script-url | eslint | | -| no-template-curly-in-string | eslint | | -| no-ternary | eslint | | -| prefer-exponentiation-operator | eslint | | -| prefer-numeric-literals | eslint | | -| sort-imports | eslint | | -| consistent-test-it | jest | | -| max-expects | jest | | -| max-nested-describe | jest | | -| no-alias-methods | jest | | -| no-confusing-set-timeout | jest | | -| no-deprecated-functions | jest | | -| no-done-callback | jest | | -| no-duplicate-hooks | jest | | -| no-hooks | jest | | -| no-identical-title | jest | | -| no-interpolation-in-snapshots | jest | | -| no-jasmine-globals | jest | | -| no-large-snapshots | jest | | -| no-mocks-import | jest | | -| no-restricted-jest-methods | jest | | -| no-restricted-matchers | jest | | -| no-test-prefixes | jest | | -| no-test-return-statement | jest | | -| no-untyped-mock-factory | jest | | -| prefer-called-with | jest | | -| prefer-comparison-matcher | jest | | -| prefer-equality-matcher | jest | | -| prefer-expect-resolves | jest | | -| prefer-hooks-in-order | jest | | -| prefer-hooks-on-top | jest | | -| prefer-jest-mocked | jest | | -| prefer-lowercase-title | jest | | -| prefer-mock-promise-shorthand | jest | | -| prefer-spy-on | jest | | -| prefer-strict-equal | jest | | -| prefer-to-be | jest | | -| prefer-to-contain | jest | | -| prefer-to-have-length | jest | | -| prefer-todo | jest | | -| require-hook | jest | | -| require-top-level-describe | jest | | -| param-names | promise | | -| jsx-boolean-value | react | | -| jsx-curly-brace-presence | react | | -| no-set-state | react | | -| prefer-es6-class | react | | -| adjacent-overload-signatures | typescript | | -| array-type | typescript | | -| ban-tslint-comment | typescript | | -| consistent-indexed-object-style | typescript | | -| consistent-type-definitions | typescript | | -| no-empty-interface | typescript | | -| prefer-for-of | typescript | | -| prefer-function-type | typescript | | -| prefer-namespace-keyword | typescript | | -| catch-error-name | unicorn | | -| empty-brace-spaces | unicorn | | -| error-message | unicorn | | -| filename-case | unicorn | | -| no-await-expression-member | unicorn | | -| no-console-spaces | unicorn | | -| no-null | unicorn | | -| no-unreadable-array-destructuring | unicorn | | -| no-zero-fractions | unicorn | | -| number-literal-case | unicorn | | -| numeric-separators-style | unicorn | | -| prefer-array-flat-map | unicorn | | -| prefer-dom-node-text-content | unicorn | | -| prefer-includes | unicorn | | -| prefer-logical-operator-over-ternary | unicorn | | -| prefer-modern-dom-apis | unicorn | | -| prefer-optional-catch-binding | unicorn | | -| prefer-reflect-apply | unicorn | | -| prefer-spread | unicorn | | -| prefer-string-trim-start-end | unicorn | | -| require-array-join-separator | unicorn | | -| switch-case-braces | unicorn | | -| text-encoding-identifier-case | unicorn | | -| throw-new-error | unicorn | | -| no-import-node-test | vitest | | - -## Nursery (10): +| Rule name | Source | Default | Fixable? | +| ------------------------------------ | ---------- | ------- | -------- | +| [default-case-last](/docs/guide/usage/linter/rules/eslint/default-case-last.html) | eslint | | | +| [default-param-last](/docs/guide/usage/linter/rules/eslint/default-param-last.html) | eslint | | | +| [func-names](/docs/guide/usage/linter/rules/eslint/func-names.html) | eslint | | 🛠️💡 | +| [guard-for-in](/docs/guide/usage/linter/rules/eslint/guard-for-in.html) | eslint | | | +| [max-params](/docs/guide/usage/linter/rules/eslint/max-params.html) | eslint | | | +| [no-continue](/docs/guide/usage/linter/rules/eslint/no-continue.html) | eslint | | | +| [no-label-var](/docs/guide/usage/linter/rules/eslint/no-label-var.html) | eslint | | | +| [no-multi-str](/docs/guide/usage/linter/rules/eslint/no-multi-str.html) | eslint | | | +| [no-script-url](/docs/guide/usage/linter/rules/eslint/no-script-url.html) | eslint | | | +| [no-template-curly-in-string](/docs/guide/usage/linter/rules/eslint/no-template-curly-in-string.html) | eslint | | | +| [no-ternary](/docs/guide/usage/linter/rules/eslint/no-ternary.html) | eslint | | | +| [prefer-exponentiation-operator](/docs/guide/usage/linter/rules/eslint/prefer-exponentiation-operator.html) | eslint | | | +| [prefer-numeric-literals](/docs/guide/usage/linter/rules/eslint/prefer-numeric-literals.html) | eslint | | 🛠️ | +| [sort-imports](/docs/guide/usage/linter/rules/eslint/sort-imports.html) | eslint | | 🛠️ | +| [consistent-test-it](/docs/guide/usage/linter/rules/jest/consistent-test-it.html) | jest | | 🛠️ | +| [max-expects](/docs/guide/usage/linter/rules/jest/max-expects.html) | jest | | | +| [max-nested-describe](/docs/guide/usage/linter/rules/jest/max-nested-describe.html) | jest | | | +| [no-alias-methods](/docs/guide/usage/linter/rules/jest/no-alias-methods.html) | jest | | 🛠️ | +| [no-confusing-set-timeout](/docs/guide/usage/linter/rules/jest/no-confusing-set-timeout.html) | jest | | | +| [no-deprecated-functions](/docs/guide/usage/linter/rules/jest/no-deprecated-functions.html) | jest | | 🛠️ | +| [no-done-callback](/docs/guide/usage/linter/rules/jest/no-done-callback.html) | jest | | | +| [no-duplicate-hooks](/docs/guide/usage/linter/rules/jest/no-duplicate-hooks.html) | jest | | | +| [no-hooks](/docs/guide/usage/linter/rules/jest/no-hooks.html) | jest | | | +| [no-identical-title](/docs/guide/usage/linter/rules/jest/no-identical-title.html) | jest | | | +| [no-interpolation-in-snapshots](/docs/guide/usage/linter/rules/jest/no-interpolation-in-snapshots.html) | jest | | | +| [no-jasmine-globals](/docs/guide/usage/linter/rules/jest/no-jasmine-globals.html) | jest | | 🛠️ | +| [no-large-snapshots](/docs/guide/usage/linter/rules/jest/no-large-snapshots.html) | jest | | | +| [no-mocks-import](/docs/guide/usage/linter/rules/jest/no-mocks-import.html) | jest | | | +| [no-restricted-jest-methods](/docs/guide/usage/linter/rules/jest/no-restricted-jest-methods.html) | jest | | | +| [no-restricted-matchers](/docs/guide/usage/linter/rules/jest/no-restricted-matchers.html) | jest | | | +| [no-test-prefixes](/docs/guide/usage/linter/rules/jest/no-test-prefixes.html) | jest | | 🛠️ | +| [no-test-return-statement](/docs/guide/usage/linter/rules/jest/no-test-return-statement.html) | jest | | | +| [no-untyped-mock-factory](/docs/guide/usage/linter/rules/jest/no-untyped-mock-factory.html) | jest | | 🛠️ | +| [prefer-called-with](/docs/guide/usage/linter/rules/jest/prefer-called-with.html) | jest | | | +| [prefer-comparison-matcher](/docs/guide/usage/linter/rules/jest/prefer-comparison-matcher.html) | jest | | 🛠️ | +| [prefer-equality-matcher](/docs/guide/usage/linter/rules/jest/prefer-equality-matcher.html) | jest | | | +| [prefer-expect-resolves](/docs/guide/usage/linter/rules/jest/prefer-expect-resolves.html) | jest | | 🛠️ | +| [prefer-hooks-in-order](/docs/guide/usage/linter/rules/jest/prefer-hooks-in-order.html) | jest | | | +| [prefer-hooks-on-top](/docs/guide/usage/linter/rules/jest/prefer-hooks-on-top.html) | jest | | | +| [prefer-jest-mocked](/docs/guide/usage/linter/rules/jest/prefer-jest-mocked.html) | jest | | 🛠️ | +| [prefer-lowercase-title](/docs/guide/usage/linter/rules/jest/prefer-lowercase-title.html) | jest | | 🛠️ | +| [prefer-mock-promise-shorthand](/docs/guide/usage/linter/rules/jest/prefer-mock-promise-shorthand.html) | jest | | 🛠️ | +| [prefer-spy-on](/docs/guide/usage/linter/rules/jest/prefer-spy-on.html) | jest | | 🛠️ | +| [prefer-strict-equal](/docs/guide/usage/linter/rules/jest/prefer-strict-equal.html) | jest | | 🛠️ | +| [prefer-to-be](/docs/guide/usage/linter/rules/jest/prefer-to-be.html) | jest | | 🛠️ | +| [prefer-to-contain](/docs/guide/usage/linter/rules/jest/prefer-to-contain.html) | jest | | | +| [prefer-to-have-length](/docs/guide/usage/linter/rules/jest/prefer-to-have-length.html) | jest | | 🛠️ | +| [prefer-todo](/docs/guide/usage/linter/rules/jest/prefer-todo.html) | jest | | 🛠️ | +| [require-hook](/docs/guide/usage/linter/rules/jest/require-hook.html) | jest | | | +| [require-top-level-describe](/docs/guide/usage/linter/rules/jest/require-top-level-describe.html) | jest | | | +| [param-names](/docs/guide/usage/linter/rules/promise/param-names.html) | promise | | | +| [prefer-await-to-then](/docs/guide/usage/linter/rules/promise/prefer-await-to-then.html) | promise | | | +| [jsx-boolean-value](/docs/guide/usage/linter/rules/react/jsx-boolean-value.html) | react | | 🛠️ | +| [jsx-curly-brace-presence](/docs/guide/usage/linter/rules/react/jsx-curly-brace-presence.html) | react | | | +| [no-set-state](/docs/guide/usage/linter/rules/react/no-set-state.html) | react | | | +| [prefer-es6-class](/docs/guide/usage/linter/rules/react/prefer-es6-class.html) | react | | | +| [adjacent-overload-signatures](/docs/guide/usage/linter/rules/typescript/adjacent-overload-signatures.html) | typescript | | | +| [array-type](/docs/guide/usage/linter/rules/typescript/array-type.html) | typescript | | 🛠️ | +| [ban-tslint-comment](/docs/guide/usage/linter/rules/typescript/ban-tslint-comment.html) | typescript | | 🛠️ | +| [consistent-indexed-object-style](/docs/guide/usage/linter/rules/typescript/consistent-indexed-object-style.html) | typescript | | 🛠️ | +| [consistent-type-definitions](/docs/guide/usage/linter/rules/typescript/consistent-type-definitions.html) | typescript | | 🛠️ | +| [no-empty-interface](/docs/guide/usage/linter/rules/typescript/no-empty-interface.html) | typescript | | | +| [prefer-for-of](/docs/guide/usage/linter/rules/typescript/prefer-for-of.html) | typescript | | | +| [prefer-function-type](/docs/guide/usage/linter/rules/typescript/prefer-function-type.html) | typescript | | 🛠️ | +| [prefer-namespace-keyword](/docs/guide/usage/linter/rules/typescript/prefer-namespace-keyword.html) | typescript | | 🛠️ | +| [catch-error-name](/docs/guide/usage/linter/rules/unicorn/catch-error-name.html) | unicorn | | | +| [empty-brace-spaces](/docs/guide/usage/linter/rules/unicorn/empty-brace-spaces.html) | unicorn | | 🛠️ | +| [error-message](/docs/guide/usage/linter/rules/unicorn/error-message.html) | unicorn | | | +| [filename-case](/docs/guide/usage/linter/rules/unicorn/filename-case.html) | unicorn | | | +| [no-await-expression-member](/docs/guide/usage/linter/rules/unicorn/no-await-expression-member.html) | unicorn | | | +| [no-console-spaces](/docs/guide/usage/linter/rules/unicorn/no-console-spaces.html) | unicorn | | 🛠️ | +| [no-null](/docs/guide/usage/linter/rules/unicorn/no-null.html) | unicorn | | 🛠️ | +| [no-unreadable-array-destructuring](/docs/guide/usage/linter/rules/unicorn/no-unreadable-array-destructuring.html) | unicorn | | | +| [no-zero-fractions](/docs/guide/usage/linter/rules/unicorn/no-zero-fractions.html) | unicorn | | 🛠️ | +| [number-literal-case](/docs/guide/usage/linter/rules/unicorn/number-literal-case.html) | unicorn | | 🛠️ | +| [numeric-separators-style](/docs/guide/usage/linter/rules/unicorn/numeric-separators-style.html) | unicorn | | 🛠️ | +| [prefer-array-flat-map](/docs/guide/usage/linter/rules/unicorn/prefer-array-flat-map.html) | unicorn | | | +| [prefer-dom-node-text-content](/docs/guide/usage/linter/rules/unicorn/prefer-dom-node-text-content.html) | unicorn | | 🛠️ | +| [prefer-includes](/docs/guide/usage/linter/rules/unicorn/prefer-includes.html) | unicorn | | | +| [prefer-logical-operator-over-ternary](/docs/guide/usage/linter/rules/unicorn/prefer-logical-operator-over-ternary.html) | unicorn | | | +| [prefer-modern-dom-apis](/docs/guide/usage/linter/rules/unicorn/prefer-modern-dom-apis.html) | unicorn | | | +| [prefer-optional-catch-binding](/docs/guide/usage/linter/rules/unicorn/prefer-optional-catch-binding.html) | unicorn | | 🚧 | +| [prefer-reflect-apply](/docs/guide/usage/linter/rules/unicorn/prefer-reflect-apply.html) | unicorn | | | +| [prefer-spread](/docs/guide/usage/linter/rules/unicorn/prefer-spread.html) | unicorn | | 🛠️ | +| [prefer-string-trim-start-end](/docs/guide/usage/linter/rules/unicorn/prefer-string-trim-start-end.html) | unicorn | | 🛠️ | +| [require-array-join-separator](/docs/guide/usage/linter/rules/unicorn/require-array-join-separator.html) | unicorn | | 🚧 | +| [switch-case-braces](/docs/guide/usage/linter/rules/unicorn/switch-case-braces.html) | unicorn | | 🛠️ | +| [text-encoding-identifier-case](/docs/guide/usage/linter/rules/unicorn/text-encoding-identifier-case.html) | unicorn | | 🚧 | +| [throw-new-error](/docs/guide/usage/linter/rules/unicorn/throw-new-error.html) | unicorn | | 🚧 | +| [no-import-node-test](/docs/guide/usage/linter/rules/vitest/no-import-node-test.html) | vitest | | 🛠️ | +| [prefer-to-be-falsy](/docs/guide/usage/linter/rules/vitest/prefer-to-be-falsy.html) | vitest | | 🛠️ | +| [prefer-to-be-truthy](/docs/guide/usage/linter/rules/vitest/prefer-to-be-truthy.html) | vitest | | 🛠️ | +## Nursery (11): New lints that are still under development. -| Rule name | Source | Default | -| --------------------------------- | ------------ | ------- | -| constructor-super | eslint | | -| getter-return | eslint | | -| no-undef | eslint | | -| no-unreachable | eslint | | -| no-unused-vars | eslint | | -| export | import | | -| require-render-return | react | | -| rules-of-hooks | react | | -| no-side-effects-in-initialization | tree_shaking | | -| consistent-type-imports | typescript | | +| Rule name | Source | Default | Fixable? | +| --------------------------------- | ------------ | ------- | -------- | +| [constructor-super](/docs/guide/usage/linter/rules/eslint/constructor-super.html) | eslint | | | +| [getter-return](/docs/guide/usage/linter/rules/eslint/getter-return.html) | eslint | | | +| [no-undef](/docs/guide/usage/linter/rules/eslint/no-undef.html) | eslint | | | +| [no-unreachable](/docs/guide/usage/linter/rules/eslint/no-unreachable.html) | eslint | | | +| [no-unused-vars](/docs/guide/usage/linter/rules/eslint/no-unused-vars.html) | eslint | | ⚠️💡 | +| [export](/docs/guide/usage/linter/rules/import/export.html) | import | | | +| [no-return-in-finally](/docs/guide/usage/linter/rules/promise/no-return-in-finally.html) | promise | | | +| [require-render-return](/docs/guide/usage/linter/rules/react/require-render-return.html) | react | | | +| [rules-of-hooks](/docs/guide/usage/linter/rules/react/rules-of-hooks.html) | react | | | +| [no-side-effects-in-initialization](/docs/guide/usage/linter/rules/tree_shaking/no-side-effects-in-initialization.html) | tree_shaking | | | +| [consistent-type-imports](/docs/guide/usage/linter/rules/typescript/consistent-type-imports.html) | typescript | | 🛠️ | + + diff --git a/src/docs/guide/usage/linter/rules/eslint/array-callback-return.md b/src/docs/guide/usage/linter/rules/eslint/array-callback-return.md new file mode 100644 index 0000000000..6a7de38c1a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/array-callback-return.md @@ -0,0 +1,26 @@ + + +# eslint/array-callback-return + +
+
+ +### What it does + +Enforce return statements in callbacks of array methods + +### Why is this bad? + +Array has several methods for filtering, mapping, and folding. +If we forget to write return statement in a callback of those, it’s probably a mistake. +If you don’t want to use a return or don’t need the returned results, +consider using .forEach instead. + +### Example + +```javascript +let foo = [1, 2, 3, 4]; +foo.map((a) => { + console.log(a); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/constructor-super.md b/src/docs/guide/usage/linter/rules/eslint/constructor-super.md new file mode 100644 index 0000000000..972adb0366 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/constructor-super.md @@ -0,0 +1,20 @@ + + +# eslint/constructor-super + +
+
+ +### What it does + +Require 'super()' calls in constructors. + +### Why is this bad? + +### Example + +```javascript +class A extends B { + constructor() {} +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/default-case-last.md b/src/docs/guide/usage/linter/rules/eslint/default-case-last.md new file mode 100644 index 0000000000..3f3bc7b433 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/default-case-last.md @@ -0,0 +1,42 @@ + + +# eslint/default-case-last + +
+
+ +### What it does + +Enforce default clauses in switch statements to be last + +### Why is this bad? + +A switch statement can optionally have a default clause. +If present, it’s usually the last clause, but it doesn’t need to be. It is also allowed to put the default clause before all case clauses, or anywhere between. The behavior is mostly the same as if it was the last clause. The default block will be still executed only if there is no match in the case clauses (including those defined after the default), but there is also the ability to “fall through” from the default clause to the following clause in the list. However, such flow is not common and it would be confusing to the readers. +Even if there is no “fall through” logic, it’s still unexpected to see the default clause before or between the case clauses. By convention, it is expected to be the last clause. +If a switch statement should have a default clause, it’s considered a best practice to define it as the last clause. + +### Example + +```javascript +switch (foo) { + default: + bar(); + break; + case "a": + baz(); + break; +} + +switch (foo) { + case 1: + bar(); + break; + default: + baz(); + break; + case 2: + qux(); + break; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/default-case.md b/src/docs/guide/usage/linter/rules/eslint/default-case.md new file mode 100644 index 0000000000..a7adfd5591 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/default-case.md @@ -0,0 +1,24 @@ + + +# eslint/default-case + +
+
+ +### What it does + +Require default cases in switch statements + +### Why is this bad? + +Some code conventions require that all switch statements have a default case, even if the +default case is empty. + +### Example + +```javascript +switch (foo) { + case 1: + break; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/default-param-last.md b/src/docs/guide/usage/linter/rules/eslint/default-param-last.md new file mode 100644 index 0000000000..56c55aeea1 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/default-param-last.md @@ -0,0 +1,26 @@ + + +# eslint/default-param-last + +
+
+ +### What it does + +Enforce default parameters to be last + +### Why is this bad? + +Putting default parameter at last allows function calls to omit optional tail arguments. + +### Example + +```javascript +// Correct: optional argument can be omitted +function createUser(id, isAdmin = false) {} +createUser("tabby"); + +// Incorrect: optional argument can **not** be omitted +function createUser(isAdmin = false, id) {} +createUser(undefined, "tabby"); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/eqeqeq.md b/src/docs/guide/usage/linter/rules/eslint/eqeqeq.md new file mode 100644 index 0000000000..763173d3aa --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/eqeqeq.md @@ -0,0 +1,25 @@ + + +# eslint/eqeqeq + +
+ +🛠️ An auto-fix is available for this rule for some violations. + +
+ +### What it does + +Requires the use of the === and !== operators + +### Why is this bad? + +Using non-strict equality operators leads to hard to track bugs due to type coercion. + +### Example + +```javascript +let a = []; +let b = false; +a == b; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/for-direction.md b/src/docs/guide/usage/linter/rules/eslint/for-direction.md new file mode 100644 index 0000000000..15f8945c2b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/for-direction.md @@ -0,0 +1,28 @@ + + +# eslint/for-direction + +
+ + This rule is turned on by default. + + +⚠️🛠️️ A dangerous auto-fix is available for this rule. + +
+ +### What it does + +Disallow "for" loop update causing the counter to move in the wrong direction. + +### Why is this bad? + +A for loop that is known to run infinitely or never run is considered a bug. + +### Example + +```javascript +for (var i = 0; i < 10; i--) {} + +for (var i = 10; i >= 0; i++) {} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/func-names.md b/src/docs/guide/usage/linter/rules/eslint/func-names.md new file mode 100644 index 0000000000..c1db5e1c9a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/func-names.md @@ -0,0 +1,76 @@ + + +# eslint/func-names + +
+ +🛠️💡 An auto-fix and a suggestion are available for this rule for some violations. + +
+ +### What it does + +Require or disallow named function expressions. + +### Why is this bad? + +Leaving the name off a function will cause `` to appear in +stack traces of errors thrown in it or any function called within it. +This makes it more difficult to find where an error is thrown. If you +provide the optional name for a function expression then you will get +the name of the function expression in the stack trace. + +## Configuration + +This rule has a string option: + +- `"always"` requires a function expression to have a name under all circumstances. +- `"as-needed"` requires a function expression to have a name only when one will not be automatically inferred by the runtime. +- `"never"` requires a function expression to not have a name under any circumstances. + +### Example + +Examples of **incorrect** code for this rule: + +```javascript +/*oxlint func-names: "error" */ + +// default is "always" and there is an anonymous function +Foo.prototype.bar = function () {}; + +/*oxlint func-names: ["error", "always"] */ + +// there is an anonymous function +Foo.prototype.bar = function () {}; + +/*oxlint func-names: ["error", "as-needed"] */ + +// there is an anonymous function +// where the name isn’t assigned automatically per the ECMAScript specs +Foo.prototype.bar = function () {}; + +/*oxlint func-names: ["error", "never"] */ + +// there is a named function +Foo.prototype.bar = function bar() {}; +``` + +Examples of \*_correct_ code for this rule: + +```javascript +/*oxlint func-names: "error" */ + +Foo.prototype.bar = function bar() {}; + +/*oxlint func-names: ["error", "always"] */ + +Foo.prototype.bar = function bar() {}; + +/*oxlint func-names: ["error", "as-needed"] */ + +var foo = function () {}; + +/*oxlint func-names: ["error", "never"] */ + +Foo.prototype.bar = function () {}; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/getter-return.md b/src/docs/guide/usage/linter/rules/eslint/getter-return.md new file mode 100644 index 0000000000..e54876fcf9 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/getter-return.md @@ -0,0 +1,24 @@ + + +# eslint/getter-return + +
+
+ +### What it does + +Requires all getters to have a return statement + +### Why is this bad? + +Getters should always return a value. If they don't, it's probably a mistake. + +### Example + +```javascript +class Person { + get name() { + // no return + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/guard-for-in.md b/src/docs/guide/usage/linter/rules/eslint/guard-for-in.md new file mode 100644 index 0000000000..1a4d63f697 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/guard-for-in.md @@ -0,0 +1,20 @@ + + +# eslint/guard-for-in + +
+
+ +### What it does + +This rule is aimed at preventing unexpected behavior that could arise from using a for in loop without filtering the results in the loop. As such, it will warn when for in loops do not filter their results with an if statement. + +### Why is this bad? + +### Example + +```javascript +for (key in foo) { + doSomething(key); +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/max-classes-per-file.md b/src/docs/guide/usage/linter/rules/eslint/max-classes-per-file.md new file mode 100644 index 0000000000..15e47e1f14 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/max-classes-per-file.md @@ -0,0 +1,22 @@ + + +# eslint/max-classes-per-file + +
+
+ +### What it does + +Enforce a maximum number of classes per file + +### Why is this bad? + +Files containing multiple classes can often result in a less navigable and poorly +structured codebase. Best practice is to keep each file limited to a single responsibility. + +### Example + +```javascript +class Foo {} +class Bar {} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/max-lines.md b/src/docs/guide/usage/linter/rules/eslint/max-lines.md new file mode 100644 index 0000000000..0d0fec0e08 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/max-lines.md @@ -0,0 +1,18 @@ + + +# eslint/max-lines + +
+
+ +### What it does + +Enforce a maximum number of lines per file. + +### Why is this bad? + +Some people consider large files a code smell. Large files tend to do a +lot of things and can make it hard following what’s going. While there +is not an objective maximum number of lines considered acceptable in a +file, most people would agree it should not be in the thousands. +Recommendations usually range from 100 to 500 lines. diff --git a/src/docs/guide/usage/linter/rules/eslint/max-params.md b/src/docs/guide/usage/linter/rules/eslint/max-params.md new file mode 100644 index 0000000000..92b1f080bb --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/max-params.md @@ -0,0 +1,22 @@ + + +# eslint/max-params + +
+
+ +### What it does + +Enforce a maximum number of parameters in function definitions + +### Why is this bad? + +Functions that take numerous parameters can be difficult to read and write because it requires the memorization of what each parameter is, its type, and the order they should appear in. As a result, many coders adhere to a convention that caps the number of parameters a function can take. + +### Example + +```javascript +function foo(bar, baz, qux, qxx) { + doSomething(); +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-array-constructor.md b/src/docs/guide/usage/linter/rules/eslint/no-array-constructor.md new file mode 100644 index 0000000000..c7b5cec2ee --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-array-constructor.md @@ -0,0 +1,21 @@ + + +# eslint/no-array-constructor + +
+
+ +### What it does + +Disallow array constructor + +### Why is this bad? + +Use of the Array constructor to construct a new array is generally discouraged in favor of array literal notation because of the single-argument pitfall and because the Array global may be redefined. +The exception is when the Array constructor is used to intentionally create sparse arrays of a specified size by giving the constructor a single numeric argument. + +### Example + +```javascript +let arr = new Array(); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-async-promise-executor.md b/src/docs/guide/usage/linter/rules/eslint/no-async-promise-executor.md new file mode 100644 index 0000000000..2ba6971a20 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-async-promise-executor.md @@ -0,0 +1,38 @@ + + +# eslint/no-async-promise-executor + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow using an async function as a Promise executor + +### Why is this bad? + +The `new Promise` constructor accepts an executor function as an argument, +which has `resolve` and `reject` parameters that can be used to control the state of the created Promise. +For example: + +### Example + +```javascript +const result = new Promise(function executor(resolve, reject) { + readFile("foo.txt", function (err, result) { + if (err) { + reject(err); + } else { + resolve(result); + } + }); +}); +``` + +The executor function can also be an `async function`. However, this is usually a mistake, for a few reasons: + +- If an async executor function throws an error, the error will be lost and won’t cause the newly-constructed `Promise` to reject.This could make it difficult to debug and handle some errors. +- If a Promise executor function is using `await`, this is usually a sign that it is not actually necessary to use the `new Promise` constructor, or the scope of the `new Promise` constructor can be reduced. diff --git a/src/docs/guide/usage/linter/rules/eslint/no-await-in-loop.md b/src/docs/guide/usage/linter/rules/eslint/no-await-in-loop.md new file mode 100644 index 0000000000..3c62a03214 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-await-in-loop.md @@ -0,0 +1,35 @@ + + +# eslint/no-await-in-loop + +
+
+ +### What it does + +This rule disallows the use of `await` within loop bodies. (for, for-in, for-of, while, do-while). + +### Why is this bad? + +It potentially indicates that the async operations are not being effectively parallelized. +Instead, they are being run in series, which can lead to poorer performance. + +### Example + +Bad: + +```javascript +async function bad() { + for (const user of users) { + const userRecord = await getUserRecord(user); + } +} +``` + +Good: + +```javascript +async function good() { + await Promise.all(users.map((user) => getUserRecord(user))); +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-bitwise.md b/src/docs/guide/usage/linter/rules/eslint/no-bitwise.md new file mode 100644 index 0000000000..e8e2acc95b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-bitwise.md @@ -0,0 +1,21 @@ + + +# eslint/no-bitwise + +
+
+ +### What it does + +Disallow bitwise operators + +### Why is this bad? + +The use of bitwise operators in JavaScript is very rare and often `&` or `|` is simply a mistyped `&&` or `||`, +which will lead to unexpected behavior. + +### Example + +```javascript +var x = y | z; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-caller.md b/src/docs/guide/usage/linter/rules/eslint/no-caller.md new file mode 100644 index 0000000000..a9a4950854 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-caller.md @@ -0,0 +1,34 @@ + + +# eslint/no-caller + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow the use of arguments.caller or arguments.callee + +### Why is this bad? + +The use of arguments.caller and arguments.callee make several code optimizations impossible. +They have been deprecated in future versions of JavaScript and their use is forbidden in ECMAScript 5 while in strict mode. + +### Example + +```javascript +function foo(n) { + if (n <= 0) { + return; + } + + arguments.callee(n - 1); +} + +[1, 2, 3, 4, 5].map(function (n) { + return !(n > 1) ? 1 : arguments.callee(n - 1) * n; +}); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-case-declarations.md b/src/docs/guide/usage/linter/rules/eslint/no-case-declarations.md new file mode 100644 index 0000000000..cd2f921420 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-case-declarations.md @@ -0,0 +1,34 @@ + + +# eslint/no-case-declarations + +
+
+ +### What it does + +Disallow lexical declarations in case clauses. + +### Why is this bad? + +The reason is that the lexical declaration is visible +in the entire switch block but it only gets initialized when it is assigned, +which will only happen if the case where it is defined is reached. + +### Example + +```javascript +switch (foo) { + case 1: + let x = 1; + break; + case 2: + const y = 2; + break; + case 3: + function f() {} + break; + default: + class C {} +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-class-assign.md b/src/docs/guide/usage/linter/rules/eslint/no-class-assign.md new file mode 100644 index 0000000000..2bc7445615 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-class-assign.md @@ -0,0 +1,26 @@ + + +# eslint/no-class-assign + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow reassigning class variables. + +### Why is this bad? + +`ClassDeclaration` creates a variable that can be re-assigned, +but the re-assignment is a mistake in most cases. + +### Example + +```javascript +class A {} +A = 123; +let a = new A(); // Error +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-compare-neg-zero.md b/src/docs/guide/usage/linter/rules/eslint/no-compare-neg-zero.md new file mode 100644 index 0000000000..609bfc5f32 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-compare-neg-zero.md @@ -0,0 +1,29 @@ + + +# eslint/no-compare-neg-zero + +
+ + This rule is turned on by default. + + +🛠️💡 An auto-fix and a suggestion are available for this rule for some violations. + +
+ +### What it does + +Disallow comparing against -0 + +### Why is this bad? + +The rule should warn against code that tries to compare against -0, +since that will not work as intended. That is, code like x === -0 will +pass for both +0 and -0. The author probably intended Object.is(x, -0). + +### Example + +```javascript +if (x === -0) { +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-cond-assign.md b/src/docs/guide/usage/linter/rules/eslint/no-cond-assign.md new file mode 100644 index 0000000000..51d1a039cc --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-cond-assign.md @@ -0,0 +1,31 @@ + + +# eslint/no-cond-assign + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow assignment operators in conditional expressions + +### Why is this bad? + +In conditional statements, it is very easy to mistype a comparison +operator (such as `==`) as an assignment operator (such as `=`). + +There are valid reasons to use assignment operators in conditional +statements. However, it can be difficult to tell whether a specific +assignment was intentional. + +### Example + +```js +// Check the user's job title +if ((user.jobTitle = "manager")) { + // user.jobTitle is now incorrect +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-console.md b/src/docs/guide/usage/linter/rules/eslint/no-console.md new file mode 100644 index 0000000000..ccc6d7c0f6 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-console.md @@ -0,0 +1,23 @@ + + +# eslint/no-console + +
+
+ +### What it does + +Disallows using the global console object. + +### Why is this bad? + +In JavaScript that is designed to be executed in the browser, +it’s considered a best practice to avoid using methods on console. +Such messages are considered to be for debugging purposes and therefore +not suitable to ship to the client. + +### Example + +```javascript +console.log("here"); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-const-assign.md b/src/docs/guide/usage/linter/rules/eslint/no-const-assign.md new file mode 100644 index 0000000000..0dfd4c466a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-const-assign.md @@ -0,0 +1,25 @@ + + +# eslint/no-const-assign + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow reassigning const variables + +### Why is this bad? + +We cannot modify variables that are declared using const keyword. +It will raise a runtime error. + +### Example + +```javascript +const a = 0; +a = 1; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-constant-binary-expression.md b/src/docs/guide/usage/linter/rules/eslint/no-constant-binary-expression.md new file mode 100644 index 0000000000..2dc2525101 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-constant-binary-expression.md @@ -0,0 +1,39 @@ + + +# eslint/no-constant-binary-expression + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow expressions where the operation doesn't affect the value + +### Why is this bad? + +Comparisons which will always evaluate to true or false and logical expressions (||, &&, ??) which either always +short-circuit or never short-circuit are both likely indications of programmer error. + +These errors are especially common in complex expressions where operator precedence is easy to misjudge. + +Additionally, this rule detects comparisons to newly constructed objects/arrays/functions/etc. +In JavaScript, where objects are compared by reference, a newly constructed object can never === any other value. +This can be surprising for programmers coming from languages where objects are compared by value. + +### Example + +```javascript +// One might think this would evaluate as `a + (b ?? c)`: +const x = a + b ?? c; + +// But it actually evaluates as `(a + b) ?? c`. Since `a + b` can never be null, +// the `?? c` has no effect. + +// Programmers coming from a language where objects are compared by value might expect this to work: +const isEmpty = x === []; + +// However, this will always result in `isEmpty` being `false`. +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-constant-condition.md b/src/docs/guide/usage/linter/rules/eslint/no-constant-condition.md new file mode 100644 index 0000000000..c24c312fd3 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-constant-condition.md @@ -0,0 +1,25 @@ + + +# eslint/no-constant-condition + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow constant expressions in conditions + +### Why is this bad? + +A constant expression (for example, a literal) as a test condition might be a typo or development trigger for a specific behavior. + +### Example + +```javascript +if (false) { + doSomethingUnfinished(); +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-constructor-return.md b/src/docs/guide/usage/linter/rules/eslint/no-constructor-return.md new file mode 100644 index 0000000000..4561f296c6 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-constructor-return.md @@ -0,0 +1,33 @@ + + +# eslint/no-constructor-return + +
+
+ +### What it does + +Disallow returning value from constructor + +### Why is this bad? + +In JavaScript, returning a value in the constructor of a class may be a mistake. +Forbidding this pattern prevents mistakes resulting from unfamiliarity with the language or a copy-paste error. + +### Example + +Bad: + +```rust +class C { + constructor() { return 42; } +} +``` + +Good: + +```rust +class C { + constructor() { this.value = 42; } +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-continue.md b/src/docs/guide/usage/linter/rules/eslint/no-continue.md new file mode 100644 index 0000000000..fc8b62ac69 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-continue.md @@ -0,0 +1,29 @@ + + +# eslint/no-continue + +
+
+ +### What it does + +Disallow `continue` statements + +### Why is this bad? + +The continue statement terminates execution of the statements in the current iteration of the current or labeled loop, and continues execution of the loop with the next iteration. When used incorrectly it makes code less testable, less readable and less maintainable. Structured control flow statements such as if should be used instead. + +### Example + +```javascript +var sum = 0, + i; + +for (i = 0; i < 10; i++) { + if (i >= 5) { + continue; + } + + sum += i; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-control-regex.md b/src/docs/guide/usage/linter/rules/eslint/no-control-regex.md new file mode 100644 index 0000000000..d5cef3991c --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-control-regex.md @@ -0,0 +1,48 @@ + + +# eslint/no-control-regex + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallows control characters and some escape sequences that match +control characters in regular expressions. + +### Why is this bad? + +Control characters are special, invisible characters in the ASCII range +0-31. These characters are rarely used in JavaScript strings so a +regular expression containing elements that explicitly match these +characters is most likely a mistake. + +### Example + +Examples of **incorrect** code for this rule: + +```javascript +var pattern1 = /\x00/; +var pattern2 = /\x0C/; +var pattern3 = /\x1F/; +var pattern4 = /\u000C/; +var pattern5 = /\u{C}/u; +var pattern6 = new RegExp("\x0C"); // raw U+000C character in the pattern +var pattern7 = new RegExp("\\x0C"); // \x0C pattern +``` + +Examples of **correct** code for this rule: + +```javascript +var pattern1 = /\x20/; +var pattern2 = /\u0020/; +var pattern3 = /\u{20}/u; +var pattern4 = /\t/; +var pattern5 = /\n/; +var pattern6 = new RegExp("\x20"); +var pattern7 = new RegExp("\\t"); +var pattern8 = new RegExp("\\n"); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-debugger.md b/src/docs/guide/usage/linter/rules/eslint/no-debugger.md new file mode 100644 index 0000000000..9a5f07d885 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-debugger.md @@ -0,0 +1,31 @@ + + +# eslint/no-debugger + +
+ + This rule is turned on by default. + + +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Checks for usage of the `debugger` statement + +### Why is this bad? + +`debugger` statements do not affect functionality when a debugger isn't attached. +They're most commonly an accidental debugging leftover. + +### Example + +```javascript +async function main() { + const data = await getData(); + const result = complexCalculation(data); + debugger; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-delete-var.md b/src/docs/guide/usage/linter/rules/eslint/no-delete-var.md new file mode 100644 index 0000000000..3672791597 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-delete-var.md @@ -0,0 +1,24 @@ + + +# eslint/no-delete-var + +
+ + This rule is turned on by default. + +
+ +### What it does + +The purpose of the delete operator is to remove a property from an object. + +### Why is this bad? + +Using the delete operator on a variable might lead to unexpected behavior. + +### Example + +```javascript +var x; +delete x; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-div-regex.md b/src/docs/guide/usage/linter/rules/eslint/no-div-regex.md new file mode 100644 index 0000000000..800d8bdf37 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-div-regex.md @@ -0,0 +1,26 @@ + + +# eslint/no-div-regex + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Disallow equal signs explicitly at the beginning of regular expressions. + +### Why is this bad? + +Characters /= at the beginning of a regular expression literal can be confused with a +division assignment operator. + +### Example + +```javascript +function bar() { + return /=foo/; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-dupe-class-members.md b/src/docs/guide/usage/linter/rules/eslint/no-dupe-class-members.md new file mode 100644 index 0000000000..da31e9481f --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-dupe-class-members.md @@ -0,0 +1,31 @@ + + +# eslint/no-dupe-class-members + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow duplicate class members + +### Why is this bad? + +If there are declarations of the same name in class members, +the last declaration overwrites other declarations silently. It can cause unexpected behaviors. + +### Example + +```javascript +class A { + foo() { + console.log("foo"); + } + foo = 123; +} +let a = new A(); +a.foo(); // Uncaught TypeError: a.foo is not a function +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-dupe-else-if.md b/src/docs/guide/usage/linter/rules/eslint/no-dupe-else-if.md new file mode 100644 index 0000000000..a942898fcd --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-dupe-else-if.md @@ -0,0 +1,31 @@ + + +# eslint/no-dupe-else-if + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow duplicate conditions in if-else-if chains + +### Why is this bad? + +if-else-if chains are commonly used when there is a need to execute only one branch (or at most one branch) out of several possible branches, based on certain conditions. +Two identical test conditions in the same chain are almost always a mistake in the code. Unless there are side effects in the expressions, +a duplicate will evaluate to the same true or false value as the identical expression earlier in the chain, meaning that its branch can never execute. + +### Example + +```javascript +if (a) { + foo(); +} else if (b) { + bar(); +} else if (b) { + baz(); +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-dupe-keys.md b/src/docs/guide/usage/linter/rules/eslint/no-dupe-keys.md new file mode 100644 index 0000000000..c6652b7ac0 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-dupe-keys.md @@ -0,0 +1,26 @@ + + +# eslint/no-dupe-keys + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow duplicate keys in object literals + +### Why is this bad? + +Multiple properties with the same key in object literals can cause unexpected behavior in your application. + +### Example + +```javascript +var foo = { + bar: "baz", + bar: "qux", +}; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-duplicate-case.md b/src/docs/guide/usage/linter/rules/eslint/no-duplicate-case.md new file mode 100644 index 0000000000..95f1e6f7d3 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-duplicate-case.md @@ -0,0 +1,34 @@ + + +# eslint/no-duplicate-case + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow duplicate case labels + +### Why is this bad? + +If a switch statement has duplicate test expressions in case clauses, +it is likely that a programmer copied a case clause but forgot to change the test expression. + +### Example + +```javascript +var a = 1; +switch (a) { + case 1: + break; + case 1: + break; + case 2: + break; + default: + break; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-empty-character-class.md b/src/docs/guide/usage/linter/rules/eslint/no-empty-character-class.md new file mode 100644 index 0000000000..bfa7b48ab3 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-empty-character-class.md @@ -0,0 +1,23 @@ + + +# eslint/no-empty-character-class + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow empty character classes in regular expressions + +### Why is this bad? + +Because empty character classes in regular expressions do not match anything, they might be typing mistakes. + +### Example + +```javascript +var foo = /^abc[]/; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-empty-function.md b/src/docs/guide/usage/linter/rules/eslint/no-empty-function.md new file mode 100644 index 0000000000..a67e6c0593 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-empty-function.md @@ -0,0 +1,23 @@ + + +# eslint/no-empty-function + +
+
+ +### What it does + +Disallows the usages of empty functions + +### Why is this bad? + +Empty functions can reduce readability because readers need to guess whether it’s +intentional or not. So writing a clear comment for empty functions is a good practice. + +### Example + +```javascript +function foo() {} + +const bar = () => {}; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-empty-pattern.md b/src/docs/guide/usage/linter/rules/eslint/no-empty-pattern.md new file mode 100644 index 0000000000..eb8eae7b6b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-empty-pattern.md @@ -0,0 +1,65 @@ + + +# eslint/no-empty-pattern + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow empty destructuring patterns + +### Why is this bad? + +When using destructuring, it’s possible to create a pattern that has no effect. +This happens when empty curly braces are used to the right of +an embedded object destructuring pattern, such as: + +```JavaScript +// doesn't create any variables +var {a: {}} = foo; +``` + +In this code, no new variables are created because a is just a location helper +while the `{}` is expected to contain the variables to create, such as: + +```JavaScript +// creates variable b +var {a: { b }} = foo; +``` + +In many cases, the empty object pattern is a mistake +where the author intended to use a default value instead, such as: + +```JavaScript +// creates variable a +var {a = {}} = foo; +``` + +The difference between these two patterns is subtle, +especially because the problematic empty pattern looks just like an object literal. + +### Examples of incorrect code for this rule: + +```JavaScript +var {} = foo; +var [] = foo; +var {a: {}} = foo; +var {a: []} = foo; +function foo({}) {} +function foo([]) {} +function foo({a: {}}) {} +function foo({a: []}) {} +``` + +### Examples of correct code for this rule: + +```JavaScript +var {a = {}} = foo; +var {a = []} = foo; +function foo({a = {}}) {} +function foo({a = []}) {} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-empty-static-block.md b/src/docs/guide/usage/linter/rules/eslint/no-empty-static-block.md new file mode 100644 index 0000000000..0cc37d39da --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-empty-static-block.md @@ -0,0 +1,26 @@ + + +# eslint/no-empty-static-block + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallows the usages of empty static blocks + +### Why is this bad? + +Empty block statements, while not technically errors, usually occur due to refactoring that wasn’t completed. +They can cause confusion when reading code. + +### Example + +```javascript +class Foo { + static {} +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-empty.md b/src/docs/guide/usage/linter/rules/eslint/no-empty.md new file mode 100644 index 0000000000..6773a9d0eb --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-empty.md @@ -0,0 +1,25 @@ + + +# eslint/no-empty + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +Disallows empty block statements + +### Why is this bad? + +Empty block statements, while not technically errors, usually occur due to refactoring that wasn’t completed. +They can cause confusion when reading code. + +### Example + +```javascript +if (condition) { +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-eq-null.md b/src/docs/guide/usage/linter/rules/eslint/no-eq-null.md new file mode 100644 index 0000000000..bb36ffa5b2 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-eq-null.md @@ -0,0 +1,25 @@ + + +# eslint/no-eq-null + +
+ +⚠️🛠️️ A dangerous auto-fix is available for this rule. + +
+ +### What it does + +Disallow null comparisons without type-checking operators. + +### Why is this bad? + +Comparing to null without a type-checking operator (== or !=), can have unintended results as the comparison will evaluate to true when comparing to not just a null, but also an undefined value. + +### Example + +```javascript +if (foo == null) { + bar(); +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-eval.md b/src/docs/guide/usage/linter/rules/eslint/no-eval.md new file mode 100644 index 0000000000..00b3ecaf38 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-eval.md @@ -0,0 +1,22 @@ + + +# eslint/no-eval + +
+
+ +### What it does + +Disallows referencing the 'eval' function. + +### Why is this bad? + +Calling 'eval' is not supported in some secure contexts and can lead to +vulnerabilities. + +### Example + +```javascript +const someString = "console.log('pwned')"; +eval(someString); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-ex-assign.md b/src/docs/guide/usage/linter/rules/eslint/no-ex-assign.md new file mode 100644 index 0000000000..1be585b9b4 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-ex-assign.md @@ -0,0 +1,31 @@ + + +# eslint/no-ex-assign + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow reassigning exceptions in catch clauses + +### Why is this bad? + +If a catch clause in a try statement accidentally +(or purposely) assigns another value to the exception parameter, +it is impossible to refer to the error from that point on. +Since there is no arguments object to offer alternative access to this data, +assignment of the parameter is absolutely destructive. + +### Example + +```javascript +try { + // code +} catch (e) { + e = 10; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-extra-boolean-cast.md b/src/docs/guide/usage/linter/rules/eslint/no-extra-boolean-cast.md new file mode 100644 index 0000000000..6983629b7e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-extra-boolean-cast.md @@ -0,0 +1,37 @@ + + +# eslint/no-extra-boolean-cast + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows unnecessary boolean casts. + +### Why is this bad? + +In contexts such as an if statement’s test where the result of the expression will already be coerced to a Boolean, +casting to a Boolean via double negation (!!) or a Boolean call is unnecessary. + +### Example + +```javascript +var foo = !!!bar; +var foo = Boolean(!!bar); + +if (!!foo) { +} +if (Boolean(foo)) { +} + +// with "enforceForLogicalOperands" option enabled +if (!!foo || bar) { +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-fallthrough.md b/src/docs/guide/usage/linter/rules/eslint/no-fallthrough.md new file mode 100644 index 0000000000..84c3afaa12 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-fallthrough.md @@ -0,0 +1,184 @@ + + +# eslint/no-fallthrough + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +Disallow fallthrough of `case` statements + +This rule is aimed at eliminating unintentional fallthrough of one case +to the other. As such, it flags any fallthrough scenarios that are not +marked by a comment. + +### Why is this bad? + +The switch statement in JavaScript is one of the more error-prone +constructs of the language thanks in part to the ability to “fall +through” from one case to the next. For example: + +```js +switch (foo) { + case 1: + doSomething(); + + case 2: + doSomethingElse(); +} +``` + +In this example, if `foo` is `1`, then execution will flow through both +cases, as the first falls through to the second. You can prevent this by +using `break`, as in this example: + +```js +switch (foo) { + case 1: + doSomething(); + break; + + case 2: + doSomethingElse(); +} +``` + +That works fine when you don’t want a fallthrough, but what if the +fallthrough is intentional, there is no way to indicate that in the +language. It’s considered a best practice to always indicate when a +fallthrough is intentional using a comment which matches the +`/falls?\s?through/i`` regular expression but isn’t a directive: + +```js +switch (foo) { + case 1: + doSomething(); + // falls through + + case 2: + doSomethingElse(); +} + +switch (foo) { + case 1: + doSomething(); + // fall through + + case 2: + doSomethingElse(); +} + +switch (foo) { + case 1: + doSomething(); + // fallsthrough + + case 2: + doSomethingElse(); +} + +switch (foo) { + case 1: { + doSomething(); + // falls through + } + + case 2: { + doSomethingElse(); + } +} +``` + +In this example, there is no confusion as to the expected behavior. It +is clear that the first case is meant to fall through to the second +case. + +### Example + +Examples of **incorrect** code for this rule: + +```js +/*oxlint no-fallthrough: "error"*/ + +switch (foo) { + case 1: + doSomething(); + + case 2: + doSomething(); +} +``` + +Examples of **correct** code for this rule: + +```js +/*oxlint no-fallthrough: "error"*/ + +switch (foo) { + case 1: + doSomething(); + break; + + case 2: + doSomething(); +} + +function bar(foo) { + switch (foo) { + case 1: + doSomething(); + return; + + case 2: + doSomething(); + } +} + +switch (foo) { + case 1: + doSomething(); + throw new Error("Boo!"); + + case 2: + doSomething(); +} + +switch (foo) { + case 1: + case 2: + doSomething(); +} + +switch (foo) { + case 1: + case 2: + doSomething(); +} + +switch (foo) { + case 1: + doSomething(); + // falls through + + case 2: + doSomething(); +} + +switch (foo) { + case 1: { + doSomething(); + // falls through + } + + case 2: { + doSomethingElse(); + } +} +``` + +Note that the last case statement in these examples does not cause a +warning because there is nothing to fall through into. diff --git a/src/docs/guide/usage/linter/rules/eslint/no-func-assign.md b/src/docs/guide/usage/linter/rules/eslint/no-func-assign.md new file mode 100644 index 0000000000..d4490f19c1 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-func-assign.md @@ -0,0 +1,24 @@ + + +# eslint/no-func-assign + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow reassigning `function` declarations + +### Why is this bad? + +Overwriting/reassigning a function written as a FunctionDeclaration is often indicative of a mistake or issue. + +### Example + +```javascript +function foo() {} +foo = bar; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-global-assign.md b/src/docs/guide/usage/linter/rules/eslint/no-global-assign.md new file mode 100644 index 0000000000..6642467f36 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-global-assign.md @@ -0,0 +1,23 @@ + + +# eslint/no-global-assign + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow modifications to read-only global variables. + +### Why is this bad? + +In almost all cases, you don’t want to assign a value to these global variables as doing so could result in losing access to important functionality. + +### Example + +```javascript +Object = null; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-import-assign.md b/src/docs/guide/usage/linter/rules/eslint/no-import-assign.md new file mode 100644 index 0000000000..8e77236f41 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-import-assign.md @@ -0,0 +1,31 @@ + + +# eslint/no-import-assign + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow assigning to imported bindings + +### Why is this bad? + +The updates of imported bindings by ES Modules cause runtime errors. + +### Example + +```javascript +import mod, { named } from "./mod.mjs"; +import * as mod_ns from "./mod.mjs"; + +mod = 1; // ERROR: 'mod' is readonly. +named = 2; // ERROR: 'named' is readonly. +mod_ns.named = 3; // ERROR: The members of 'mod_ns' are readonly. +mod_ns = {}; // ERROR: 'mod_ns' is readonly. +// Can't extend 'mod_ns' +Object.assign(mod_ns, { foo: "foo" }); // ERROR: The members of 'mod_ns' are readonly. +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-inner-declarations.md b/src/docs/guide/usage/linter/rules/eslint/no-inner-declarations.md new file mode 100644 index 0000000000..910c7c410c --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-inner-declarations.md @@ -0,0 +1,24 @@ + + +# eslint/no-inner-declarations + +
+
+ +### What it does + +Disallow variable or function declarations in nested blocks + +### Why is this bad? + +A variable declaration is permitted anywhere a statement can go, even nested deeply inside other blocks. +This is often undesirable due to variable hoisting, and moving declarations to the root of the program or function body can increase clarity. +Note that block bindings (let, const) are not hoisted and therefore they are not affected by this rule. + +### Example + +```javascript +if (test) { + function doSomethingElse() {} +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-irregular-whitespace.md b/src/docs/guide/usage/linter/rules/eslint/no-irregular-whitespace.md new file mode 100644 index 0000000000..a9abef157f --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-irregular-whitespace.md @@ -0,0 +1,26 @@ + + +# eslint/no-irregular-whitespace + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallows the use of irregular whitespaces in the code. + +### Why is this bad + +The use of irregular whitespaces can hinder code readability and +create inconsistencies, making maintenance and collaboration more challenging. + +### Example + +```javascript +function invalidExample() { + return 42; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-iterator.md b/src/docs/guide/usage/linter/rules/eslint/no-iterator.md new file mode 100644 index 0000000000..e23fb1c48c --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-iterator.md @@ -0,0 +1,26 @@ + + +# eslint/no-iterator + +
+
+ +### What it does + +Disallow the use of the **iterator** property + +### Why is this bad? + +The **iterator** property was a SpiderMonkey extension to JavaScript +that could be used to create custom iterators that are compatible with +JavaScript’s for in and for each constructs. However, this property is +now obsolete, so it should not be used. Here’s an example of how this +used to work: + +### Example + +```javascript +Foo.prototype.__iterator__ = function () { + return new FooIterator(this); +}; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-label-var.md b/src/docs/guide/usage/linter/rules/eslint/no-label-var.md new file mode 100644 index 0000000000..46e1be54e7 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-label-var.md @@ -0,0 +1,44 @@ + + +# eslint/no-label-var + +
+
+ +### What it does + +Disallow labels that share a name with a variable. + +### Why is this bad? + +This rule aims to create clearer code by disallowing the bad practice of creating a label +that shares a name with a variable that is in scope. + +### Example + +Examples of **incorrect** code for this rule: + +```js +var x = foo; +function bar() { + x: for (;;) { + break x; + } +} +``` + +Examples of **correct** code for this rule: + +```js +// The variable that has the same name as the label is not in scope. + +function foo() { + var q = t; +} + +function bar() { + q: for (;;) { + break q; + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-loss-of-precision.md b/src/docs/guide/usage/linter/rules/eslint/no-loss-of-precision.md new file mode 100644 index 0000000000..b5734bfa2f --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-loss-of-precision.md @@ -0,0 +1,24 @@ + + +# eslint/no-loss-of-precision + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow precision loss of number literal + +### Why is this bad? + +It can lead to unexpected results in certain situations +For example, when performing mathematical operations + +### Example + +```javascript +var x = 2e999; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-multi-str.md b/src/docs/guide/usage/linter/rules/eslint/no-multi-str.md new file mode 100644 index 0000000000..104427c03d --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-multi-str.md @@ -0,0 +1,23 @@ + + +# eslint/no-multi-str + +
+
+ +### What it does + +Disallow multiline strings. + +### Why is this bad? + +Some consider this to be a bad practice as it was an undocumented feature of JavaScript +that was only formalized later. + +### Example + +```javascript +var x = + "Line 1 \ + Line 2"; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-new-native-nonconstructor.md b/src/docs/guide/usage/linter/rules/eslint/no-new-native-nonconstructor.md new file mode 100644 index 0000000000..7dbd28d09c --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-new-native-nonconstructor.md @@ -0,0 +1,28 @@ + + +# eslint/no-new-native-nonconstructor + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow new operators with global non-constructor functions (Symbol, BigInt) + +### Why is this bad? + +Both new Symbol and new BigInt throw a type error because they are functions and not classes. +It is easy to make this mistake by assuming the uppercase letters indicate classes. + +### Example + +```javascript +// throws a TypeError +let foo = new Symbol("foo"); + +// throws a TypeError +let result = new BigInt(9007199254740991); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-new-wrappers.md b/src/docs/guide/usage/linter/rules/eslint/no-new-wrappers.md new file mode 100644 index 0000000000..819c31378a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-new-wrappers.md @@ -0,0 +1,22 @@ + + +# eslint/no-new-wrappers + +
+
+ +### What it does + +Disallow new operators with the String, Number, and Boolean objects + +### Why is this bad? + +The first problem is that primitive wrapper objects are, in fact, objects. That means typeof will return "object" instead of "string", "number", or "boolean". +The second problem comes with boolean objects. Every object is truthy, that means an instance of Boolean always resolves to true even when its actual value is false. +https://eslint.org/docs/latest/rules/no-new-wrappers + +### Example + +```javascript +var stringObject = new String("Hello world"); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-new.md b/src/docs/guide/usage/linter/rules/eslint/no-new.md new file mode 100644 index 0000000000..b14ce0cdb1 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-new.md @@ -0,0 +1,21 @@ + + +# eslint/no-new + +
+
+ +### What it does + +Disallow new operators outside of assignments or comparisons. + +### Why is this bad? + +Calling new without assigning or comparing it the reference is thrown away and in many +cases the constructor can be replaced with a function. + +### Example + +```javascript +new Person(); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-nonoctal-decimal-escape.md b/src/docs/guide/usage/linter/rules/eslint/no-nonoctal-decimal-escape.md new file mode 100644 index 0000000000..2ff68570cc --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-nonoctal-decimal-escape.md @@ -0,0 +1,26 @@ + + +# eslint/no-nonoctal-decimal-escape + +
+ + This rule is turned on by default. + +
+ +### What it does + +This rule disallows \8 and \9 escape sequences in string literals + +### Why is this bad? + +ECMAScript specification treats \8 and \9 in string literals as a legacy feature + +### Example + +```javascript +incorrect: "8"; +("9"); +correct: "8"; +("\\9"); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-obj-calls.md b/src/docs/guide/usage/linter/rules/eslint/no-obj-calls.md new file mode 100644 index 0000000000..effeaf9787 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-obj-calls.md @@ -0,0 +1,44 @@ + + +# eslint/no-obj-calls + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow calling some global objects as functions + +### Why is this bad? + +Some global objects are not intended to be called as functions. +Calling them as functions will usually result in a TypeError being thrown. + +### Example + +```javascript +// Bad +let math = Math(); +let newMath = new Math(); + +let json = JSON(); +let newJson = new JSON(); + +let atomics = Atomics(); +let newAtomics = new Atomics(); + +let intl = Intl(); +let newIntl = new Intl(); + +let reflect = Reflect(); +let newReflect = new Reflect(); + +// Good +let area = (r) => 2 * Math.PI * r * r; +let object = JSON.parse("{}"); +let first = Atomics.load(sharedArray, 0); +let segmenterFrom = Intl.Segmenter("fr", { granularity: "word" }); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-proto.md b/src/docs/guide/usage/linter/rules/eslint/no-proto.md new file mode 100644 index 0000000000..4c7f955d24 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-proto.md @@ -0,0 +1,28 @@ + + +# eslint/no-proto + +
+
+ +### What it does + +Disallow the use of the **proto** property + +### Why is this bad? + +**proto** property has been deprecated as of ECMAScript 3.1 and shouldn’t be used in the code. Use Object.getPrototypeOf and Object.setPrototypeOf instead. + +### Example + +```javascript +/*eslint no-proto: "error"*/ + +var a = obj.__proto__; + +var a = obj["__proto__"]; + +obj.__proto__ = b; + +obj["__proto__"] = b; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-prototype-builtins.md b/src/docs/guide/usage/linter/rules/eslint/no-prototype-builtins.md new file mode 100644 index 0000000000..3339a114c1 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-prototype-builtins.md @@ -0,0 +1,28 @@ + + +# eslint/no-prototype-builtins + +
+
+ +### What it does + +Disallow calling some Object.prototype methods directly on objects + +### Why is this bad? + +In ECMAScript 5.1, Object.create was added, which enables the creation of objects with a specified [[Prototype]]. +Object.create(null) is a common pattern used to create objects that will be used as a Map. +This can lead to errors when it is assumed that objects will have properties from Object.prototype. This rule prevents calling some Object.prototype methods directly from an object. +Additionally, objects can have properties that shadow the built-ins on Object.prototype, potentially causing unintended behavior or denial-of-service security vulnerabilities. +For example, it would be unsafe for a webserver to parse JSON input from a client and call hasOwnProperty directly on the resulting object, because a malicious client could send a JSON value like {"hasOwnProperty": 1} and cause the server to crash. + +To avoid subtle bugs like this, it’s better to always call these methods from Object.prototype. For example, foo.hasOwnProperty("bar") should be replaced with Object.prototype.hasOwnProperty.call(foo, "bar"). + +### Example + +```javascript +var hasBarProperty = foo.hasOwnProperty("bar"); +var isPrototypeOfBar = foo.isPrototypeOf(bar); +var barIsEnumerable = foo.propertyIsEnumerable("bar"); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-redeclare.md b/src/docs/guide/usage/linter/rules/eslint/no-redeclare.md new file mode 100644 index 0000000000..970a084694 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-redeclare.md @@ -0,0 +1,21 @@ + + +# eslint/no-redeclare + +
+
+ +### What it does + +Disallow variable redeclaration + +### Why is this bad? + +n JavaScript, it’s possible to redeclare the same variable name using var. This can lead to confusion as to where the variable is actually declared and initialized. + +### Example + +```javascript +var a = 3; +var a = 10; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-regex-spaces.md b/src/docs/guide/usage/linter/rules/eslint/no-regex-spaces.md new file mode 100644 index 0000000000..88d3d8d705 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-regex-spaces.md @@ -0,0 +1,26 @@ + + +# eslint/no-regex-spaces + +
+
+ +### What it does + +Disallow 2+ consecutive spaces in regular expressions. + +### Why is this bad? + +In a regular expression, it is hard to tell how many spaces are +intended to be matched. It is better to use only one space and +then specify how many spaces are expected using a quantifier. + +```javascript +var re = /foo {3}bar/; +``` + +### Example + +```javascript +var re = /foo bar/; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-restricted-globals.md b/src/docs/guide/usage/linter/rules/eslint/no-restricted-globals.md new file mode 100644 index 0000000000..68abd5a92c --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-restricted-globals.md @@ -0,0 +1,35 @@ + + +# eslint/no-restricted-globals + +
+
+ +### What it does + +This rule allows you to specify global variable names that you don't want to use in your application. + +### Why is this bad? + +Disallowing usage of specific global variables can be useful if you want to allow a set of global +variables by enabling an environment, but still want to disallow some of those. + +For instance, early Internet Explorer versions exposed the current DOM event as a global variable +`event`, but using this variable has been considered as a bad practice for a long time. Restricting +this will make sure this variable isn't used in browser code. + +### Example + +If we have options: + +```json +"no-restricted-globals": ["error", "event"] +``` + +The following patterns are considered problems: + +```javascript +function onClick() { + console.log(event); // Unexpected global variable 'event'. Use local parameter instead. +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-script-url.md b/src/docs/guide/usage/linter/rules/eslint/no-script-url.md new file mode 100644 index 0000000000..d5a37997d2 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-script-url.md @@ -0,0 +1,24 @@ + + +# eslint/no-script-url + +
+
+ +### What it does + +Disallow javascript: URLs + +### Why is this bad? + +Using javascript: URLs is considered by some as a form of eval. Code passed in javascript: URLs has to be parsed and evaluated by the browser in the same way that eval is processed. + +### Example + +```javascript +/*eslint no-script-url: "error"*/ + +location.href = "javascript:void(0)"; + +location.href = `javascript:void(0)`; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-self-assign.md b/src/docs/guide/usage/linter/rules/eslint/no-self-assign.md new file mode 100644 index 0000000000..1b42d41a05 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-self-assign.md @@ -0,0 +1,24 @@ + + +# eslint/no-self-assign + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow assignments where both sides are exactly the same + +### Why is this bad? + +Self assignments have no effect, so probably those are an error due to incomplete refactoring. Those indicate that what you should do is still remaining. + +### Example + +```javascript +foo = foo; +[bar, baz] = [bar, qiz]; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-self-compare.md b/src/docs/guide/usage/linter/rules/eslint/no-self-compare.md new file mode 100644 index 0000000000..15ade67354 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-self-compare.md @@ -0,0 +1,24 @@ + + +# eslint/no-self-compare + +
+
+ +### What it does + +Disallow comparisons where both sides are exactly the same + +### Why is this bad? + +Comparing a variable against itself is usually an error, either a typo or refactoring error. +It is confusing to the reader and may potentially introduce a runtime error. + +### Example + +```javascript +var x = 10; +if (x === x) { + x = 20; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-setter-return.md b/src/docs/guide/usage/linter/rules/eslint/no-setter-return.md new file mode 100644 index 0000000000..1be3fc986a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-setter-return.md @@ -0,0 +1,29 @@ + + +# eslint/no-setter-return + +
+ + This rule is turned on by default. + +
+ +### What it does + +Setters cannot return values. + +### Why is this bad? + +While returning a value from a setter does not produce an error, the returned value is +being ignored. Therefore, returning a value from a setter is either unnecessary or a +possible error, since the returned value cannot be used. + +### Example + +```javascript +class URL { + set origin() { + return true; + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-shadow-restricted-names.md b/src/docs/guide/usage/linter/rules/eslint/no-shadow-restricted-names.md new file mode 100644 index 0000000000..3219b3e903 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-shadow-restricted-names.md @@ -0,0 +1,28 @@ + + +# eslint/no-shadow-restricted-names + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow redefine the global variables like 'undefined', 'NaN', 'Infinity', 'eval', 'arguments'. + +### Why is this bad? + +### Example + +```javascript +function NaN() {} + +!function (Infinity) {}; + +var undefined = 5; + +try { +} catch (eval) {} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-sparse-arrays.md b/src/docs/guide/usage/linter/rules/eslint/no-sparse-arrays.md new file mode 100644 index 0000000000..d459d99d0f --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-sparse-arrays.md @@ -0,0 +1,24 @@ + + +# eslint/no-sparse-arrays + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow sparse arrays. + +### Why is this bad? + +The confusion around sparse arrays is enough that it’s recommended to avoid using them unless you are certain that they are useful in your code. + +### Example + +```javascript +var items = [, ,]; +var colors = ["red", , "blue"]; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-template-curly-in-string.md b/src/docs/guide/usage/linter/rules/eslint/no-template-curly-in-string.md new file mode 100644 index 0000000000..b71dbbc436 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-template-curly-in-string.md @@ -0,0 +1,23 @@ + + +# eslint/no-template-curly-in-string + +
+
+ +### What it does + +Disallow template literal placeholder syntax in regular strings + +### Why is this bad? + +ECMAScript 6 allows programmers to create strings containing variable or expressions using template literals, instead of string concatenation, by writing expressions like ${variable} between two backtick quotes (`). It can be easy to use the wrong quotes when wanting to use template literals, by writing "${variable}", and end up with the literal value "${variable}" instead of a string containing the value of the injected expressions. + +### Example + +```javascript +/*eslint no-template-curly-in-string: "error"*/ +"Hello ${name}!"; +"Hello ${name}!"; +"Time: ${12 * 60 * 60 * 1000}"; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-ternary.md b/src/docs/guide/usage/linter/rules/eslint/no-ternary.md new file mode 100644 index 0000000000..a41b6b46c7 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-ternary.md @@ -0,0 +1,20 @@ + + +# eslint/no-ternary + +
+
+ +### What it does + +Disallow ternary operators + +### Why is this bad? + +The ternary operator is used to conditionally assign a value to a variable. Some believe that the use of ternary operators leads to unclear code. + +### Example + +```javascript +var foo = isBar ? baz : qux; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-this-before-super.md b/src/docs/guide/usage/linter/rules/eslint/no-this-before-super.md new file mode 100644 index 0000000000..1331f80c88 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-this-before-super.md @@ -0,0 +1,30 @@ + + +# eslint/no-this-before-super + +
+ + This rule is turned on by default. + +
+ +### What it does + +Requires calling `super()` before using `this` or `super`. + +### Why is this bad? + +Getters should always return a value. +If they don't, it's probably a mistake. + +### Example + +```javascript +class A1 extends B { + constructor() { + // super() needs to be called first + this.a = 0; + super(); + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-undef.md b/src/docs/guide/usage/linter/rules/eslint/no-undef.md new file mode 100644 index 0000000000..b2e665a00b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-undef.md @@ -0,0 +1,21 @@ + + +# eslint/no-undef + +
+
+ +### What it does + +Disallow the use of undeclared variables. + +### Why is this bad? + +It is most likely a potential ReferenceError caused by a misspelling of a variable or parameter name. + +### Example + +```javascript +var foo = someFunction(); +var bar = a + 1; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-undefined.md b/src/docs/guide/usage/linter/rules/eslint/no-undefined.md new file mode 100644 index 0000000000..92ba4a7d02 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-undefined.md @@ -0,0 +1,46 @@ + + +# eslint/no-undefined + +
+
+ +### What it does + +Disallow the use of `undefined` as an identifier + +### Why is this bad? + +### Example of bad code + +```javascript +var foo = undefined; + +var undefined = "foo"; + +if (foo === undefined) { + // ... +} + +function baz(undefined) { + // ... +} + +bar(undefined, "lorem"); +``` + +### Example of good code + +```javascript +var foo = void 0; + +var Undefined = "foo"; + +if (typeof foo === "undefined") { + // ... +} + +global.undefined = "foo"; + +bar(void 0, "lorem"); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-unreachable.md b/src/docs/guide/usage/linter/rules/eslint/no-unreachable.md new file mode 100644 index 0000000000..8e0935d324 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-unreachable.md @@ -0,0 +1,10 @@ + + +# eslint/no-unreachable + +
+
+ +### What it does + +Disallow unreachable code after `return`, `throw`, `continue`, and `break` statements diff --git a/src/docs/guide/usage/linter/rules/eslint/no-unsafe-finally.md b/src/docs/guide/usage/linter/rules/eslint/no-unsafe-finally.md new file mode 100644 index 0000000000..2c66fe2ea7 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-unsafe-finally.md @@ -0,0 +1,35 @@ + + +# eslint/no-unsafe-finally + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow control flow statements in finally blocks + +### Why is this bad? + +JavaScript suspends the control flow statements of try and catch blocks until the execution of finally block finishes. +So, when return, throw, break, or continue is used in finally, control flow statements inside try and catch are overwritten, which is considered as unexpected behavior. + +### Example + +```javascript +// We expect this function to return 1; +(() => { + try { + return 1; // 1 is returned but suspended until finally block ends + } catch (err) { + return 2; + } finally { + return 3; // 3 is returned before 1, which we did not expect + } +})(); + +// > 3 +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-unsafe-negation.md b/src/docs/guide/usage/linter/rules/eslint/no-unsafe-negation.md new file mode 100644 index 0000000000..b09c09b02e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-unsafe-negation.md @@ -0,0 +1,31 @@ + + +# eslint/no-unsafe-negation + +
+ + This rule is turned on by default. + + +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Disallow negating the left operand of relational operators + +### Why is this bad? + +Just as developers might type -a + b when they mean -(a + b) for the negative of a sum, +they might type !key in object by mistake when they almost certainly mean !(key in object) +to test that a key is not in an object. !obj instanceof Ctor is similar. + +### Example + +```javascript +if ((!key) in object) { + //operator precedence makes it equivalent to (!key) in object + //and type conversion makes it equivalent to (key ? "false" : "true") in object +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-unsafe-optional-chaining.md b/src/docs/guide/usage/linter/rules/eslint/no-unsafe-optional-chaining.md new file mode 100644 index 0000000000..2a9522313b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-unsafe-optional-chaining.md @@ -0,0 +1,27 @@ + + +# eslint/no-unsafe-optional-chaining + +
+
+ +### What it does + +Disallow use of optional chaining in contexts where the undefined value is not allowed + +### Why is this bad? + +The optional chaining (?.) expression can short-circuit with a return value of undefined. +Therefore, treating an evaluated optional chaining expression as a function, object, number, etc., +can cause TypeError or unexpected results. For example: + +### Example + +```javascript +var obj = undefined; +1 in obj?.foo; // TypeError +with (obj?.foo); // TypeError +for (bar of obj?.foo); // TypeError +bar instanceof obj?.foo; // TypeError +const { bar } = obj?.foo; // TypeError +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-unused-labels.md b/src/docs/guide/usage/linter/rules/eslint/no-unused-labels.md new file mode 100644 index 0000000000..9d69b1f9d9 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-unused-labels.md @@ -0,0 +1,31 @@ + + +# eslint/no-unused-labels + +
+ + This rule is turned on by default. + + +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Disallow unused labels + +### Why is this bad? + +Labels that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. + +### Example + +```javascript +OUTER_LOOP: for (const student of students) { + if (checkScores(student.scores)) { + continue; + } + doSomething(student); +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-unused-private-class-members.md b/src/docs/guide/usage/linter/rules/eslint/no-unused-private-class-members.md new file mode 100644 index 0000000000..6f2f2d1574 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-unused-private-class-members.md @@ -0,0 +1,73 @@ + + +# eslint/no-unused-private-class-members + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow unused private class members + +### Why is this bad? + +Private class members that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such class members take up space in the code and can lead to confusion by readers. + +### Example + +```javascript +/// bad +class A { + #unusedMember = 5; +} + +class B { + #usedOnlyInWrite = 5; + method() { + this.#usedOnlyInWrite = 42; + } +} + +class C { + #usedOnlyToUpdateItself = 5; + method() { + this.#usedOnlyToUpdateItself++; + } +} + +class D { + #unusedMethod() {} +} + +class E { + get #unusedAccessor() {} + set #unusedAccessor(value) {} +} + +/// Good +class A { + #usedMember = 42; + method() { + return this.#usedMember; + } +} +class B { + #usedMethod() { + return 42; + } + anotherMethod() { + return this.#usedMethod(); + } +} +class C { + get #usedAccessor() {} + set #usedAccessor(value) {} + + method() { + this.#usedAccessor = 42; + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-unused-vars.md b/src/docs/guide/usage/linter/rules/eslint/no-unused-vars.md new file mode 100644 index 0000000000..ef3454036f --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-unused-vars.md @@ -0,0 +1,124 @@ + + +# eslint/no-unused-vars + +
+ +⚠️💡 A dangerous suggestion is available for this rule. + +
+ +### What it does + +Disallows variable declarations or imports that are not used in code. + +### Why is this bad? + +Variables that are declared and not used anywhere in the code are most +likely an error due to incomplete refactoring. Such variables take up +space in the code and can lead to confusion by readers. + +A variable `foo` is considered to be used if any of the following are +true: + +- It is called (`foo()`) or constructed (`new foo()`) +- It is read (`var bar = foo`) +- It is passed into a function as an argument (`doSomething(foo)`) +- It is read inside of a function that is passed to another function (`doSomething(function() { foo(); })`) + +A variable is _not_ considered to be used if it is only ever declared +(`var foo = 5`) or assigned to (`foo = 7`). + +#### Ignored Files + +This rule ignores `.d.ts` files and `.vue` files entirely. Variables, +classes, interfaces, and types declared in `.d.ts` files are generally +used by other files, which are not checked by Oxlint. Since Oxlint does +not support parsing Vue templates, this rule cannot tell if a variable +is used or unused in a Vue file. + +#### Exported + +The original ESLint rule recognizes `/* exported variableName */` +comments as a way to indicate that a variable is used in another script +and should not be considered unused. Since ES6 modules are now a TC39 +standard, Oxlint does not support this feature. + +### Example + +Examples of **incorrect** code for this rule: + +```javascript +/*eslint no-unused-vars: "error"*/ +/*global some_unused_var*/ + +// It checks variables you have defined as global +some_unused_var = 42; + +var x; + +// Write-only variables are not considered as used. +var y = 10; +y = 5; + +// A read for a modification of itself is not considered as used. +var z = 0; +z = z + 1; + +// By default, unused arguments cause warnings. +(function (foo) { + return 5; +})(); + +// Unused recursive functions also cause warnings. +function fact(n) { + if (n < 2) return 1; + return n * fact(n - 1); +} + +// When a function definition destructures an array, unused entries from +// the array also cause warnings. +function getY([x, y]) { + return y; +} +``` + +Examples of **correct** code for this rule: + +```javascript +/*eslint no-unused-vars: "error"*/ + +var x = 10; +alert(x); + +// foo is considered used here +myFunc( + function foo() { + // ... + }.bind(this), +); + +(function (foo) { + return foo; +})(); + +var myFunc; +myFunc = setTimeout(function () { + // myFunc is considered used + myFunc(); +}, 50); + +// Only the second argument from the destructured array is used. +function getY([, y]) { + return y; +} +``` + +Examples of **incorrect** code for `/* exported variableName */` operation: + +```javascript +/* exported global_var */ + +// Not respected, use ES6 modules instead. +var global_var = 42; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-useless-catch.md b/src/docs/guide/usage/linter/rules/eslint/no-useless-catch.md new file mode 100644 index 0000000000..115c47726a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-useless-catch.md @@ -0,0 +1,30 @@ + + +# eslint/no-useless-catch + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow unnecessary catch clauses + +### Why is this bad? + +A catch clause that only rethrows the original error is redundant, +and has no effect on the runtime behavior of the program. +These redundant clauses can be a source of confusion and code bloat, +so it’s better to disallow these unnecessary catch clauses. + +### Example + +```javascript +try { + doSomethingThatMightThrow(); +} catch (e) { + throw e; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-useless-concat.md b/src/docs/guide/usage/linter/rules/eslint/no-useless-concat.md new file mode 100644 index 0000000000..1e4ca4542c --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-useless-concat.md @@ -0,0 +1,20 @@ + + +# eslint/no-useless-concat + +
+
+ +### What it does + +Disallow unnecessary concatenation of literals or template literals + +### Why is this bad? + +It’s unnecessary to concatenate two strings together. + +### Example + +```javascript +var foo = "a" + "b"; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-useless-constructor.md b/src/docs/guide/usage/linter/rules/eslint/no-useless-constructor.md new file mode 100644 index 0000000000..38bdc5cce9 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-useless-constructor.md @@ -0,0 +1,61 @@ + + +# eslint/no-useless-constructor + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Disallow unnecessary constructors + +This rule flags class constructors that can be safely removed without +changing how the class works. + +ES2015 provides a default class constructor if one is not specified. As +such, it is unnecessary to provide an empty constructor or one that +simply delegates into its parent class, as in the following examples: + +### Example + +Examples of **incorrect** code for this rule: + +```javascript +class A { + constructor() {} +} + +class B extends A { + constructor(...args) { + super(...args); + } +} +``` + +Examples of **correct** code for this rule: + +```javascript +class A {} + +class B { + constructor() { + doSomething(); + } +} + +class C extends A { + constructor() { + super("foo"); + } +} + +class D extends A { + constructor() { + super(); + doSomething(); + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-useless-escape.md b/src/docs/guide/usage/linter/rules/eslint/no-useless-escape.md new file mode 100644 index 0000000000..15d7cecb5e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-useless-escape.md @@ -0,0 +1,60 @@ + + +# eslint/no-useless-escape + +
+ + This rule is turned on by default. + + +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Disallow unnecessary escape characters + +### Why is this bad? + +### Example + +Examples of **incorrect** code for this rule: + +```javascript +/*eslint no-useless-escape: "error"*/ + +"\'"; +'\"'; +"\#"; +"\e"; +`\"`; +`\"${foo}\"`; +`\#{foo}`; +/\!/; +/\@/; +/[\[]/; +/[a-z\-]/; +``` + +Examples of **correct** code for this rule: + +```javascript +/*eslint no-useless-escape: "error"*/ + +"\""; +'\''; +"\x12"; +"\u00a9"; +"\371"; +"xs\u2111"; +`\``; +`\${${foo}}`; +`$\{${foo}}`; +/\\/g; +/\t/g; +/\w\$\*\^\./; +/[[]/; +/[\]]/; +/[a-z-]/; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-useless-rename.md b/src/docs/guide/usage/linter/rules/eslint/no-useless-rename.md new file mode 100644 index 0000000000..5e6b990e33 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-useless-rename.md @@ -0,0 +1,31 @@ + + +# eslint/no-useless-rename + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow renaming import, export, and destructured assignments to the same name. + +### Why is this bad? + +It is unnecessary to rename a variable to the same name. + +### Example + +```javascript +// Bad +import { foo as foo } from "foo"; +const { bar: bar } = obj; +export { baz as baz }; + +// Good +import { foo } from "foo"; +const { bar: renamed } = obj; +export { baz }; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-var.md b/src/docs/guide/usage/linter/rules/eslint/no-var.md new file mode 100644 index 0000000000..875581aed0 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-var.md @@ -0,0 +1,32 @@ + + +# eslint/no-var + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +ECMAScript 6 allows programmers to create variables with block scope +instead of function scope using the `let` and `const` keywords. Block +scope is common in many other programming languages and helps +programmers avoid mistakes. + +### Why is this bad? + +Using `var` in an es6 environment triggers this error + +### Example + +```javascript +// error +var x = "y"; +var CONFIG = {}; + +// success +let x = "y"; +const CONFIG = {}; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-void.md b/src/docs/guide/usage/linter/rules/eslint/no-void.md new file mode 100644 index 0000000000..76be46249e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-void.md @@ -0,0 +1,23 @@ + + +# eslint/no-void + +
+
+ +### What it does + +Disallow `void` operators. + +### Example + +```javascript +// error +void 0; +var foo = void 0; + +// success +("var foo = bar()"); +("foo.void()"); +("foo.void = bar"); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/no-with.md b/src/docs/guide/usage/linter/rules/eslint/no-with.md new file mode 100644 index 0000000000..447ef02f48 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/no-with.md @@ -0,0 +1,25 @@ + + +# eslint/no-with + +
+ + This rule is turned on by default. + +
+ +### What it does + +Disallow `with` statements + +### Why is this bad? + +The with statement is potentially problematic because it adds members of an object to the current scope, making it impossible to tell what a variable inside the block actually refers to. + +### Example + +```javascript +with (point) { + r = Math.sqrt(x * x + y * y); // is r a member of point? +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/prefer-exponentiation-operator.md b/src/docs/guide/usage/linter/rules/eslint/prefer-exponentiation-operator.md new file mode 100644 index 0000000000..2718aeb649 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/prefer-exponentiation-operator.md @@ -0,0 +1,22 @@ + + +# eslint/prefer-exponentiation-operator + +
+
+ +### What it does + +Disallow the use of Math.pow in favor of the \*\* operator + +### Why is this bad? + +Introduced in ES2016, the infix exponentiation operator \*\* is an alternative for the +standard Math.pow function. Infix notation is considered to be more readable and thus more +preferable than the function notation. + +### Example + +```javascript +Math.pow(a, b); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/prefer-numeric-literals.md b/src/docs/guide/usage/linter/rules/eslint/prefer-numeric-literals.md new file mode 100644 index 0000000000..9ec24ec3ec --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/prefer-numeric-literals.md @@ -0,0 +1,33 @@ + + +# eslint/prefer-numeric-literals + +
+ +🛠️ An auto-fix is available for this rule for some violations. + +
+ +### What it does + +Disallow parseInt() and Number.parseInt() in favor of binary, octal, and hexadecimal +literals. + +### Why is this bad? + +The parseInt() and Number.parseInt() functions can be used to turn binary, octal, and +hexadecimal strings into integers. As binary, octal, and hexadecimal literals are supported +in ES6, this rule encourages use of those numeric literals instead of parseInt() or +Number.parseInt(). + +### Example + +```javascript +parseInt("111110111", 2) === 503; +parseInt(`111110111`, 2) === 503; +parseInt("767", 8) === 503; +parseInt("1F7", 16) === 503; +Number.parseInt("111110111", 2) === 503; +Number.parseInt("767", 8) === 503; +Number.parseInt("1F7", 16) === 503; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/radix.md b/src/docs/guide/usage/linter/rules/eslint/radix.md new file mode 100644 index 0000000000..060e42fa63 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/radix.md @@ -0,0 +1,24 @@ + + +# eslint/radix + +
+
+ +### What it does + +Enforce the consistent use of the radix argument when using `parseInt()`. + +### Why is this bad? + +Using the `parseInt()` function without specifying the radix can lead to unexpected results. + +### Example + +```javascript +// error +var num = parseInt("071"); // 57 + +// success +var num = parseInt("071", 10); // 71 +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/require-await.md b/src/docs/guide/usage/linter/rules/eslint/require-await.md new file mode 100644 index 0000000000..0d02ae872f --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/require-await.md @@ -0,0 +1,57 @@ + + +# eslint/require-await + +
+
+ +### What it does + +Disallow async functions which have no `await` expression. + +### Why is this bad? + +Asynchronous functions in JavaScript behave differently than other +functions in two important ways: + +1. The return value is always a `Promise`. +2. You can use the `await` operator inside of them. + +The primary reason to use asynchronous functions is typically to use the +await operator, such as this: + +```js +async function fetchData(processDataItem) { + const response = await fetch(DATA_URL); + const data = await response.json(); + + return data.map(processDataItem); +} +``` + +Asynchronous functions that don’t use await might not need to be +asynchronous functions and could be the unintentional result of +refactoring. + +Note: this rule ignores async generator functions. This is because +generators yield rather than return a value and async generators might +yield all the values of another async generator without ever actually +needing to use await. + +### Example + +Examples of **incorrect** code for this rule: + +```js +async function foo() { + doSomething(); +} +``` + +Examples of **correct** code for this rule: + +```js +async function foo() { + await doSomething(); +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/require-yield.md b/src/docs/guide/usage/linter/rules/eslint/require-yield.md new file mode 100644 index 0000000000..bf6c53438b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/require-yield.md @@ -0,0 +1,25 @@ + + +# eslint/require-yield + +
+ + This rule is turned on by default. + +
+ +### What it does + +This rule generates warnings for generator functions that do not have the yield keyword. + +### Why is this bad? + +Probably a mistake. + +### Example + +```javascript +function* foo() { + return 10; +} +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/sort-imports.md b/src/docs/guide/usage/linter/rules/eslint/sort-imports.md new file mode 100644 index 0000000000..dbfea025a4 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/sort-imports.md @@ -0,0 +1,28 @@ + + +# eslint/sort-imports + +
+ +🛠️ An auto-fix is available for this rule for some violations. + +
+ +### What it does + +This rule checks all import declarations and verifies that all imports are first sorted +by the used member syntax and then alphabetically by the first member or alias name. + +When declaring multiple imports, a sorted list of import declarations make it easier for developers to read +the code and find necessary imports later. + +### Why is this bad? + +### Example + +```javascript +import { b, a, c } from "foo.js"; + +import d from "foo.js"; +import e from "bar.js"; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/symbol-description.md b/src/docs/guide/usage/linter/rules/eslint/symbol-description.md new file mode 100644 index 0000000000..e15c2de5c3 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/symbol-description.md @@ -0,0 +1,36 @@ + + +# eslint/symbol-description + +
+
+ +### What it does + +Require symbol descriptions. + +### Why is this bad? + +The Symbol function may have an optional description. + +```js +var foo = Symbol("some description"); + +var someString = "some description"; +var bar = Symbol(someString); +``` + +Using `description` promotes easier debugging: when a symbol is logged the description is used: + +```js +var foo = Symbol("some description"); + +console.log(foo); +// prints - Symbol(some description) +``` + +### Example + +```javascript +var foo = Symbol(); +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/unicode-bom.md b/src/docs/guide/usage/linter/rules/eslint/unicode-bom.md new file mode 100644 index 0000000000..d9f0093278 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/unicode-bom.md @@ -0,0 +1,27 @@ + + +# eslint/unicode-bom + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Require or disallow Unicode byte order mark (BOM) + +### Why is this bad? + +The Unicode Byte Order Mark (BOM) is used to specify whether code units are big endian or +little endian. That is, whether the most significant or least significant bytes come first. +UTF-8 does not require a BOM because byte ordering does not matter when characters are a +single byte. Since UTF-8 is the dominant encoding of the web, we make "never" the default +option. + +### Example + +```javascript +var a = 123; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/use-isnan.md b/src/docs/guide/usage/linter/rules/eslint/use-isnan.md new file mode 100644 index 0000000000..8033531b00 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/use-isnan.md @@ -0,0 +1,40 @@ + + +# eslint/use-isnan + +
+ + This rule is turned on by default. + + +🛠️ An auto-fix is available for this rule for some violations. + +
+ +### What it does + +Disallows checking against NaN without using isNaN() call. + +### Why is this bad? + +In JavaScript, NaN is a special value of the Number type. +It’s used to represent any of the “not-a-number” values represented +by the double-precision 64-bit format as specified by the IEEE Standard +for Binary Floating-Point Arithmetic. + +Because NaN is unique in JavaScript by not being equal to anything, including itself, +the results of comparisons to NaN are confusing: + +- NaN === NaN or NaN == NaN evaluate to false +- NaN !== NaN or NaN != NaN evaluate to true + +Therefore, use Number.isNaN() or global isNaN() functions to test whether a value is NaN. + +### Example + +```javascript +foo == NaN; +foo === NaN; +foo <= NaN; +foo > NaN; +``` diff --git a/src/docs/guide/usage/linter/rules/eslint/valid-typeof.md b/src/docs/guide/usage/linter/rules/eslint/valid-typeof.md new file mode 100644 index 0000000000..7b9acef7bc --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/valid-typeof.md @@ -0,0 +1,36 @@ + + +# eslint/valid-typeof + +
+ + This rule is turned on by default. + + +🛠️ An auto-fix is available for this rule for some violations. + +
+ +### What it does + +Enforce comparing `typeof` expressions against valid strings + +### Why is this bad? + +It is usually a typing mistake to compare the result of a `typeof` +operator to other string literals. + +### Example + +```js +// requireStringLiterals: false +// incorrect: +typeof foo === "strnig"; +// correct: +typeof foo === "string"; +typeof foo === baz; + +// requireStringLiterals: true +// incorrect: +typeof foo === baz; +``` diff --git a/src/docs/guide/usage/linter/rules/import/default.md b/src/docs/guide/usage/linter/rules/import/default.md new file mode 100644 index 0000000000..31b485dc11 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/default.md @@ -0,0 +1,22 @@ + + +# import/default + +
+
+ +### What it does + +If a default import is requested, this rule will report if there is no default export in the imported module. + +### Example + +```javascript +// ./bar.js +export function bar() { + return null; +} + +// ./foo.js +import bar from "./bar"; // no default export found in ./bar +``` diff --git a/src/docs/guide/usage/linter/rules/import/export.md b/src/docs/guide/usage/linter/rules/import/export.md new file mode 100644 index 0000000000..40c5c2d6f7 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/export.md @@ -0,0 +1,18 @@ + + +# import/export + +
+
+ +### What it does + +Reports funny business with exports, like repeated exports of names or defaults. + +### Example + +```javascript +let foo; +export { foo }; // Multiple exports of name 'foo'. +export * from "./export-all"; // export-all.js also export foo +``` diff --git a/src/docs/guide/usage/linter/rules/import/max-dependencies.md b/src/docs/guide/usage/linter/rules/import/max-dependencies.md new file mode 100644 index 0000000000..ea8f9318d4 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/max-dependencies.md @@ -0,0 +1,26 @@ + + +# import/max-dependencies + +
+
+ +### What it does + +Forbid modules to have too many dependencies (import or require statements). + +### Why is this bad? + +This is a useful rule because a module with too many dependencies is a code smell, and +usually indicates the module is doing too much and/or should be broken up into smaller +modules. + +### Example + +Given `{"max": 2}` + +```javascript +import a from "./a"; +import b from "./b"; +import c from "./c"; +``` diff --git a/src/docs/guide/usage/linter/rules/import/named.md b/src/docs/guide/usage/linter/rules/import/named.md new file mode 100644 index 0000000000..9b50001b87 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/named.md @@ -0,0 +1,61 @@ + + +# import/named + +
+
+ +### What it does + +Verifies that all named imports are part of the set of named exports in +the referenced module. + +For `export`, verifies that all named exports exist in the referenced +module. + +Note: for packages, the plugin will find exported names from +`jsnext:main` (deprecated) or `module`, if present in `package.json`. +Redux's npm module includes this key, and thereby is lintable, for +example. + +A module path that is ignored or not unambiguously an ES module will not +be reported when imported. Note that type imports and exports, as used +by Flow, are always ignored. + +### Why is this bad? + +### Example + +Given + +```js +// ./foo.js +export const foo = "I'm so foo"; +``` + +The following is considered valid: + +```js +// ./bar.js +import { foo } from "./foo"; + +// ES7 proposal +export { foo as bar } from "./foo"; + +// node_modules without jsnext:main are not analyzed by default +// (import/ignore setting) +import { SomeNonsenseThatDoesntExist } from "react"; +``` + +...and the following are reported: + +```js +// ./baz.js +import { notFoo } from "./foo"; + +// ES7 proposal +export { notFoo as defNotBar } from "./foo"; + +// will follow 'jsnext:main', if available +import { dontCreateStore } from "redux"; +``` diff --git a/src/docs/guide/usage/linter/rules/import/namespace.md b/src/docs/guide/usage/linter/rules/import/namespace.md new file mode 100644 index 0000000000..f1e032a2ea --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/namespace.md @@ -0,0 +1,15 @@ + + +# import/namespace + +
+
+ +### What it does + +Enforces names exist at the time they are dereferenced, when imported as +a full namespace (i.e. `import * as foo from './foo'; foo.bar();` will +report if bar is not exported by `./foo.`). Will report at the import +declaration if there are no exported names found. Also, will report for +computed references (i.e. `foo["bar"]()`). Reports on assignment to a +member of an imported namespace. diff --git a/src/docs/guide/usage/linter/rules/import/no-amd.md b/src/docs/guide/usage/linter/rules/import/no-amd.md new file mode 100644 index 0000000000..a96a71a462 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/no-amd.md @@ -0,0 +1,20 @@ + + +# import/no-amd + +
+
+ +### What it does + +Forbid AMD `require` and `define` calls. + +### Example + +```javascript +// fail +require([a, b], function () {}); +// pass +require("../name"); +require(`../name`); +``` diff --git a/src/docs/guide/usage/linter/rules/import/no-cycle.md b/src/docs/guide/usage/linter/rules/import/no-cycle.md new file mode 100644 index 0000000000..6a9c22dcc4 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/no-cycle.md @@ -0,0 +1,34 @@ + + +# import/no-cycle + +
+
+ +### What it does + +Ensures that there is no resolvable path back to this module via its dependencies. + +This includes cycles of depth 1 (imported module imports me) to "∞" (or Infinity), +if the maxDepth option is not set. + +### Why is this bad? + +Dependency cycles lead to confusing architectures where bugs become hard to find. + +It is common to import an `undefined` value that is caused by a cyclic dependency. + +### Example + +```javascript +// dep-b.js +import "./dep-a.js"; +export function b() { + /* ... */ +} +``` + +```javascript +// dep-a.js +import { b } from "./dep-b.js"; // reported: Dependency cycle detected. +``` diff --git a/src/docs/guide/usage/linter/rules/import/no-default-export.md b/src/docs/guide/usage/linter/rules/import/no-default-export.md new file mode 100644 index 0000000000..b9641259a1 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/no-default-export.md @@ -0,0 +1,29 @@ + + +# import/no-default-export + +
+
+ +### What it does + +Forbid a module to have a default exports. This help your editor to provide better auto imports. + +### Examples + +```javascript +// bad1.js + +// There is a default export. +export const foo = "foo"; +const bar = "bar"; +export default "bar"; +``` + +```javascript +// bad2.js + +// There is a default export. +const foo = "foo"; +export { foo as default }; +``` diff --git a/src/docs/guide/usage/linter/rules/import/no-duplicates.md b/src/docs/guide/usage/linter/rules/import/no-duplicates.md new file mode 100644 index 0000000000..f7f204ec33 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/no-duplicates.md @@ -0,0 +1,10 @@ + + +# import/no-duplicates + +
+
+ +### What it does + +Reports if a resolved path is imported more than once. diff --git a/src/docs/guide/usage/linter/rules/import/no-named-as-default-member.md b/src/docs/guide/usage/linter/rules/import/no-named-as-default-member.md new file mode 100644 index 0000000000..dd8e49c8b0 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/no-named-as-default-member.md @@ -0,0 +1,26 @@ + + +# import/no-named-as-default-member + +
+
+ +### What it does + +Reports use of an exported name as a property on the default export. + +### Example + +```javascript +// ./bar.js +export function bar() { + return null; +} +export default () => { + return 1; +}; + +// ./foo.js +import bar from "./bar"; +const bar = foo.bar; // trying to access named export via default +``` diff --git a/src/docs/guide/usage/linter/rules/import/no-named-as-default.md b/src/docs/guide/usage/linter/rules/import/no-named-as-default.md new file mode 100644 index 0000000000..889db6fd23 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/no-named-as-default.md @@ -0,0 +1,31 @@ + + +# import/no-named-as-default + +
+
+ +### What it does + +Reports use of an exported name as the locally imported name of a default export. + +### Example + +```javascript +// foo.js +export default "foo"; +export const bar = "baz"; +``` + +Valid: + +```javascript +import foo from "./foo.js"; +``` + +Invalid: + +```javascript +// using exported name 'bar' as identifier for default export. +import bar from "./foo.js"; +``` diff --git a/src/docs/guide/usage/linter/rules/import/no-self-import.md b/src/docs/guide/usage/linter/rules/import/no-self-import.md new file mode 100644 index 0000000000..1af163112b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/no-self-import.md @@ -0,0 +1,18 @@ + + +# import/no-self-import + +
+
+ +### What it does + +Forbid a module from importing itself. This can sometimes happen during refactoring. + +### Example + +```javascript +// foo.js +import foo from "./foo.js"; +const foo = require("./foo"); +``` diff --git a/src/docs/guide/usage/linter/rules/import/no-webpack-loader-syntax.md b/src/docs/guide/usage/linter/rules/import/no-webpack-loader-syntax.md new file mode 100644 index 0000000000..7092f33f40 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/import/no-webpack-loader-syntax.md @@ -0,0 +1,25 @@ + + +# import/no-webpack-loader-syntax + +
+
+ +### What it does + +Forbid webpack loader syntax in imports. + +### Why is this bad? + +This loader syntax is non-standard, so it couples the code to webpack. The recommended way to +specify webpack loader configuration is in a [Webpack configuration file](https://webpack.js.org/concepts/loaders/#configuration). + +### Example + +```javascript +import myModule from "my-loader!my-module"; +import theme from "style!css!./theme.css"; + +var myModule = require("my-loader!./my-module"); +var theme = require("style!css!./theme.css"); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/consistent-test-it.md b/src/docs/guide/usage/linter/rules/jest/consistent-test-it.md new file mode 100644 index 0000000000..7a438269fe --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/consistent-test-it.md @@ -0,0 +1,87 @@ + + +# jest/consistent-test-it + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Jest allows you to choose how you want to define your tests, using the `it` or +the `test` keywords, with multiple permutations for each: + +- **it:** `it`, `xit`, `fit`, `it.only`, `it.skip`. +- **test:** `test`, `xtest`, `test.only`, `test.skip`. + +### Example + +```javascript +/*eslint jest/consistent-test-it: ["error", {"fn": "test"}]*/ +test("foo"); // valid +test.only("foo"); // valid + +it("foo"); // invalid +it.only("foo"); // invalid +``` + +```javascript +/*eslint jest/consistent-test-it: ["error", {"fn": "it"}]*/ +it("foo"); // valid +it.only("foo"); // valid +test("foo"); // invalid +test.only("foo"); // invalid +``` + +```javascript +/*eslint jest/consistent-test-it: ["error", {"fn": "it", "withinDescribe": "test"}]*/ +it("foo"); // valid +describe("foo", function () { + test("bar"); // valid +}); + +test("foo"); // invalid +describe("foo", function () { + it("bar"); // invalid +}); +``` + +#### Options + +This rule can be configured as follows + +```json5 +{ + type: "object", + properties: { + fn: { + enum: ["it", "test"], + }, + withinDescribe: { + enum: ["it", "test"], + }, + }, + additionalProperties: false, +} +``` + +##### fn + +Decides whether to use `test` or `it`. + +##### withinDescribe + +Decides whether to use `test` or `it` within a `describe` scope. + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/consistent-test-it.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/consistent-test-it": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/expect-expect.md b/src/docs/guide/usage/linter/rules/jest/expect-expect.md new file mode 100644 index 0000000000..6eecad432d --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/expect-expect.md @@ -0,0 +1,34 @@ + + +# jest/expect-expect + +
+
+ +### What it does + +This rule triggers when there is no call made to `expect` in a test, ensure that there is at least one `expect` call made in a test. + +### Why is this bad? + +People may forget to add assertions. + +### Example + +```javascript +it("should be a test", () => { + console.log("no assertion"); +}); +test("should assert something", () => {}); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/expect-expect": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/max-expects.md b/src/docs/guide/usage/linter/rules/jest/max-expects.md new file mode 100644 index 0000000000..9293cc1b42 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/max-expects.md @@ -0,0 +1,39 @@ + + +# jest/max-expects + +
+
+ +### What it does + +As more assertions are made, there is a possible tendency for the test to be +more likely to mix multiple objectives. To avoid this, this rule reports when +the maximum number of assertions is exceeded. + +### Why is this bad? + +This rule enforces a maximum number of `expect()` calls. +The following patterns are considered warnings (with the default option of `{ "max": 5 } `): + +### Example + +```javascript +test("should not pass", () => { + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); +}); + +it("should not pass", () => { + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); + expect(true).toBeDefined(); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/max-nested-describe.md b/src/docs/guide/usage/linter/rules/jest/max-nested-describe.md new file mode 100644 index 0000000000..db4ad16d86 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/max-nested-describe.md @@ -0,0 +1,85 @@ + + +# jest/max-nested-describe + +
+
+ +### What it does + +This rule enforces a maximum depth to nested `describe()` calls to improve code +clarity in your tests. + +The following patterns are considered warnings (with the default option of +`{ "max": 5 } `): + +### Example + +```javascript +// invalid +describe("foo", () => { + describe("bar", () => { + describe("baz", () => { + describe("qux", () => { + describe("quxx", () => { + describe("too many", () => { + it("should get something", () => { + expect(getSomething()).toBe("Something"); + }); + }); + }); + }); + }); + }); +}); + +describe("foo", function () { + describe("bar", function () { + describe("baz", function () { + describe("qux", function () { + describe("quxx", function () { + describe("too many", function () { + it("should get something", () => { + expect(getSomething()).toBe("Something"); + }); + }); + }); + }); + }); + }); +}); + +// valid +describe("foo", () => { + describe("bar", () => { + it("should get something", () => { + expect(getSomething()).toBe("Something"); + }); + }); + describe("qux", () => { + it("should get something", () => { + expect(getSomething()).toBe("Something"); + }); + }); +}); + +describe("foo2", function () { + it("should get something", () => { + expect(getSomething()).toBe("Something"); + }); +}); + +describe("foo", function () { + describe("bar", function () { + describe("baz", function () { + describe("qux", function () { + describe("this is the limit", function () { + it("should get something", () => { + expect(getSomething()).toBe("Something"); + }); + }); + }); + }); + }); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-alias-methods.md b/src/docs/guide/usage/linter/rules/jest/no-alias-methods.md new file mode 100644 index 0000000000..294be50299 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-alias-methods.md @@ -0,0 +1,45 @@ + + +# jest/no-alias-methods + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +This rule ensures that only the canonical name as used in the Jest documentation is used in the code. + +### Why is this bad? + +These aliases are going to be removed in the next major version of Jest - see [jestjs/jest#13164](https://github.com/jestjs/jest/issues/13164) for more. +This rule will makes it easier to search for all occurrences of the method within code, and it ensures consistency among the method names used. + +### Example + +```javascript +expect(a).toBeCalled(); +expect(a).toBeCalledTimes(); +expect(a).toBeCalledWith(); +expect(a).lastCalledWith(); +expect(a).nthCalledWith(); +expect(a).toReturn(); +expect(a).toReturnTimes(); +expect(a).toReturnWith(); +expect(a).lastReturnedWith(); +expect(a).nthReturnedWith(); +expect(a).toThrowError(); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-alias-methods.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/no-alias-methods": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-commented-out-tests.md b/src/docs/guide/usage/linter/rules/jest/no-commented-out-tests.md new file mode 100644 index 0000000000..e15b155abb --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-commented-out-tests.md @@ -0,0 +1,39 @@ + + +# jest/no-commented-out-tests + +
+
+ +### What it does + +This rule raises a warning about commented out tests. It's similar to +no-disabled-tests rule. + +### Why is this bad? + +You may forget to uncomment some tests. This rule raises a warning about commented out tests. It's similar to +no-disabled-tests rule. + +### Example + +```javascript +// describe('foo', () => {}); +// it('foo', () => {}); +// test('foo', () => {}); + +// describe.skip('foo', () => {}); +// it.skip('foo', () => {}); +// test.skip('foo', () => {}); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-commented-out-tests.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/no-commented-out-tests": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-conditional-expect.md b/src/docs/guide/usage/linter/rules/jest/no-conditional-expect.md new file mode 100644 index 0000000000..199a24117b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-conditional-expect.md @@ -0,0 +1,45 @@ + + +# jest/no-conditional-expect + +
+
+ +### What it does + +This rule prevents the use of expect in conditional blocks, such as ifs & catch(s). +This includes using expect in callbacks to functions named catch, which are assumed to be promises. + +### Why is this bad? + +Jest only considers a test to have failed if it throws an error, meaning if calls to assertion functions like expect occur in conditional code such as a catch statement, tests can end up passing but not actually test anything. +Additionally, conditionals tend to make tests more brittle and complex, as they increase the amount of mental thinking needed to understand what is actually being tested. + +### Example + +```javascript +it("foo", () => { + doTest && expect(1).toBe(2); +}); + +it("bar", () => { + if (!skipTest) { + expect(1).toEqual(2); + } +}); + +it("throws an error", async () => { + await foo().catch((error) => expect(error).toBeInstanceOf(error)); +}); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-conditional-expect.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/no-conditional-expect": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-confusing-set-timeout.md b/src/docs/guide/usage/linter/rules/jest/no-confusing-set-timeout.md new file mode 100644 index 0000000000..a70f5a8038 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-confusing-set-timeout.md @@ -0,0 +1,46 @@ + + +# jest/no-confusing-set-timeout + +
+
+ +### What it does + +Disallow confusing usages of jest.setTimeout + +### Why is this bad? + +- being called anywhere other than in global scope +- being called multiple times +- being called after other Jest functions like hooks, `describe`, `test`, or `it` + +### Example + +All of these are invalid case: + +```javascript +escribe("test foo", () => { + jest.setTimeout(1000); + it("test-description", () => { + // test logic; + }); +}); + +describe("test bar", () => { + it("test-description", () => { + jest.setTimeout(1000); + // test logic; + }); +}); + +test("foo-bar", () => { + jest.setTimeout(1000); +}); + +describe("unit test", () => { + beforeEach(() => { + jest.setTimeout(1000); + }); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-deprecated-functions.md b/src/docs/guide/usage/linter/rules/jest/no-deprecated-functions.md new file mode 100644 index 0000000000..77c3447775 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-deprecated-functions.md @@ -0,0 +1,55 @@ + + +# jest/no-deprecated-functions + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Over the years Jest has accrued some debt in the form of functions that have +either been renamed for clarity, or replaced with more powerful APIs. + +This rule can also autofix a number of these deprecations for you. + +#### `jest.resetModuleRegistry` + +This function was renamed to `resetModules` in Jest 15 and removed in Jest 27. + +#### `jest.addMatchers` + +This function was replaced with `expect.extend` in Jest 17 and removed in Jest 27. + +#### `require.requireActual` & `require.requireMock` + +These functions were replaced in Jest 21 and removed in Jest 26. + +Originally, the `requireActual` & `requireMock` the `requireActual`& +`requireMock` functions were placed onto the `require` function. + +These functions were later moved onto the `jest` object in order to be easier +for type checkers to handle, and their use via `require` deprecated. Finally, +the release of Jest 26 saw them removed from the `require` function altogether. + +#### `jest.runTimersToTime` + +This function was renamed to `advanceTimersByTime` in Jest 22 and removed in Jest 27. + +#### `jest.genMockFromModule` + +This function was renamed to `createMockFromModule` in Jest 26, and is scheduled for removal in Jest 30. + +### Why is this bad? + +While typically these deprecated functions are kept in the codebase for a number +of majors, eventually they are removed completely. + +### Example + +```javascript +jest.resetModuleRegistry; // since Jest 15 +jest.addMatchers; // since Jest 17 +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-disabled-tests.md b/src/docs/guide/usage/linter/rules/jest/no-disabled-tests.md new file mode 100644 index 0000000000..96b21144aa --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-disabled-tests.md @@ -0,0 +1,51 @@ + + +# jest/no-disabled-tests + +
+
+ +### What it does + +This rule raises a warning about disabled tests. + +### Why is this bad? + +Jest has a feature that allows you to temporarily mark tests as disabled. This +feature is often helpful while debugging or to create placeholders for future +tests. Before committing changes we may want to check that all tests are +running. + +### Example + +```js +describe.skip("foo", () => {}); +it.skip("foo", () => {}); +test.skip("foo", () => {}); + +describe["skip"]("bar", () => {}); +it["skip"]("bar", () => {}); +test["skip"]("bar", () => {}); + +xdescribe("foo", () => {}); +xit("foo", () => {}); +xtest("foo", () => {}); + +it("bar"); +test("bar"); + +it("foo", () => { + pending(); +}); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-disabled-tests.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/no-disabled-tests": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-done-callback.md b/src/docs/guide/usage/linter/rules/jest/no-done-callback.md new file mode 100644 index 0000000000..e1844f56a3 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-done-callback.md @@ -0,0 +1,48 @@ + + +# jest/no-done-callback + +
+
+ +### What it does + +This rule checks the function parameter of hooks & tests for use of the done argument, suggesting you return a promise instead. + +### Why is this bad? + +When calling asynchronous code in hooks and tests, jest needs to know when the asynchronous work is complete to progress the current run. +Originally the most common pattern to achieve this was to use callbacks: + +```javascript +test("the data is peanut butter", (done) => { + function callback(data) { + try { + expect(data).toBe("peanut butter"); + done(); + } catch (error) { + done(error); + } + } + + fetchData(callback); +}); +``` + +This can be very error-prone however, as it requires careful understanding of how assertions work in tests or otherwise tests won't behave as expected. + +### Example + +```javascript +beforeEach((done) => { + // ... +}); + +test("myFunction()", (done) => { + // ... +}); + +test("myFunction()", function (done) { + // ... +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-duplicate-hooks.md b/src/docs/guide/usage/linter/rules/jest/no-duplicate-hooks.md new file mode 100644 index 0000000000..1a27fbc2c2 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-duplicate-hooks.md @@ -0,0 +1,76 @@ + + +# jest/no-duplicate-hooks + +
+
+ +### What it does + +A `describe` block should not contain duplicate hooks. + +### Example + +```javascript +// invalid +describe("foo", () => { + beforeEach(() => { + // some setup + }); + beforeEach(() => { + // some setup + }); + test("foo_test", () => { + // some test + }); +}); + +// Nested describe scenario +describe("foo", () => { + beforeEach(() => { + // some setup + }); + test("foo_test", () => { + // some test + }); + describe("bar", () => { + test("bar_test", () => { + afterAll(() => { + // some teardown + }); + afterAll(() => { + // some teardown + }); + }); + }); +}); +``` + +```javascript +// valid +describe("foo", () => { + beforeEach(() => { + // some setup + }); + test("foo_test", () => { + // some test + }); +}); + +// Nested describe scenario +describe("foo", () => { + beforeEach(() => { + // some setup + }); + test("foo_test", () => { + // some test + }); + describe("bar", () => { + test("bar_test", () => { + beforeEach(() => { + // some setup + }); + }); + }); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-export.md b/src/docs/guide/usage/linter/rules/jest/no-export.md new file mode 100644 index 0000000000..7e63991718 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-export.md @@ -0,0 +1,25 @@ + + +# jest/no-export + +
+
+ +### What it does + +Prevents using exports if a file has one or more tests in it. + +### Why is this bad? + +This rule aims to eliminate duplicate runs of tests by exporting things from test files. +If you import from a test file, then all the tests in that file will be run in each imported instance. +so bottom line, don't export from a test, but instead move helper functions into a separate file when they need to be shared across tests. + +### Example + +```javascript +export function myHelper() {} +describe("a test", () => { + expect(1).toBe(1); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-focused-tests.md b/src/docs/guide/usage/linter/rules/jest/no-focused-tests.md new file mode 100644 index 0000000000..a9cadbcd3a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-focused-tests.md @@ -0,0 +1,49 @@ + + +# jest/no-focused-tests + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +This rule reminds you to remove `.only` from your tests by raising a warning +whenever you are using the exclusivity feature. + +### Why is this bad? + +Jest has a feature that allows you to focus tests by appending `.only` or +prepending `f` to a test-suite or a test-case. This feature is really helpful to +debug a failing test, so you don’t have to execute all of your tests. After you +have fixed your test and before committing the changes you have to remove +`.only` to ensure all tests are executed on your build tool. + +### Example + +```javascript +describe.only("foo", () => {}); +it.only("foo", () => {}); +describe["only"]("bar", () => {}); +it["only"]("bar", () => {}); +test.only("foo", () => {}); +test["only"]("bar", () => {}); +fdescribe("foo", () => {}); +fit("foo", () => {}); +fit.each` + table +`(); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-focused-tests.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/no-focused-tests": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-hooks.md b/src/docs/guide/usage/linter/rules/jest/no-hooks.md new file mode 100644 index 0000000000..2a49696b11 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-hooks.md @@ -0,0 +1,56 @@ + + +# jest/no-hooks + +
+
+ +### What it does + +Jest provides global functions for setup and teardown tasks, which are called before/after each test case +and each test suite. The use of these hooks promotes shared state between tests. + +### Why is this bad? + +This rule reports for the following function calls: + +- beforeAll +- beforeEach +- afterAll +- afterEach + +### Example + +```javascript +function setupFoo(options) { + /* ... */ +} +function setupBar(options) { + /* ... */ +} + +describe("foo", () => { + let foo; + beforeEach(() => { + foo = setupFoo(); + }); + afterEach(() => { + foo = null; + }); + it("does something", () => { + expect(foo.doesSomething()).toBe(true); + }); + describe("with bar", () => { + let bar; + beforeEach(() => { + bar = setupBar(); + }); + afterEach(() => { + bar = null; + }); + it("does something with bar", () => { + expect(foo.doesSomething(bar)).toBe(true); + }); + }); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-identical-title.md b/src/docs/guide/usage/linter/rules/jest/no-identical-title.md new file mode 100644 index 0000000000..14df0af49a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-identical-title.md @@ -0,0 +1,40 @@ + + +# jest/no-identical-title + +
+
+ +### What it does + +This rule looks at the title of every test and test suite. +It will report when two test suites or two test cases at the same level of a test suite have the same title. + +### Why is this bad? + +Having identical titles for two different tests or test suites may create confusion. +For example, when a test with the same title as another test in the same test suite fails, it is harder to know which one failed and thus harder to fix. + +### Example + +```javascript +describe("baz", () => { + //... +}); + +describe("baz", () => { + // Has the same title as a previous test suite + // ... +}); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-identical-title.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/no-identical-title": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-interpolation-in-snapshots.md b/src/docs/guide/usage/linter/rules/jest/no-interpolation-in-snapshots.md new file mode 100644 index 0000000000..9bb7a05293 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-interpolation-in-snapshots.md @@ -0,0 +1,36 @@ + + +# jest/no-interpolation-in-snapshots + +
+
+ +### What it does + +Prevents the use of string interpolations in snapshots. + +### Why is this bad? + +Interpolation prevents snapshots from being updated. Instead, properties should +be overloaded with a matcher by using +[property matchers](https://jestjs.io/docs/en/snapshot-testing#property-matchers). + +### Example + +```javascript +expect(something).toMatchInlineSnapshot( + `Object { + property: ${interpolated} + }`, +); + +expect(something).toMatchInlineSnapshot( + { other: expect.any(Number) }, + `Object { + other: Any, + property: ${interpolated} + }`, +); + +expect(errorThrowingFunction).toThrowErrorMatchingInlineSnapshot(`${interpolated}`); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-jasmine-globals.md b/src/docs/guide/usage/linter/rules/jest/no-jasmine-globals.md new file mode 100644 index 0000000000..003f003c9b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-jasmine-globals.md @@ -0,0 +1,25 @@ + + +# jest/no-jasmine-globals + +
+ +🛠️ An auto-fix is available for this rule for some violations. + +
+ +### What it does + +This rule reports on any usage of Jasmine globals, which is not ported to Jest, and suggests alternatives from Jest's own API. + +### Example + +```javascript +jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; +test("my test", () => { + pending(); +}); +test("my test", () => { + jasmine.createSpy(); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-large-snapshots.md b/src/docs/guide/usage/linter/rules/jest/no-large-snapshots.md new file mode 100644 index 0000000000..e3e19e809a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-large-snapshots.md @@ -0,0 +1,81 @@ + + +# jest/no-large-snapshots + +
+
+ +### What it does + +When using Jest's snapshot capability one should be mindful of the size of +created snapshots. As a general best practice snapshots should be limited in +size in order to be more manageable and reviewable. A stored snapshot is only as +good as its review and as such keeping it short, sweet, and readable is +important to allow for thorough reviews. + +### Example + +```javascript +// invalid +exports[`a large snapshot 1`] = ` +line 1 +line 2 +line 3 +line 4 +line 5 +line 6 +line 7 +line 8 +line 9 +line 10 +line 11 +line 12 +line 13 +line 14 +line 15 +line 16 +line 17 +line 18 +line 19 +line 20 +line 21 +line 22 +line 23 +line 24 +line 25 +line 26 +line 27 +line 28 +line 29 +line 30 +line 31 +line 32 +line 33 +line 34 +line 35 +line 36 +line 37 +line 38 +line 39 +line 40 +line 41 +line 42 +line 43 +line 44 +line 45 +line 46 +line 47 +line 48 +line 49 +line 50 +line 51 +`; + +// valid +exports[`a more manageable and readable snapshot 1`] = ` +line 1 +line 2 +line 3 +line 4 +`; +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-mocks-import.md b/src/docs/guide/usage/linter/rules/jest/no-mocks-import.md new file mode 100644 index 0000000000..90b02f98a4 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-mocks-import.md @@ -0,0 +1,18 @@ + + +# jest/no-mocks-import + +
+
+ +### What it does + +This rule reports imports from a path containing a **mocks** component. + +### Example + +```javascript +import thing from "./__mocks__/index"; +require("./__mocks__/index"); +require("__mocks__"); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-restricted-jest-methods.md b/src/docs/guide/usage/linter/rules/jest/no-restricted-jest-methods.md new file mode 100644 index 0000000000..090c8e6380 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-restricted-jest-methods.md @@ -0,0 +1,29 @@ + + +# jest/no-restricted-jest-methods + +
+
+ +### What it does + +Restrict the use of specific `jest` methods. + +### Example + +```javascript +jest.useFakeTimers(); +it("calls the callback after 1 second via advanceTimersByTime", () => { + // ... + + jest.advanceTimersByTime(1000); + + // ... +}); + +test("plays video", () => { + const spy = jest.spyOn(video, "play"); + + // ... +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-restricted-matchers.md b/src/docs/guide/usage/linter/rules/jest/no-restricted-matchers.md new file mode 100644 index 0000000000..5ea7e60b35 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-restricted-matchers.md @@ -0,0 +1,31 @@ + + +# jest/no-restricted-matchers + +
+
+ +### What it does + +Ban specific matchers & modifiers from being used, and can suggest alternatives. + +### Example + +```javascript +it("is false", () => { + // if this has a modifier (i.e. `not.toBeFalsy`), it would be considered fine + expect(a).toBeFalsy(); +}); + +it("resolves", async () => { + // all uses of this modifier are disallowed, regardless of matcher + await expect(myPromise()).resolves.toBe(true); +}); + +describe("when an error happens", () => { + it("does not upload the file", async () => { + // all uses of this matcher are disallowed + expect(uploadFileMock).not.toHaveBeenCalledWith("file.name"); + }); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-standalone-expect.md b/src/docs/guide/usage/linter/rules/jest/no-standalone-expect.md new file mode 100644 index 0000000000..8d138a7307 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-standalone-expect.md @@ -0,0 +1,23 @@ + + +# jest/no-standalone-expect + +
+
+ +### What it does + +Prevents `expect` statements outside of a `test` or `it` block. An `expect` +within a helper function (but outside of a `test` or `it` block) will not +trigger this rule. + +Statements like `expect.hasAssertions()` will NOT trigger this rule since these +calls will execute if they are not in a test block. + +### Example + +```javascript +describe("a test", () => { + expect(1).toBe(1); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-test-prefixes.md b/src/docs/guide/usage/linter/rules/jest/no-test-prefixes.md new file mode 100644 index 0000000000..ce04b4ed0b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-test-prefixes.md @@ -0,0 +1,44 @@ + + +# jest/no-test-prefixes + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Require using `.only` and `.skip` over `f` and `x`. + +### Why is this bad? + +Jest allows you to choose how you want to define focused and skipped tests, +with multiple permutations for each: + +- only & skip: it.only, test.only, describe.only, it.skip, test.skip, describe.skip. +- 'f' & 'x': fit, fdescribe, xit, xtest, xdescribe. + +This rule enforces usages from the only & skip list. + +### Example + +```javascript +fit("foo"); // invalid +fdescribe("foo"); // invalid +xit("foo"); // invalid +xtest("foo"); // invalid +xdescribe("foo"); // invalid +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/no-test-prefixes.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/no-test-prefixes": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-test-return-statement.md b/src/docs/guide/usage/linter/rules/jest/no-test-return-statement.md new file mode 100644 index 0000000000..b6c43544ad --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-test-return-statement.md @@ -0,0 +1,24 @@ + + +# jest/no-test-return-statement + +
+
+ +### What it does + +Disallow explicitly returning from tests. + +### Why is this bad? + +Tests in Jest should be void and not return values. +If you are returning Promises then you should update the test to use +`async/await`. + +### Example + +```javascript +test("one", () => { + return expect(1).toBe(1); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/no-untyped-mock-factory.md b/src/docs/guide/usage/linter/rules/jest/no-untyped-mock-factory.md new file mode 100644 index 0000000000..08be06af9c --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/no-untyped-mock-factory.md @@ -0,0 +1,72 @@ + + +# jest/no-untyped-mock-factory + +
+ +🛠️ An auto-fix is available for this rule for some violations. + +
+ +### What it does + +This rule triggers a warning if `mock()` or `doMock()` is used without a generic +type parameter or return type. + +### Why is this bad? + +By default, `jest.mock` and `jest.doMock` allow any type to be returned by a +mock factory. A generic type parameter can be used to enforce that the factory +returns an object with the same shape as the original module, or some other +strict type. Requiring a type makes it easier to use TypeScript to catch changes +needed in test mocks when the source module changes. + +### Example + +// invalid + +```typescript +jest.mock("../moduleName", () => { + return jest.fn(() => 42); +}); + +jest.mock("./module", () => ({ + ...jest.requireActual("./module"), + foo: jest.fn(), +})); + +jest.mock("random-num", () => { + return jest.fn(() => 42); +}); +``` + +// valid + +```typescript +// Uses typeof import() +jest.mock("../moduleName", () => { + return jest.fn(() => 42); +}); + +jest.mock("./module", () => ({ + ...jest.requireActual("./module"), + foo: jest.fn(), +})); + +// Uses custom type +jest.mock<() => number>("random-num", () => { + return jest.fn(() => 42); +}); + +// No factory +jest.mock("random-num"); + +// Virtual mock +jest.mock( + "../moduleName", + () => { + return jest.fn(() => 42); + }, + { virtual: true }, +); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-called-with.md b/src/docs/guide/usage/linter/rules/jest/prefer-called-with.md new file mode 100644 index 0000000000..1db368f7ad --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-called-with.md @@ -0,0 +1,24 @@ + + +# jest/prefer-called-with + +
+
+ +### What it does + +Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()` + +### Example + +```javascript +// valid +expect(noArgsFunction).toBeCalledWith(); +expect(roughArgsFunction).toBeCalledWith(expect.anything(), expect.any(Date)); +expect(anyArgsFunction).toBeCalledTimes(1); +expect(uncalledFunction).not.toBeCalled(); + +// invalid +expect(someFunction).toBeCalled(); +expect(someFunction).toHaveBeenCalled(); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-comparison-matcher.md b/src/docs/guide/usage/linter/rules/jest/prefer-comparison-matcher.md new file mode 100644 index 0000000000..6b1f20aa3d --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-comparison-matcher.md @@ -0,0 +1,37 @@ + + +# jest/prefer-comparison-matcher + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +This rule checks for comparisons in tests that could be replaced with one of the +following built-in comparison matchers: + +- `toBeGreaterThan` +- `toBeGreaterThanOrEqual` +- `toBeLessThan` +- `toBeLessThanOrEqual` + +### Examples + +```js +// invalid +expect(x > 5).toBe(true); +expect(x < 7).not.toEqual(true); +expect(x <= y).toStrictEqual(true); +``` + +```js /// +// valid +expect(x).toBeGreaterThan(5); +expect(x).not.toBeLessThanOrEqual(7); +expect(x).toBeLessThanOrEqual(y); +// special case - see below +expect(x < "Carl").toBe(true); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-equality-matcher.md b/src/docs/guide/usage/linter/rules/jest/prefer-equality-matcher.md new file mode 100644 index 0000000000..54fb6d2500 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-equality-matcher.md @@ -0,0 +1,25 @@ + + +# jest/prefer-equality-matcher + +
+
+ +### What it does + +Jest has built-in matchers for expecting equality, which allow for more readable +tests and error messages if an expectation fails. + +### Example + +```javascript +// invalid +expect(x === 5).toBe(true); +expect(name === "Carl").not.toEqual(true); +expect(myObj !== thatObj).toStrictEqual(true); + +// valid +expect(x).toBe(5); +expect(name).not.toEqual("Carl"); +expect(myObj).toStrictEqual(thatObj); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-expect-resolves.md b/src/docs/guide/usage/linter/rules/jest/prefer-expect-resolves.md new file mode 100644 index 0000000000..fba5d2209d --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-expect-resolves.md @@ -0,0 +1,51 @@ + + +# jest/prefer-expect-resolves + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +When working with promises, there are two primary ways you can test the resolved +value: + +1. use the `resolve` modifier on `expect` (`await expect(...).resolves.` style) +2. `await` the promise and assert against its result (`expect(await ...).` style) + +While the second style is arguably less dependent on `jest`, if the promise +rejects it will be treated as a general error, resulting in less predictable +behaviour and output from `jest`. + +Additionally, favoring the first style ensures consistency with its `rejects` +counterpart, as there is no way of "awaiting" a rejection. + +### Example + +```javascript +// valid +it("passes", async () => { + await expect(someValue()).resolves.toBe(true); +}); +it("is true", async () => { + const myPromise = Promise.resolve(true); + + await expect(myPromise).resolves.toBe(true); +}); + +it("errors", async () => { + await expect(Promise.reject(new Error("oh noes!"))).rejects.toThrowError("oh noes!"); +}); + +// invalid +it("passes", async () => { + expect(await someValue()).toBe(true); +}); +it("is true", async () => { + const myPromise = Promise.resolve(true); + expect(await myPromise).toBe(true); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-hooks-in-order.md b/src/docs/guide/usage/linter/rules/jest/prefer-hooks-in-order.md new file mode 100644 index 0000000000..4f017900e7 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-hooks-in-order.md @@ -0,0 +1,119 @@ + + +# jest/prefer-hooks-in-order + +
+
+ +### What it does + +While hooks can be setup in any order, they're always called by `jest` in this +specific order: + +1. `beforeAll` +2. `beforeEach` +3. `afterEach` +4. `afterAll` + +This rule aims to make that more obvious by enforcing grouped hooks be setup in +that order within tests. + +### Example + +```javascript +// invalid +describe("foo", () => { + beforeEach(() => { + seedMyDatabase(); + }); + beforeAll(() => { + createMyDatabase(); + }); + it("accepts this input", () => { + // ... + }); + it("returns that value", () => { + // ... + }); + describe("when the database has specific values", () => { + const specificValue = "..."; + beforeEach(() => { + seedMyDatabase(specificValue); + }); + + it("accepts that input", () => { + // ... + }); + it("throws an error", () => { + // ... + }); + afterEach(() => { + clearLogger(); + }); + beforeEach(() => { + mockLogger(); + }); + it("logs a message", () => { + // ... + }); + }); + afterAll(() => { + removeMyDatabase(); + }); +}); +``` + +```javascript +// valid +describe("foo", () => { + beforeAll(() => { + createMyDatabase(); + }); + + beforeEach(() => { + seedMyDatabase(); + }); + + it("accepts this input", () => { + // ... + }); + it("returns that value", () => { + // ... + }); + describe("when the database has specific values", () => { + const specificValue = "..."; + beforeEach(() => { + seedMyDatabase(specificValue); + }); + it("accepts that input", () => { + // ... + }); + it("throws an error", () => { + // ... + }); + beforeEach(() => { + mockLogger(); + }); + afterEach(() => { + clearLogger(); + }); + it("logs a message", () => { + // ... + }); + }); + afterAll(() => { + removeMyDatabase(); + }); +}); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/prefer-hooks-in-order.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/prefer-hooks-in-order": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-hooks-on-top.md b/src/docs/guide/usage/linter/rules/jest/prefer-hooks-on-top.md new file mode 100644 index 0000000000..5c20f1d16b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-hooks-on-top.md @@ -0,0 +1,117 @@ + + +# jest/prefer-hooks-on-top + +
+
+ +### What it does + +While hooks can be setup anywhere in a test file, they are always called in a +specific order, which means it can be confusing if they're intermixed with test +cases. + +### Example + +```javascript +// invalid +describe("foo", () => { + beforeEach(() => { + seedMyDatabase(); + }); + + it("accepts this input", () => { + // ... + }); + + beforeAll(() => { + createMyDatabase(); + }); + + it("returns that value", () => { + // ... + }); + + describe("when the database has specific values", () => { + const specificValue = "..."; + beforeEach(() => { + seedMyDatabase(specificValue); + }); + + it("accepts that input", () => { + // ... + }); + + it("throws an error", () => { + // ... + }); + + afterEach(() => { + clearLogger(); + }); + + beforeEach(() => { + mockLogger(); + }); + + it("logs a message", () => { + // ... + }); + }); + + afterAll(() => { + removeMyDatabase(); + }); +}); + +// valid +describe("foo", () => { + beforeAll(() => { + createMyDatabase(); + }); + + beforeEach(() => { + seedMyDatabase(); + }); + + afterAll(() => { + clearMyDatabase(); + }); + + it("accepts this input", () => { + // ... + }); + + it("returns that value", () => { + // ... + }); + + describe("when the database has specific values", () => { + const specificValue = "..."; + + beforeEach(() => { + seedMyDatabase(specificValue); + }); + + beforeEach(() => { + mockLogger(); + }); + + afterEach(() => { + clearLogger(); + }); + + it("accepts that input", () => { + // ... + }); + + it("throws an error", () => { + // ... + }); + + it("logs a message", () => { + // ... + }); + }); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-jest-mocked.md b/src/docs/guide/usage/linter/rules/jest/prefer-jest-mocked.md new file mode 100644 index 0000000000..92c4e5d695 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-jest-mocked.md @@ -0,0 +1,39 @@ + + +# jest/prefer-jest-mocked + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +When working with mocks of functions using Jest, it's recommended to use the +`jest.mocked()` helper function to properly type the mocked functions. This rule +enforces the use of `jest.mocked()` for better type safety and readability. + +Restricted types: + +- `jest.Mock` +- `jest.MockedFunction` +- `jest.MockedClass` +- `jest.MockedObject` + +### Examples + +```typescript +// invalid +(foo as jest.Mock).mockReturnValue(1); +const mock = (foo as jest.Mock).mockReturnValue(1); +(foo as unknown as jest.Mock).mockReturnValue(1); +(Obj.foo as jest.Mock).mockReturnValue(1); +([].foo as jest.Mock).mockReturnValue(1); + +// valid +jest.mocked(foo).mockReturnValue(1); +const mock = jest.mocked(foo).mockReturnValue(1); +jest.mocked(Obj.foo).mockReturnValue(1); +jest.mocked([].foo).mockReturnValue(1); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-lowercase-title.md b/src/docs/guide/usage/linter/rules/jest/prefer-lowercase-title.md new file mode 100644 index 0000000000..778a53838b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-lowercase-title.md @@ -0,0 +1,106 @@ + + +# jest/prefer-lowercase-title + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Enforce `it`, `test` and `describe` to have descriptions that begin with a +lowercase letter. This provides more readable test failures. This rule is not +enabled by default. + +### Example + +```javascript +// invalid +it("Adds 1 + 2 to equal 3", () => { + expect(sum(1, 2)).toBe(3); +}); + +// valid +it("adds 1 + 2 to equal 3", () => { + expect(sum(1, 2)).toBe(3); +}); +``` + +## Options + +```json +{ + "jest/prefer-lowercase-title": [ + "error", + { + "ignore": ["describe", "test"] + } + ] +} +``` + +### `ignore` + +This array option controls which Jest functions are checked by this rule. There +are three possible values: + +- `"describe"` +- `"test"` +- `"it"` + +By default, none of these options are enabled (the equivalent of +`{ "ignore": [] }`). + +Example of **correct** code for the `{ "ignore": ["describe"] }` option: + +```js +/* eslint jest/prefer-lowercase-title: ["error", { "ignore": ["describe"] }] */ +describe("Uppercase description"); +``` + +Example of **correct** code for the `{ "ignore": ["test"] }` option: + +```js +/* eslint jest/prefer-lowercase-title: ["error", { "ignore": ["test"] }] */ +test("Uppercase description"); +``` + +Example of **correct** code for the `{ "ignore": ["it"] }` option: + +```js +/* eslint jest/prefer-lowercase-title: ["error", { "ignore": ["it"] }] */ +it("Uppercase description"); +``` + +### `allowedPrefixes` + +This array option allows specifying prefixes, which contain capitals that titles +can start with. This can be useful when writing tests for API endpoints, where +you'd like to prefix with the HTTP method. +By default, nothing is allowed (the equivalent of `{ "allowedPrefixes": [] }`). + +Example of **correct** code for the `{ "allowedPrefixes": ["GET"] }` option: + +```js +/* eslint jest/prefer-lowercase-title: ["error", { "allowedPrefixes": ["GET"] }] */ +describe("GET /live"); +``` + +### `ignoreTopLevelDescribe` + +This option can be set to allow only the top-level `describe` blocks to have a +title starting with an upper-case letter. +Example of **correct** code for the `{ "ignoreTopLevelDescribe": true }` option: + +```js +/* eslint jest/prefer-lowercase-title: ["error", { "ignoreTopLevelDescribe": true }] */ +describe("MyClass", () => { + describe("#myMethod", () => { + it("does things", () => { + // + }); + }); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-mock-promise-shorthand.md b/src/docs/guide/usage/linter/rules/jest/prefer-mock-promise-shorthand.md new file mode 100644 index 0000000000..e8a25b06e3 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-mock-promise-shorthand.md @@ -0,0 +1,37 @@ + + +# jest/prefer-mock-promise-shorthand + +
+ +🛠️ An auto-fix is available for this rule for some violations. + +
+ +### What it does + +When working with mocks of functions that return promises, Jest provides some +API sugar functions to reduce the amount of boilerplate you have to write. +These methods should be preferred when possible. + +### Example + +```javascript +// invalid +jest.fn().mockImplementation(() => Promise.resolve(123)); +jest.spyOn(fs.promises, "readFile").mockReturnValue(Promise.reject(new Error("oh noes!"))); + +myFunction + .mockReturnValueOnce(Promise.resolve(42)) + .mockImplementationOnce(() => Promise.resolve(42)) + .mockReturnValue(Promise.reject(new Error("too many calls!"))); +``` + +// valid + +```javascript +jest.fn().mockResolvedValue(123); +jest.spyOn(fs.promises, "readFile").mockRejectedValue(new Error("oh noes!")); + +myFunction.mockResolvedValueOnce(42).mockResolvedValueOnce(42).mockRejectedValue(new Error("too many calls!")); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-spy-on.md b/src/docs/guide/usage/linter/rules/jest/prefer-spy-on.md new file mode 100644 index 0000000000..07cd4b1781 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-spy-on.md @@ -0,0 +1,34 @@ + + +# jest/prefer-spy-on + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +When mocking a function by overwriting a property you have to manually restore +the original implementation when cleaning up. When using `jest.spyOn()` Jest +keeps track of changes, and they can be restored with `jest.restoreAllMocks()`, +`mockFn.mockRestore()` or by setting `restoreMocks` to `true` in the Jest +config. + +Note: The mock created by `jest.spyOn()` still behaves the same as the original +function. The original function can be overwritten with +`mockFn.mockImplementation()` or by some of the +[other mock functions](https://jestjs.io/docs/en/mock-function-api). + +### Example + +```javascript +// invalid +Date.now = jest.fn(); +Date.now = jest.fn(() => 10); + +// valid +jest.spyOn(Date, "now"); +jest.spyOn(Date, "now").mockImplementation(() => 10); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-strict-equal.md b/src/docs/guide/usage/linter/rules/jest/prefer-strict-equal.md new file mode 100644 index 0000000000..58602328b6 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-strict-equal.md @@ -0,0 +1,23 @@ + + +# jest/prefer-strict-equal + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +This rule triggers a warning if `toEqual()` is used to assert equality. + +### Example + +```javascript +// invalid +expect({ a: "a", b: undefined }).toEqual({ a: "a" }); + +// valid +expect({ a: "a", b: undefined }).toStrictEqual({ a: "a" }); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-to-be.md b/src/docs/guide/usage/linter/rules/jest/prefer-to-be.md new file mode 100644 index 0000000000..b411075cfd --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-to-be.md @@ -0,0 +1,35 @@ + + +# jest/prefer-to-be + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +When asserting against primitive literals such as numbers and strings, the +equality matchers all operate the same, but read slightly differently in code. + +This rule recommends using the `toBe` matcher in these situations, as it forms +the most grammatically natural sentence. For `null`, `undefined`, and `NaN` this +rule recommends using their specific `toBe` matchers, as they give better error +messages as well. + +### Example + +```javascript +// valid +expect(value).not.toBe(5); +expect(getMessage()).toBe("hello world"); +expect(loadMessage()).resolves.toBe("hello world"); +expect(didError).not.toBe(true); +expect(catchError()).toStrictEqual({ message: "oh noes!" }); + +// invalid +expect(value).not.toEqual(5); +expect(getMessage()).toStrictEqual("hello world"); +expect(loadMessage()).resolves.toEqual("hello world"); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-to-contain.md b/src/docs/guide/usage/linter/rules/jest/prefer-to-contain.md new file mode 100644 index 0000000000..7cf0a38d04 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-to-contain.md @@ -0,0 +1,31 @@ + + +# jest/prefer-to-contain + +
+
+ +### What it does + +In order to have a better failure message, `toContain()` should be used upon +asserting expectations on an array containing an object. + +### Why is this bad? + +TThis rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is +used to assert object inclusion in an array + +### Example + +```javascript +// valid +expect(a).toContain(b); +expect(a).not.toContain(b); + +// invalid +expect(a.includes(b)).toBe(true); +expect(a.includes(b)).not.toBe(true); +expect(a.includes(b)).toBe(false); +expect(a.includes(b)).toEqual(true); +expect(a.includes(b)).toStrictEqual(true); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-to-have-length.md b/src/docs/guide/usage/linter/rules/jest/prefer-to-have-length.md new file mode 100644 index 0000000000..988b149eb1 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-to-have-length.md @@ -0,0 +1,34 @@ + + +# jest/prefer-to-have-length + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +In order to have a better failure message, `toHaveLength()` should be used upon +asserting expectations on objects length property. + +### Why is this bad? + +This rule triggers a warning if `toBe()`, `toEqual()` or `toStrictEqual()` is +used to assert objects length property. + +### Example + +```javascript +// valid +expect.hasAssertions; +expect.hasAssertions(); +expect(files).toHaveLength(1); +expect(files.name).toBe("file"); + +// invalid +expect(files["length"]).toBe(1); +expect(files["length"]).toBe(1); +expect(files["length"])["not"].toBe(1); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/prefer-todo.md b/src/docs/guide/usage/linter/rules/jest/prefer-todo.md new file mode 100644 index 0000000000..975b630fea --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/prefer-todo.md @@ -0,0 +1,28 @@ + + +# jest/prefer-todo + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +When test cases are empty then it is better to mark them as `test.todo` as it +will be highlighted in the summary output. + +### Why is this bad? + +This rule triggers a warning if empty test cases are used without 'test.todo'. + +### Example + +```javascript +test("i need to write this test"); // invalid +test("i need to write this test", () => {}); // invalid +test.skip("i need to write this test", () => {}); // invalid + +test.todo("i need to write this test"); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/require-hook.md b/src/docs/guide/usage/linter/rules/jest/require-hook.md new file mode 100644 index 0000000000..fe410a672e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/require-hook.md @@ -0,0 +1,111 @@ + + +# jest/require-hook + +
+
+ +### What it does + +This rule flags any expression that is either at the toplevel of a test file or +directly within the body of a `describe`, _except_ for the following: + +- `import` statements +- `const` variables +- `let` _declarations_, and initializations to `null` or `undefined` +- Classes +- Types +- Calls to the standard Jest globals + +### Example + +```javascript +// invalid +import { database, isCity } from "../database"; +import { Logger } from "../../../src/Logger"; +import { loadCities } from "../api"; + +jest.mock("../api"); + +const initializeCityDatabase = () => { + database.addCity("Vienna"); + database.addCity("San Juan"); + database.addCity("Wellington"); +}; + +const clearCityDatabase = () => { + database.clear(); +}; + +initializeCityDatabase(); + +test("that persists cities", () => { + expect(database.cities.length).toHaveLength(3); +}); +test("city database has Vienna", () => { + expect(isCity("Vienna")).toBeTruthy(); +}); + +test("city database has San Juan", () => { + expect(isCity("San Juan")).toBeTruthy(); +}); + +describe("when loading cities from the api", () => { + let consoleWarnSpy = jest.spyOn(console, "warn"); + loadCities.mockResolvedValue(["Wellington", "London"]); + + it("does not duplicate cities", async () => { + await database.loadCities(); + expect(database.cities).toHaveLength(4); + }); +}); +clearCityDatabase(); + +// valid +import { database, isCity } from "../database"; +import { Logger } from "../../../src/Logger"; +import { loadCities } from "../api"; + +jest.mock("../api"); +const initializeCityDatabase = () => { + database.addCity("Vienna"); + database.addCity("San Juan"); + database.addCity("Wellington"); +}; + +const clearCityDatabase = () => { + database.clear(); +}; + +beforeEach(() => { + initializeCityDatabase(); +}); + +test("that persists cities", () => { + expect(database.cities.length).toHaveLength(3); +}); + +test("city database has Vienna", () => { + expect(isCity("Vienna")).toBeTruthy(); +}); + +test("city database has San Juan", () => { + expect(isCity("San Juan")).toBeTruthy(); +}); + +describe("when loading cities from the api", () => { + let consoleWarnSpy; + beforeEach(() => { + consoleWarnSpy = jest.spyOn(console, "warn"); + loadCities.mockResolvedValue(["Wellington", "London"]); + }); + + it("does not duplicate cities", async () => { + await database.loadCities(); + expect(database.cities).toHaveLength(4); + }); +}); +afterEach(() => { + clearCityDatabase(); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/require-to-throw-message.md b/src/docs/guide/usage/linter/rules/jest/require-to-throw-message.md new file mode 100644 index 0000000000..e9ef0babe6 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/require-to-throw-message.md @@ -0,0 +1,30 @@ + + +# jest/require-to-throw-message + +
+
+ +### What it does + +This rule triggers a warning if `toThrow()` or `toThrowError()` is used without an error message. + +### Example + +```javascript +// invalid +test("all the things", async () => { + expect(() => a()).toThrow(); + expect(() => a()).toThrowError(); + await expect(a()).rejects.toThrow(); + await expect(a()).rejects.toThrowError(); +}); + +// valid +test("all the things", async () => { + expect(() => a()).toThrow("a"); + expect(() => a()).toThrowError("a"); + await expect(a()).rejects.toThrow("a"); + await expect(a()).rejects.toThrowError("a"); +}); +``` diff --git a/src/docs/guide/usage/linter/rules/jest/require-top-level-describe.md b/src/docs/guide/usage/linter/rules/jest/require-top-level-describe.md new file mode 100644 index 0000000000..d1951f6c3b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/require-top-level-describe.md @@ -0,0 +1,65 @@ + + +# jest/require-top-level-describe + +
+
+ +### What it does + +This rule triggers a warning if a test case (`test` and `it`) or a hook +(`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) is not located in a +top-level `describe` block. + +### Example + +```javascript +// invalid + +// Above a describe block +test("my test", () => {}); +describe("test suite", () => { + it("test", () => {}); +}); + +// Below a describe block +describe("test suite", () => {}); +test("my test", () => {}); + +// Same for hooks +beforeAll("my beforeAll", () => {}); +describe("test suite", () => {}); +afterEach("my afterEach", () => {}); + +//valid + +// Above a describe block +// In a describe block +describe("test suite", () => { + test("my test", () => {}); +}); + +// In a nested describe block +describe("test suite", () => { + test("my test", () => {}); + describe("another test suite", () => { + test("my other test", () => {}); + }); +}); +``` + +### Options + +You can also enforce a limit on the number of describes allowed at the top-level +using the `maxNumberOfTopLevelDescribes` option: + +```json +{ + "jest/require-top-level-describe": [ + "error", + { + "maxNumberOfTopLevelDescribes": 2 + } + ] +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/valid-describe-callback.md b/src/docs/guide/usage/linter/rules/jest/valid-describe-callback.md new file mode 100644 index 0000000000..a059c7d760 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/valid-describe-callback.md @@ -0,0 +1,52 @@ + + +# jest/valid-describe-callback + +
+
+ +### What it does + +This rule validates that the second parameter of a `describe()` function is a +callback function. This callback function: + +- should not be + [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) +- should not contain any parameters +- should not contain any `return` statements + +### Why is this bad? + +Using an improper `describe()` callback function can lead to unexpected test +errors. + +### Example + +```javascript +// Async callback functions are not allowed +describe("myFunction()", async () => { + // ... +}); + +// Callback function parameters are not allowed +describe("myFunction()", (done) => { + // ... +}); + +// Returning a value from a describe block is not allowed +describe("myFunction", () => + it("returns a truthy value", () => { + expect(myFunction()).toBeTruthy(); + })); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/valid-describe-callback.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/valid-describe-callback": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/valid-expect.md b/src/docs/guide/usage/linter/rules/jest/valid-expect.md new file mode 100644 index 0000000000..c843dabb07 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/valid-expect.md @@ -0,0 +1,32 @@ + + +# jest/valid-expect + +
+
+ +### What it does + +This rule triggers a warning if `expect()` is called with more than one argument +or without arguments. It would also issue a warning if there is nothing called +on `expect()`, e.g.: + +### Example + +```javascript +expect(); +expect("something"); +expect(true).toBeDefined; +expect(Promise.resolve("Hi!")).resolves.toBe("Hi!"); +``` + +This rule is compatible with [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest/blob/main/docs/rules/valid-expect.md), +to use it, add the following configuration to your `.eslintrc.json`: + +```json +{ + "rules": { + "vitest/valid-expect": "error" + } +} +``` diff --git a/src/docs/guide/usage/linter/rules/jest/valid-title.md b/src/docs/guide/usage/linter/rules/jest/valid-title.md new file mode 100644 index 0000000000..bf1be9e787 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jest/valid-title.md @@ -0,0 +1,29 @@ + + +# jest/valid-title + +
+
+ +### What it does + +Checks that the title of Jest blocks are valid by ensuring that titles are: + +- not empty, +- is a string, +- not prefixed with their block name, +- have no leading or trailing spaces + +### Example + +```javascript +describe("", () => {}); +describe("foo", () => { + it("", () => {}); +}); +it("", () => {}); +test("", () => {}); +xdescribe("", () => {}); +xit("", () => {}); +xtest("", () => {}); +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/check-access.md b/src/docs/guide/usage/linter/rules/jsdoc/check-access.md new file mode 100644 index 0000000000..369daad594 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/check-access.md @@ -0,0 +1,35 @@ + + +# jsdoc/check-access + +
+
+ +### What it does + +Checks that `@access` tags use one of the following values: + +- "package", "private", "protected", "public" + +Also reports: + +- Mixing of `@access` with `@public`, `@private`, `@protected`, or `@package` on the same doc block. +- Use of multiple instances of `@access` (or the `@public`, etc) on the same doc block. + +### Why is this bad? + +It is important to have a consistent way of specifying access levels. + +### Example + +```javascript +// Passing +/** @access private */ + +/** @private */ + +// Failing +/** @access private @public */ + +/** @access invalidlevel */ +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/check-property-names.md b/src/docs/guide/usage/linter/rules/jsdoc/check-property-names.md new file mode 100644 index 0000000000..4684b99d72 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/check-property-names.md @@ -0,0 +1,41 @@ + + +# jsdoc/check-property-names + +
+
+ +### What it does + +Ensures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots. + +### Why is this bad? + +`@property` tags with the same name can be confusing and may indicate a mistake. + +### Example + +```javascript +// Passing +/** + * @typedef {object} state + * @property {number} foo + */ +/** + * @typedef {object} state + * @property {object} foo + * @property {number} foo.bar + */ + +// Failing +/** + * @typedef {object} state + * @property {number} foo + * @property {string} foo + */ + +/** + * @typedef {object} state + * @property {number} foo.bar + */ +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/check-tag-names.md b/src/docs/guide/usage/linter/rules/jsdoc/check-tag-names.md new file mode 100644 index 0000000000..7e8a55778e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/check-tag-names.md @@ -0,0 +1,31 @@ + + +# jsdoc/check-tag-names + +
+
+ +### What it does + +Reports invalid block tag names. +Additionally checks for tag names that are redundant when using a type checker such as TypeScript. + +### Why is this bad? + +Using invalid tags can lead to confusion and make the documentation harder to read. + +### Example + +```javascript +// Passing +/** @param */ + +// Failing +/** @Param */ +/** @foo */ + +/** + * This is redundant when typed. + * @type {string} + */ +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/empty-tags.md b/src/docs/guide/usage/linter/rules/jsdoc/empty-tags.md new file mode 100644 index 0000000000..13efc929f5 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/empty-tags.md @@ -0,0 +1,47 @@ + + +# jsdoc/empty-tags + +
+
+ +### What it does + +Expects the following tags to be empty of any content: + +- `@abstract` +- `@async` +- `@generator` +- `@global` +- `@hideconstructor` +- `@ignore` +- `@inner` +- `@instance` +- `@override` +- `@readonly` +- `@inheritDoc` +- `@internal` +- `@overload` +- `@package` +- `@private` +- `@protected` +- `@public` +- `@static` + +### Why is this bad? + +The void tags should be empty. + +### Example + +```javascript +// Passing +/** @async */ + +/** @private */ + +// Failing +/** @async foo */ + +/** @private bar */ +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/implements-on-classes.md b/src/docs/guide/usage/linter/rules/jsdoc/implements-on-classes.md new file mode 100644 index 0000000000..89fafc9326 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/implements-on-classes.md @@ -0,0 +1,38 @@ + + +# jsdoc/implements-on-classes + +
+
+ +### What it does + +Reports an issue with any non-constructor function using `@implements`. + +### Why is this bad? + +Constructor functions should be +whether marked with `@class`, `@constructs`, or being an ES6 class constructor. + +### Example + +```javascript +// Passing +class Foo { + /** + * @implements {SomeClass} + */ + constructor() {} +} +/** + * @implements {SomeClass} + * @class + */ +function quux() {} + +// Failing +/** + * @implements {SomeClass} + */ +function quux() {} +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/no-defaults.md b/src/docs/guide/usage/linter/rules/jsdoc/no-defaults.md new file mode 100644 index 0000000000..b79e7a4f45 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/no-defaults.md @@ -0,0 +1,30 @@ + + +# jsdoc/no-defaults + +
+
+ +### What it does + +This rule reports defaults being used on the relevant portion of `@param` or `@default`. +It also optionally reports the presence of the square-bracketed optional arguments at all. + +### Why is this bad? + +The rule is intended to prevent the indication of defaults on tags +where this would be redundant with ES6 default parameters. + +### Example + +```javascript +// Passing +/** @param {number} foo */ +function quux(foo) {} +/** @param foo */ +function quux(foo) {} + +// Failing +/** @param {number} [foo="7"] */ +function quux(foo) {} +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-param-description.md b/src/docs/guide/usage/linter/rules/jsdoc/require-param-description.md new file mode 100644 index 0000000000..f529e87b5a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-param-description.md @@ -0,0 +1,26 @@ + + +# jsdoc/require-param-description + +
+
+ +### What it does + +Requires that each `@param` tag has a description value. + +### Why is this bad? + +The description of a param should be documented. + +### Example + +```javascript +// Passing +/** @param foo Foo. */ +function quux(foo) {} + +// Failing +/** @param foo */ +function quux(foo) {} +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-param-name.md b/src/docs/guide/usage/linter/rules/jsdoc/require-param-name.md new file mode 100644 index 0000000000..4788df9174 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-param-name.md @@ -0,0 +1,26 @@ + + +# jsdoc/require-param-name + +
+
+ +### What it does + +Requires that all `@param` tags have names. + +### Why is this bad? + +The name of a param should be documented. + +### Example + +```javascript +// Passing +/** @param {SomeType} foo */ +function quux(foo) {} + +// Failing +/** @param {SomeType} */ +function quux(foo) {} +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-param-type.md b/src/docs/guide/usage/linter/rules/jsdoc/require-param-type.md new file mode 100644 index 0000000000..4bb40f9417 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-param-type.md @@ -0,0 +1,26 @@ + + +# jsdoc/require-param-type + +
+
+ +### What it does + +Requires that each `@param` tag has a type value (within curly brackets). + +### Why is this bad? + +The type of a parameter should be documented. + +### Example + +```javascript +// Passing +/** @param {SomeType} foo */ +function quux(foo) {} + +// Failing +/** @param foo */ +function quux(foo) {} +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-param.md b/src/docs/guide/usage/linter/rules/jsdoc/require-param.md new file mode 100644 index 0000000000..b39e08aac6 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-param.md @@ -0,0 +1,26 @@ + + +# jsdoc/require-param + +
+
+ +### What it does + +Requires that all function parameters are documented with JSDoc `@param` tags. + +### Why is this bad? + +The rule is aimed at enforcing code quality and maintainability by requiring that all function parameters are documented. + +### Example + +```javascript +// Passing +/** @param foo */ +function quux(foo) {} + +// Failing +/** @param foo */ +function quux(foo, bar) {} +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-property-description.md b/src/docs/guide/usage/linter/rules/jsdoc/require-property-description.md new file mode 100644 index 0000000000..0d8b47ed9b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-property-description.md @@ -0,0 +1,30 @@ + + +# jsdoc/require-property-description + +
+
+ +### What it does + +Requires that all `@property` tags have descriptions. + +### Why is this bad? + +The description of a property should be documented. + +### Example + +```javascript +// Passing +/** + * @typedef {SomeType} SomeTypedef + * @property {number} foo Foo. + */ + +// Failing +/** + * @typedef {SomeType} SomeTypedef + * @property {number} foo + */ +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-property-name.md b/src/docs/guide/usage/linter/rules/jsdoc/require-property-name.md new file mode 100644 index 0000000000..8bcb73cb71 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-property-name.md @@ -0,0 +1,30 @@ + + +# jsdoc/require-property-name + +
+
+ +### What it does + +Requires that all `@property` tags have names. + +### Why is this bad? + +The name of a property type should be documented. + +### Example + +```javascript +// Passing +/** + * @typedef {SomeType} SomeTypedef + * @property {number} foo + */ + +// Failing +/** + * @typedef {SomeType} SomeTypedef + * @property {number} + */ +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-property-type.md b/src/docs/guide/usage/linter/rules/jsdoc/require-property-type.md new file mode 100644 index 0000000000..3b48fe3d3e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-property-type.md @@ -0,0 +1,30 @@ + + +# jsdoc/require-property-type + +
+
+ +### What it does + +Requires that each `@property` tag has a type value (within curly brackets). + +### Why is this bad? + +The type of a property should be documented. + +### Example + +```javascript +// Passing +/** + * @typedef {SomeType} SomeTypedef + * @property {number} foo + */ + +// Failing +/** + * @typedef {SomeType} SomeTypedef + * @property foo + */ +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-property.md b/src/docs/guide/usage/linter/rules/jsdoc/require-property.md new file mode 100644 index 0000000000..c46d19c8b8 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-property.md @@ -0,0 +1,37 @@ + + +# jsdoc/require-property + +
+
+ +### What it does + +Requires that all `@typedef` and `@namespace` tags have `@property` tags +when their type is a plain `object`, `Object`, or `PlainObject`. + +### Why is this bad? + +Object type should have properties defined. + +### Example + +```javascript +// Passing +/** + * @typedef {Object} SomeTypedef + * @property {SomeType} propName Prop description + */ +/** + * @typedef {object} Foo + * @property someProp + */ + +// Failing +/** + * @typedef {Object} SomeTypedef + */ +/** + * @namespace {Object} SomeNamesoace + */ +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-returns-description.md b/src/docs/guide/usage/linter/rules/jsdoc/require-returns-description.md new file mode 100644 index 0000000000..2a07f26464 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-returns-description.md @@ -0,0 +1,27 @@ + + +# jsdoc/require-returns-description + +
+
+ +### What it does + +Requires that the `@returns` tag has a description value. +The error will not be reported if the return value is `void `or `undefined` or if it is `Promise` or `Promise`. + +### Why is this bad? + +A `@returns` tag should have a description value. + +### Example + +```javascript +// Passing +/** @returns Foo. */ +function quux(foo) {} + +// Failing +/** @returns */ +function quux(foo) {} +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-returns-type.md b/src/docs/guide/usage/linter/rules/jsdoc/require-returns-type.md new file mode 100644 index 0000000000..a313ab9b56 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-returns-type.md @@ -0,0 +1,26 @@ + + +# jsdoc/require-returns-type + +
+
+ +### What it does + +Requires that `@returns` tag has a type value (in curly brackets). + +### Why is this bad? + +A `@returns` tag should have a type value. + +### Example + +```javascript +// Passing +/** @returns {string} */ +function quux(foo) {} + +// Failing +/** @returns */ +function quux(foo) {} +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-returns.md b/src/docs/guide/usage/linter/rules/jsdoc/require-returns.md new file mode 100644 index 0000000000..7e17e7fd4d --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-returns.md @@ -0,0 +1,38 @@ + + +# jsdoc/require-returns + +
+
+ +### What it does + +Requires that return statements are documented. +Will also report if multiple `@returns` tags are present. + +### Why is this bad? + +The rule is intended to prevent the omission of `@returns` tag when necessary. + +### Example + +```javascript +// Passing +/** @returns Foo. */ +function quux() { + return foo; +} + +// Failing +/** Foo. */ +function quux() { + return foo; +} +/** + * @returns Foo! + * @returns Foo? + */ +function quux() { + return foo; +} +``` diff --git a/src/docs/guide/usage/linter/rules/jsdoc/require-yields.md b/src/docs/guide/usage/linter/rules/jsdoc/require-yields.md new file mode 100644 index 0000000000..f76700e009 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsdoc/require-yields.md @@ -0,0 +1,35 @@ + + +# jsdoc/require-yields + +
+
+ +### What it does + +Requires that yields are documented. +Will also report if multiple `@yields` tags are present. + +### Why is this bad? + +The rule is intended to prevent the omission of `@yields` tags when they are necessary. + +### Example + +```javascript +// Passing +/** * @yields Foo */ +function* quux(foo) { + yield foo; +} + +// Failing +function* quux(foo) { + yield foo; +} +/** + * @yields {undefined} + * @yields {void} + */ +function* quux(foo) {} +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/alt-text.md b/src/docs/guide/usage/linter/rules/jsx_a11y/alt-text.md new file mode 100644 index 0000000000..73f0155d4f --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/alt-text.md @@ -0,0 +1,41 @@ + + +# jsx_a11y/alt-text + +
+
+ +### What it does + +Enforce that all elements that require alternative text have meaningful +information to relay back to the end user. + +### Why is this necessary? + +Alternative text is a critical component of accessibility for screen +reader users, enabling them to understand the content and function +of an element. + +### What it checks + +This rule checks for alternative text on the following elements: +``, ``, ``, and ``. + +### How to fix it + +Ensure that the `alt` attribute is present and contains meaningful +text that describes the element's content or purpose. + +### Example + +Examples of **incorrect** code for this rule: + +```jsx +A close-up of a white daisy +``` + +Examples of **correct** code for this rule: + +```jsx + +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/anchor-has-content.md b/src/docs/guide/usage/linter/rules/jsx_a11y/anchor-has-content.md new file mode 100644 index 0000000000..49edc81da0 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/anchor-has-content.md @@ -0,0 +1,34 @@ + + +# jsx_a11y/anchor-has-content + +
+
+ +### What it does + +Enforce that anchors have content and that the content is accessible to screen readers. +Accessible means that it is not hidden using the `aria-hidden` prop. + +Alternatively, you may use the `title` prop or the `aria-label` prop. + +### Why is this bad? + +### Example + +#### good + +``` +Anchor Content! + + + + +``` + +#### bad + +``` + + +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/anchor-is-valid.md b/src/docs/guide/usage/linter/rules/jsx_a11y/anchor-is-valid.md new file mode 100644 index 0000000000..724aa35dc2 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/anchor-is-valid.md @@ -0,0 +1,80 @@ + + +# jsx_a11y/anchor-is-valid + +
+
+ +### What it does + +The HTML `` element, with a valid href attribute, is formally defined as representing a **hyperlink**. +That is, a link between one HTML document and another, or between one location inside an HTML document and another location inside the same document. + +While before it was possible to attach logic to an anchor element, with the advent of JSX libraries, +it's now easier to attach logic to any HTML element, anchors included. + +This rule is designed to prevent users to attach logic at the click of anchors, and also makes +sure that the `href` provided to the anchor element is valid. If the anchor has logic attached to it, +the rules suggests to turn it to a `button`, because that's likely what the user wants. + +Anchor `` elements should be used for navigation, while `` should be +used for user interaction. + +Consider the following: + +```jsx +<> + + Perform action + + + Perform action + + Perform action + +``` + +All these anchor implementations indicate that the element is only used to execute JavaScript code. All the above should be replaced with: + +```jsx + +``` + +` + +### Why is this bad? + +There are **many reasons** why an anchor should not have a logic and have a correct `href` attribute: + +- it can disrupt the correct flow of the user navigation e.g. a user that wants to open the link in another tab, but the default "click" behaviour is prevented +- it can source of invalid links, and crawlers can't navigate the website, risking to penalise SEO ranking + +### Example + +#### Valid + +```jsx +<> + navigate here + navigate here + navigate here + +``` + +#### Invalid + +```jsx +<> + navigate here + navigate here + navigate here + navigate here + + navigate here + + +``` + +### Reference + +- [WCAG 2.1.1](https://www.w3.org/WAI/WCAG21/Understanding/keyboard) diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/aria-activedescendant-has-tabindex.md b/src/docs/guide/usage/linter/rules/jsx_a11y/aria-activedescendant-has-tabindex.md new file mode 100644 index 0000000000..03f36436a8 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/aria-activedescendant-has-tabindex.md @@ -0,0 +1,36 @@ + + +# jsx_a11y/aria-activedescendant-has-tabindex + +
+
+ +### What it does + +Enforce elements with aria-activedescendant are tabbable. + +### Example + +```jsx +const Good = ( + <> + + + + +
+ +
+
+
+
+
+
+ + + + +); + +const Bad =
; +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/aria-props.md b/src/docs/guide/usage/linter/rules/jsx_a11y/aria-props.md new file mode 100644 index 0000000000..6ef4cf5e2e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/aria-props.md @@ -0,0 +1,35 @@ + + +# jsx_a11y/aria-props + +
+ +🛠️ An auto-fix is available for this rule for some violations. + +
+ +### What it does + +Enforces that elements do not use invalid ARIA attributes. + +### Why is this bad? + +Using invalid ARIA attributes can mislead screen readers and other assistive technologies. +It may cause the accessibility features of the website to fail, making it difficult +for users with disabilities to use the site effectively. + +This rule includes fixes for some common typos. + +### Example + +Examples of **incorrect** code for this rule: + +```jsx + +``` + +Examples of **correct** code for this rule: + +```jsx + +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/aria-role.md b/src/docs/guide/usage/linter/rules/jsx_a11y/aria-role.md new file mode 100644 index 0000000000..d695a69201 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/aria-role.md @@ -0,0 +1,82 @@ + + +# jsx_a11y/aria-role + +
+
+ +### What it does + +Elements with ARIA roles must use a valid, non-abstract ARIA role. A +reference to role definitions can be found at +[WAI-ARIA](https://www.w3.org/TR/wai-aria/#role_definitions) site. + +### Why is this bad? + +The intent of this Success Criterion is to ensure that Assistive +Technologies (AT) can gather information about, activate (or set) and +keep up to date on the status of user interface controls in the +content(such as screen readers, screen magnifiers, and speech +recognition software, used by people with disabilities). + +When standard controls from accessible technologies are used, this +process is straightforward. If the user interface elements are used +according to specification the conditions of this provision will be met. + +If custom controls are created, however, or interface elements are +programmed (in code or script) to have a different role and/or function +than usual, then additional measures need to be taken to ensure that the +controls provide important information to assistive technologies and +allow themselves to be controlled by assistive technologies. A +particularly important state of a user interface control is whether or +not it has focus. The focus state of a control can be programmatically +determined, and notifications about change of focus are sent to user +agents and assistive technology. Other examples of user interface +control state are whether or not a checkbox or radio button has been +selected, or whether or not a collapsible tree or list node is expanded +or collapsed. + +### Rule options + +This rule takes one optional object argument of type object: + +```json +{ + "rules": { + "jsx-a11y/aria-role": [ + 2, + { + "allowedInvalidRoles": ["text"], + "ignoreNonDOM": true + } + ] + } +} +``` + +`allowedInvalidRules` is an optional string array of custom roles that +should be allowed in addition to the ARIA spec, such as for cases when +you need to use a non-standard role. + +For the `ignoreNonDOM` option, this determines if developer created +components are checked. + +### Example + +Examples of **incorrect** code for this rule: + +```jsx +
+
+
+ +``` + +Examples of **correct** code for this rule: + +```jsx +
+
+
+ +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/aria-unsupported-elements.md b/src/docs/guide/usage/linter/rules/jsx_a11y/aria-unsupported-elements.md new file mode 100644 index 0000000000..3b843649d7 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/aria-unsupported-elements.md @@ -0,0 +1,20 @@ + + +# jsx_a11y/aria-unsupported-elements + +
+
+ +### What it does + +Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `role` and/or `aria-*` props. + +### Example + +```jsx +// Good + + +// Bad + +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/autocomplete-valid.md b/src/docs/guide/usage/linter/rules/jsx_a11y/autocomplete-valid.md new file mode 100644 index 0000000000..76f94eeba0 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/autocomplete-valid.md @@ -0,0 +1,24 @@ + + +# jsx_a11y/autocomplete-valid + +
+
+ +### What it does + +Enforces that an element's autocomplete attribute must be a valid value. + +### Why is this bad? + +Incorrectly using the autocomplete attribute may decrease the accessibility of the website for users. + +### Example + +```jsx +// Bad + + +// Good + +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/click-events-have-key-events.md b/src/docs/guide/usage/linter/rules/jsx_a11y/click-events-have-key-events.md new file mode 100644 index 0000000000..1dd242083c --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/click-events-have-key-events.md @@ -0,0 +1,25 @@ + + +# jsx_a11y/click-events-have-key-events + +
+
+ +### What it does + +Enforce onClick is accompanied by at least one of the following: onKeyUp, onKeyDown, onKeyPress. + +### Why is this bad? + +Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users. +This does not apply for interactive or hidden elements. + +### Example + +```jsx +// Good +
void 0} onKeyDown={() => void 0} /> + +// Bad +
void 0} /> +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/heading-has-content.md b/src/docs/guide/usage/linter/rules/jsx_a11y/heading-has-content.md new file mode 100644 index 0000000000..8b1f401ada --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/heading-has-content.md @@ -0,0 +1,29 @@ + + +# jsx_a11y/heading-has-content + +
+
+ +### What it does + +Enforce that heading elements (h1, h2, etc.) have content and +that the content is accessible to screen readers. +Accessible means that it is not hidden using the aria-hidden prop. + +### Why is this bad? + +Screen readers alert users to the presence of a heading tag. +If the heading is empty or the text cannot be accessed, +this could either confuse users or even prevent them +from accessing information on the page's structure. + +### Example + +```jsx +// Bad +

+ +// Good +

Foo

+``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/html-has-lang.md b/src/docs/guide/usage/linter/rules/jsx_a11y/html-has-lang.md new file mode 100644 index 0000000000..3d3cd4f597 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/html-has-lang.md @@ -0,0 +1,27 @@ + + +# jsx_a11y/HTML-has-lang + +
+
+ +### What it does + +Ensures that every HTML document has a lang attribute + +### Why is this bad? + +If the language of a web page is not specified, +the screen reader assumes the default language set by the user. +Language settings become an issue for users who speak multiple languages +and access website in more than one language. + +### Example + +```jsx +// Bad + + +// Good + +``` diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/iframe-has-title.md b/src/docs/guide/usage/linter/rules/jsx_a11y/iframe-has-title.md new file mode 100644 index 0000000000..c0b8a809b2 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/iframe-has-title.md @@ -0,0 +1,38 @@ + + +# jsx_a11y/iframe-has-title + +
+
+ +### What it does + +Enforce iframe elements have a title attribute. + +### Why is this necessary? + +Screen reader users rely on a iframe title to describe the contents of the iframe. +Navigating through iframe and iframe elements quickly becomes difficult and confusing for users of this technology if the markup does not contain a title attribute. + +### What it checks + +This rule checks for title property on iframe element. + +### Example + +```jsx +// Bad +