@thibaudcolas/eslint-plugin-cookbook 
Shareable ESLint config, based on airbnb/javascript, bundled as a plugin.
Why
We want shareable configs to have as low of an overhead as possible. Users shouldn't have to know exactly what plugins are required by the config, install them and manage their versions manually. This plugin contains a shareable config, with plugin dependencies automatically installed.
See https://github.com/eslint/eslint/issues/3458 for further discussion on this topic.
Usage
Install ESLint and the config:
npm install --save-dev eslint @thibaudcolas/eslint-plugin-cookbookThen configure ESLint to use this config. As a .eslintrc.js in the root of your project:
module.exports = {
// https://github.com/thibaudcolas/eslint-plugin-cookbook
extends: "plugin:@thibaudcolas/cookbook/recommended",
};With Prettier
This recommended config is Prettier-compatible. First, install Prettier:
npm install --save-dev prettierThen, to configure Prettier itself, create a prettier.config.js file in the root of your project. You can use the following to get started:
// https://github.com/thibaudcolas/eslint-plugin-cookbook
module.exports = require("@thibaudcolas/eslint-plugin-cookbook/prettier.config");Switching to this config
Read on: Upgrading to a stricter ESLint config.
Overriding the rules
Should further customisation be required, rules coming from external plugins require the @thibaudcolas/cookbook prefix:
module.exports = {
// https://github.com/thibaudcolas/eslint-plugin-cookbook
extends: "plugin:@thibaudcolas/cookbook/recommended",
rules: {
- "react/react-in-jsx-scope": ["warn"],
+ "@thibaudcolas/cookbook/react/react-in-jsx-scope": ["warn"],
- "import/prefer-default-export": ["warn"],
+ "@thibaudcolas/cookbook/import/prefer-default-export": ["warn"],
},
};Tips
- Use ESLint’s
--report-unused-disable-directivesflag to ensure you do not use moreeslint-disablecomments than needed.
Related tools
To get the most out of this config, it is assumed that projects have the following tools set up:
- Prettier for automated formatting of stylesheets.
- Browserslist for the definition of target browsers (along with autoprefixer and @babel/preset-env).
Rules
Extends
Cookbook config
- no-warning-comments:
1, terms: todo, fixme, xxx, location: start - import/no-extraneous-dependencies:
2, devDependencies: test/**, tests/**, spec/**, **/__tests__… - react/jsx-filename-extension:
2, extensions: .js - no-param-reassign:
2, props: false - react/forbid-prop-types:
2, forbid: any
Rules of airbnb
error, components:
- jsx-a11y/aria-role: error, ignoreNonDom: false, ignoreNonDOM: false
- jsx-a11y/aria-props
- jsx-a11y/aria-proptypes
- jsx-a11y/aria-unsupported-elements
- jsx-a11y/alt-text: error, elements: img, object, area, inputtype=\image\, img: …
- jsx-a11y/img-redundant-alt
- jsx-a11y/label-has-associated-control: error, labelComponents: , labelAttributes: , controlComponen…
- jsx-a11y/control-has-associated-label: error, labelAttributes: label, controlComponents: , ignoreEl…
- jsx-a11y/mouse-events-have-key-events
- jsx-a11y/no-access-key
- jsx-a11y/interactive-supports-focus
- jsx-a11y/role-has-required-aria-props
- jsx-a11y/role-supports-aria-props
- jsx-a11y/tabindex-no-positive
- jsx-a11y/heading-has-content: error, components:
- jsx-a11y/html-has-lang
- jsx-a11y/lang
- jsx-a11y/no-distracting-elements: error, elements: marquee, blink
- jsx-a11y/scope
- jsx-a11y/click-events-have-key-events
- jsx-a11y/no-static-element-interactions: error, handlers: onClick, onMouseDown, onMouseUp, onKeyPress…
- jsx-a11y/no-noninteractive-element-interactions: error, handlers: onClick, onMouseDown, onMouseUp, onKeyPress…
- jsx-a11y/accessible-emoji
- jsx-a11y/aria-activedescendant-has-tabindex
- jsx-a11y/iframe-has-title
- jsx-a11y/no-autofocus: error, ignoreNonDOM: true
- jsx-a11y/no-redundant-roles
- jsx-a11y/media-has-caption: error, audio: , video: , track:
- jsx-a11y/no-interactive-element-to-noninteractive-role: error, tr: none, presentation
- jsx-a11y/no-noninteractive-element-to-interactive-role: error, ul: listbox, menu, menubar, radiogroup, tablist, tree…
- jsx-a11y/no-noninteractive-tabindex: error, tags: , roles: tabpanel
- jsx-a11y/anchor-is-valid: error, components: Link, specialLink: to, aspects: noHref, i…
- no-underscore-dangle: error, allow: __REDUX_DEVTOOLS_EXTENSION_COMPOSE__, allowAft…
- class-methods-use-this: error, exceptMethods: render, getInitialState, getDefaultPro…
- react/jsx-boolean-value: error, never, always:
- react/jsx-no-duplicate-props: error, ignoreCase: true
- react/jsx-no-undef
- react/jsx-pascal-case: error, allowAllCaps: true, ignore:
- react/jsx-uses-react
- react/jsx-uses-vars
- react/no-danger: warn
- react/no-deprecated
- react/no-did-update-set-state
- react/no-will-update-set-state
- react/no-is-mounted
- react/no-string-refs
- react/no-unknown-property
- react/prefer-es6-class: error, always
- react/prefer-stateless-function: error, ignorePureComponents: true
- react/prop-types: error, ignore: , customValidators: , skipUndeclared: false
- react/react-in-jsx-scope
- react/require-render-return
- react/self-closing-comp
- react/sort-comp: error, order: static-variables, static-methods, instance-var…
- react/jsx-no-target-blank: error, enforceDynamicLinks: always
- react/jsx-no-comment-textnodes
- react/no-render-return-value
- react/no-find-dom-node
- react/no-danger-with-children
- react/no-unused-prop-types: error, customValidators: , skipShapeProps: true
- react/style-prop-object
- react/no-unescaped-entities
- react/no-children-prop
- react/no-array-index-key
- react/require-default-props: error, forbidDefaultForRequired: true
- react/forbid-foreign-prop-types: warn, allowInPropTypes: true
- react/void-dom-elements-no-children
- react/default-props-match-prop-types: error, allowRequiredDefaults: false
- react/no-redundant-should-component-update
- react/no-unused-state
- react/no-typos
- react/jsx-curly-brace-presence: error, props: never, children: never
- react/destructuring-assignment: error, always
- react/no-access-state-in-setstate
- react/button-has-type: error, button: true, submit: true, reset: false
- react/no-this-in-sfc
- react/jsx-fragments: error, syntax
- react/state-in-constructor: error, always
- react/static-property-placement: error, property assignment
- react/jsx-props-no-spreading: error, html: enforce, custom: enforce, exceptions:
- strict: error, never
- import/no-unresolved: error, commonjs: true, caseSensitive: true
- import/named
- import/export
- import/no-named-as-default
- import/no-named-as-default-member
- import/no-mutable-exports
- import/no-amd
- import/first
- import/no-duplicates
- import/extensions: error, ignorePackages, js: never, mjs: never, jsx: never
- import/order: error, groups: builtin, external, internal
- import/newline-after-import
- import/prefer-default-export
- import/no-absolute-path
- import/no-dynamic-require
- import/no-webpack-loader-syntax
- import/no-named-default
- import/no-self-import
- import/no-cycle
- import/no-useless-path-segments: error, commonjs: true
- constructor-super
- no-class-assign
- no-const-assign
- no-dupe-class-members
- no-new-symbol
- no-this-before-super
- no-useless-computed-key
- no-useless-constructor
- no-useless-rename: error, ignoreDestructuring: false, ignoreImport: false, igno…
- no-var
- object-shorthand: error, always, ignoreConstructors: false, avoidQuotes: true
- prefer-const: error, destructuring: any, ignoreReadBeforeAssign: true
- prefer-destructuring: error, VariableDeclarator: array: false, object: true, Assig…
- prefer-numeric-literals
- prefer-rest-params
- prefer-spread
- prefer-template
- require-yield
- symbol-description
- no-delete-var
- no-label-var
- no-restricted-globals: error, isFinite, isNaN, addEventListener, blur, close, close…
- no-shadow
- no-shadow-restricted-names
- no-undef
- no-undef-init
- no-unused-vars: error, vars: all, args: after-used, ignoreRestSiblings: true
- no-use-before-define: error, functions: true, classes: true, variables: true
- camelcase: error, properties: never, ignoreDestructuring: false, ignore…
- func-names: warn
- lines-between-class-members: error, always, exceptAfterSingleLine: false
- lines-around-directive: error, before: always, after: always
- new-cap: error, newIsCap: true, newIsCapExceptions: , capIsNew: false…
- no-array-constructor
- no-bitwise
- no-continue
- no-lonely-if
- no-multi-assign
- no-nested-ternary
- no-new-object
- no-plusplus
- no-restricted-syntax: error, selector: ForInStatement, message: for..in loops iter…
- no-unneeded-ternary: error, defaultAssignment: false
- one-var: error, never
- operator-assignment: error, always
- prefer-object-spread
- spaced-comment: error, always, line: exceptions: -, +, markers: =, !, block:…
- global-require
- no-buffer-constructor
- no-new-require
- no-path-concat
- for-direction
- getter-return: error, allowImplicit: true
- no-async-promise-executor
- no-await-in-loop
- no-compare-neg-zero
- no-cond-assign: error, always
- no-console: warn
- no-constant-condition: warn
- no-control-regex
- no-debugger
- no-dupe-args
- no-dupe-keys
- no-duplicate-case
- no-empty
- no-empty-character-class
- no-ex-assign
- no-extra-boolean-cast
- no-func-assign
- no-inner-declarations
- no-invalid-regexp
- no-irregular-whitespace
- no-misleading-character-class
- no-obj-calls
- no-prototype-builtins
- no-regex-spaces
- no-sparse-arrays
- no-template-curly-in-string
- no-unreachable
- no-unsafe-finally
- no-unsafe-negation
- use-isnan
- valid-typeof: error, requireStringLiterals: true
- array-callback-return: error, allowImplicit: true, checkForEach: false
- block-scoped-var
- consistent-return
- default-case: error, commentPattern: ^no default$
- dot-notation: error, allowKeywords: true, allowPattern:
- eqeqeq: error, always, null: ignore
- guard-for-in
- max-classes-per-file: error, 1
- no-alert: warn
- no-caller
- no-case-declarations
- no-else-return: error, allowElseIf: false
- no-empty-function: error, allow: arrowFunctions, functions, methods
- no-empty-pattern
- no-eval
- no-extend-native
- no-extra-bind
- no-extra-label
- no-fallthrough
- no-global-assign: error, exceptions:
- no-implied-eval
- no-iterator
- no-labels: error, allowLoop: false, allowSwitch: false
- no-lone-blocks
- no-loop-func
- no-multi-str
- no-new
- no-new-func
- no-new-wrappers
- no-octal
- no-octal-escape
- no-proto
- no-redeclare
- no-restricted-properties: error, object: arguments, property: callee, message: argumen…
- no-return-assign: error, always
- no-return-await
- no-script-url
- no-self-assign: error, props: true
- no-self-compare
- no-sequences
- no-throw-literal
- no-unused-expressions: error, allowShortCircuit: false, allowTernary: false, allowT…
- no-unused-labels
- no-useless-catch
- no-useless-concat
- no-useless-escape
- no-useless-return
- no-void
- no-with
- prefer-promise-reject-errors: error, allowEmptyReject: true
- radix
- vars-on-top
- yoda