mirror of
https://github.com/airbnb/javascript.git
synced 2026-01-14 13:58:13 -05:00
Compare commits
20 Commits
eslint-con
...
actions
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34b5bc39f1 | ||
|
|
d4e39c9b10 | ||
|
|
baaa5e8d26 | ||
|
|
274c8d5701 | ||
|
|
38bc026fe4 | ||
|
|
445322db64 | ||
|
|
152bd5e85a | ||
|
|
afc2cc3432 | ||
|
|
371537f393 | ||
|
|
c05ffb2417 | ||
|
|
97a3238020 | ||
|
|
e0bb393519 | ||
|
|
c4000b932a | ||
|
|
31c6f21878 | ||
|
|
91cab81f69 | ||
|
|
d8cb404da7 | ||
|
|
52e710c14e | ||
|
|
1bc8cabd44 | ||
|
|
37ebbba44c | ||
|
|
930a6f2e4c |
16
.github/workflows/node.yml
vendored
16
.github/workflows/node.yml
vendored
@@ -62,16 +62,12 @@ jobs:
|
||||
matrix:
|
||||
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
|
||||
eslint:
|
||||
- 8
|
||||
- 7
|
||||
# - 6
|
||||
# - 5
|
||||
package:
|
||||
- eslint-config-airbnb
|
||||
react-hooks:
|
||||
- ''
|
||||
# - 3 # TODO: re-enable these once the react config uses eslint 8
|
||||
# - 2.3
|
||||
# - 1.7
|
||||
- 4
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -131,16 +127,12 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
eslint:
|
||||
- 8
|
||||
- 7
|
||||
# - 6
|
||||
# - 5
|
||||
package:
|
||||
- eslint-config-airbnb
|
||||
react-hooks:
|
||||
- ''
|
||||
# - 3 # TODO: re-enable these once the react config uses eslint 8
|
||||
# - 2.3
|
||||
# - 1.7
|
||||
- 4
|
||||
|
||||
defaults:
|
||||
run:
|
||||
|
||||
@@ -310,7 +310,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="objects--rest-spread"></a>
|
||||
- [3.8](#objects--rest-spread) Prefer the object spread syntax over [`Object.assign`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) to shallow-copy objects. Use the object rest operator to get a new object with certain properties omitted. eslint: [`prefer-object-spread`](https://eslint.org/docs/rules/prefer-object-spread)
|
||||
- [3.8](#objects--rest-spread) Prefer the object spread syntax over [`Object.assign`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) to shallow-copy objects. Use the object rest parameter syntax to get a new object with certain properties omitted. eslint: [`prefer-object-spread`](https://eslint.org/docs/rules/prefer-object-spread)
|
||||
|
||||
```javascript
|
||||
// very bad
|
||||
|
||||
@@ -68,20 +68,20 @@
|
||||
},
|
||||
"homepage": "https://github.com/airbnb/javascript",
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@babel/runtime": "^7.16.3",
|
||||
"babel-preset-airbnb": "^4.5.0",
|
||||
"babel-tape-runner": "^3.0.0",
|
||||
"eclint": "^2.8.1",
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-find-rules": "^4.0.0",
|
||||
"eslint-plugin-import": "^2.25.2",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"in-publish": "^2.0.1",
|
||||
"safe-publish-latest": "^2.0.0",
|
||||
"tape": "^5.3.1"
|
||||
"tape": "^5.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-plugin-import": "^2.25.2"
|
||||
"eslint-plugin-import": "^2.25.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.12.0 || >=12.0.0"
|
||||
@@ -89,7 +89,6 @@
|
||||
"dependencies": {
|
||||
"confusing-browser-globals": "^1.0.10",
|
||||
"object.assign": "^4.1.2",
|
||||
"object.entries": "^1.1.5",
|
||||
"semver": "^6.3.0"
|
||||
"object.entries": "^1.1.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,6 +376,11 @@ module.exports = {
|
||||
// https://eslint.org/docs/rules/prefer-named-capture-group
|
||||
'prefer-named-capture-group': 'off',
|
||||
|
||||
// Prefer Object.hasOwn() over Object.prototype.hasOwnProperty.call()
|
||||
// https://eslint.org/docs/rules/prefer-object-has-own
|
||||
// TODO: semver-major: enable thus rule, once eslint v8.5.0 is required
|
||||
'prefer-object-has-own': 'off',
|
||||
|
||||
// https://eslint.org/docs/rules/prefer-regex-literals
|
||||
'prefer-regex-literals': ['error', {
|
||||
disallowRedundantWrapping: true,
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
const semver = require('semver');
|
||||
const eslintPkg = require('eslint/package.json');
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
// enforce line breaks after opening and before closing array brackets
|
||||
@@ -105,7 +102,7 @@ module.exports = {
|
||||
|
||||
// require line breaks inside function parentheses if there are line breaks between parameters
|
||||
// https://eslint.org/docs/rules/function-paren-newline
|
||||
'function-paren-newline': ['error', semver.satisfies(eslintPkg.version, '>= 6') ? 'multiline-arguments' : 'consistent'],
|
||||
'function-paren-newline': ['error', 'multiline-arguments'],
|
||||
|
||||
// disallow specified identifiers
|
||||
// https://eslint.org/docs/rules/id-denylist
|
||||
|
||||
@@ -5,6 +5,7 @@ const entries = require('object.entries');
|
||||
const { ESLint } = require('eslint');
|
||||
|
||||
const baseConfig = require('.');
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
|
||||
@@ -45,52 +46,4 @@ async function onlyErrorOnRules(rulesToError, config) {
|
||||
return errorsOnly;
|
||||
}
|
||||
|
||||
onlyErrorOnRules([
|
||||
'array-bracket-newline',
|
||||
'array-bracket-spacing',
|
||||
'array-element-newline',
|
||||
'arrow-spacing',
|
||||
'block-spacing',
|
||||
'comma-spacing',
|
||||
'computed-property-spacing',
|
||||
'dot-location',
|
||||
'eol-last',
|
||||
'func-call-spacing',
|
||||
'function-paren-newline',
|
||||
'generator-star-spacing',
|
||||
'implicit-arrow-linebreak',
|
||||
'indent',
|
||||
'key-spacing',
|
||||
'keyword-spacing',
|
||||
'line-comment-position',
|
||||
'linebreak-style',
|
||||
'multiline-ternary',
|
||||
'newline-per-chained-call',
|
||||
'no-irregular-whitespace',
|
||||
'no-mixed-spaces-and-tabs',
|
||||
'no-multi-spaces',
|
||||
'no-regex-spaces',
|
||||
'no-spaced-func',
|
||||
'no-trailing-spaces',
|
||||
'no-whitespace-before-property',
|
||||
'nonblock-statement-body-position',
|
||||
'object-curly-newline',
|
||||
'object-curly-spacing',
|
||||
'object-property-newline',
|
||||
'one-var-declaration-per-line',
|
||||
'operator-linebreak',
|
||||
'padded-blocks',
|
||||
'padding-line-between-statements',
|
||||
'rest-spread-spacing',
|
||||
'semi-spacing',
|
||||
'semi-style',
|
||||
'space-before-blocks',
|
||||
'space-before-function-paren',
|
||||
'space-in-parens',
|
||||
'space-infix-ops',
|
||||
'space-unary-ops',
|
||||
'spaced-comment',
|
||||
'switch-colon-spacing',
|
||||
'template-tag-spacing',
|
||||
'import/newline-after-import',
|
||||
], baseConfig).then((config) => console.log(JSON.stringify(config)));
|
||||
onlyErrorOnRules(whitespaceRules, baseConfig).then((config) => console.log(JSON.stringify(config)));
|
||||
|
||||
@@ -6,6 +6,7 @@ if (CLIEngine) {
|
||||
/* eslint no-inner-declarations: 0 */
|
||||
const assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
const baseConfig = require('.');
|
||||
|
||||
@@ -45,55 +46,7 @@ if (CLIEngine) {
|
||||
return errorsOnly;
|
||||
}
|
||||
|
||||
module.exports = onlyErrorOnRules([
|
||||
'array-bracket-newline',
|
||||
'array-bracket-spacing',
|
||||
'array-element-newline',
|
||||
'arrow-spacing',
|
||||
'block-spacing',
|
||||
'comma-spacing',
|
||||
'computed-property-spacing',
|
||||
'dot-location',
|
||||
'eol-last',
|
||||
'func-call-spacing',
|
||||
'function-paren-newline',
|
||||
'generator-star-spacing',
|
||||
'implicit-arrow-linebreak',
|
||||
'indent',
|
||||
'key-spacing',
|
||||
'keyword-spacing',
|
||||
'line-comment-position',
|
||||
'linebreak-style',
|
||||
'multiline-ternary',
|
||||
'newline-per-chained-call',
|
||||
'no-irregular-whitespace',
|
||||
'no-mixed-spaces-and-tabs',
|
||||
'no-multi-spaces',
|
||||
'no-regex-spaces',
|
||||
'no-spaced-func',
|
||||
'no-trailing-spaces',
|
||||
'no-whitespace-before-property',
|
||||
'nonblock-statement-body-position',
|
||||
'object-curly-newline',
|
||||
'object-curly-spacing',
|
||||
'object-property-newline',
|
||||
'one-var-declaration-per-line',
|
||||
'operator-linebreak',
|
||||
'padded-blocks',
|
||||
'padding-line-between-statements',
|
||||
'rest-spread-spacing',
|
||||
'semi-spacing',
|
||||
'semi-style',
|
||||
'space-before-blocks',
|
||||
'space-before-function-paren',
|
||||
'space-in-parens',
|
||||
'space-infix-ops',
|
||||
'space-unary-ops',
|
||||
'spaced-comment',
|
||||
'switch-colon-spacing',
|
||||
'template-tag-spacing',
|
||||
'import/newline-after-import',
|
||||
], baseConfig);
|
||||
module.exports = onlyErrorOnRules(whitespaceRules, baseConfig);
|
||||
} else {
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
49
packages/eslint-config-airbnb-base/whitespaceRules.js
Normal file
49
packages/eslint-config-airbnb-base/whitespaceRules.js
Normal file
@@ -0,0 +1,49 @@
|
||||
module.exports = [
|
||||
'array-bracket-newline',
|
||||
'array-bracket-spacing',
|
||||
'array-element-newline',
|
||||
'arrow-spacing',
|
||||
'block-spacing',
|
||||
'comma-spacing',
|
||||
'computed-property-spacing',
|
||||
'dot-location',
|
||||
'eol-last',
|
||||
'func-call-spacing',
|
||||
'function-paren-newline',
|
||||
'generator-star-spacing',
|
||||
'implicit-arrow-linebreak',
|
||||
'indent',
|
||||
'key-spacing',
|
||||
'keyword-spacing',
|
||||
'line-comment-position',
|
||||
'linebreak-style',
|
||||
'multiline-ternary',
|
||||
'newline-per-chained-call',
|
||||
'no-irregular-whitespace',
|
||||
'no-mixed-spaces-and-tabs',
|
||||
'no-multi-spaces',
|
||||
'no-regex-spaces',
|
||||
'no-spaced-func',
|
||||
'no-trailing-spaces',
|
||||
'no-whitespace-before-property',
|
||||
'nonblock-statement-body-position',
|
||||
'object-curly-newline',
|
||||
'object-curly-spacing',
|
||||
'object-property-newline',
|
||||
'one-var-declaration-per-line',
|
||||
'operator-linebreak',
|
||||
'padded-blocks',
|
||||
'padding-line-between-statements',
|
||||
'rest-spread-spacing',
|
||||
'semi-spacing',
|
||||
'semi-style',
|
||||
'space-before-blocks',
|
||||
'space-before-function-paren',
|
||||
'space-in-parens',
|
||||
'space-infix-ops',
|
||||
'space-unary-ops',
|
||||
'spaced-comment',
|
||||
'switch-colon-spacing',
|
||||
'template-tag-spacing',
|
||||
'import/newline-after-import'
|
||||
];
|
||||
@@ -1,3 +1,36 @@
|
||||
19.0.4 / 2021-12-25
|
||||
==================
|
||||
- republish to fix #2529
|
||||
|
||||
19.0.3 / 2021-12-24
|
||||
==================
|
||||
- [patch] set `namedComponents` option to match style guide
|
||||
- [deps] update `eslint-plugin-react`
|
||||
|
||||
19.0.2 / 2021-12-02
|
||||
==================
|
||||
- [meta] fix "exports" path (#2525)
|
||||
- [Tests] re-enable tests disabled for the eslint 8 upgrade
|
||||
|
||||
19.0.1 / 2021-11-22
|
||||
==================
|
||||
- [fix] `whitespace`: update to support eslint 8 (#2517)
|
||||
- [deps] update `eslint-plugin-react`
|
||||
- [dev deps] update `tape`
|
||||
|
||||
19.0.0 / 2021-11-10
|
||||
==================
|
||||
- [breaking] support `eslint` 8; drop `eslint` < 7
|
||||
- [patch] Explain why `react/jsx-key` is turned off (#2474)
|
||||
- [fix] bump eslint-plugin-react-hooks peer dependency version (#2356)
|
||||
- [patch] Alphabetize the rules for react-a11y.js (#2407)
|
||||
- [Docs] HTTP => HTTPS (#2489)
|
||||
- [readme] clarify hooks requirement (#2482)
|
||||
- [deps] update `eslint-config-airbnb-base`, `eslint-plugin-jsx-a11y`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, `safe-publish-latest`, `eslint-plugin-import`, `object.entries`
|
||||
- [meta] add `--no-save` to link scripts
|
||||
- [meta] use `prepublishOnly` script for npm 7+
|
||||
- [dev deps] update `@babel/runtime`, `tape`
|
||||
|
||||
18.2.1 / 2020-11-06
|
||||
==================
|
||||
- [patch] remove deprecated `jsx-a11y/accessible-emoji` rule (#2322)
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
{
|
||||
"name": "eslint-config-airbnb",
|
||||
"version": "18.2.1",
|
||||
"version": "19.0.4",
|
||||
"description": "Airbnb's ESLint config, following our styleguide",
|
||||
"main": "index.js",
|
||||
"exports": {
|
||||
".": "./index.js",
|
||||
"./base": "./base.js",
|
||||
"./hooks": "./hooks.js",
|
||||
"./legacy": "./legacy.js",
|
||||
"./whitespace": "./whitespace.js",
|
||||
"./rules/react": "./rules/react.js",
|
||||
"./rules/react-a11y": "./rules/react-a11y.js",
|
||||
"./rules/react-hooks": "./rules/react-hooks.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"prelint": "eclint check * rules/* test/*",
|
||||
"lint": "eslint .",
|
||||
@@ -55,34 +66,34 @@
|
||||
},
|
||||
"homepage": "https://github.com/airbnb/javascript",
|
||||
"dependencies": {
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"object.assign": "^4.1.2",
|
||||
"object.entries": "^1.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "^7.16.0",
|
||||
"@babel/runtime": "^7.16.3",
|
||||
"babel-preset-airbnb": "^4.5.0",
|
||||
"babel-tape-runner": "^3.0.0",
|
||||
"eclint": "^2.8.1",
|
||||
"eslint": "^5.16.0 || ^6.8.0 || ^7.2.0",
|
||||
"eslint-find-rules": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.25.2",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-react": "^7.26.0",
|
||||
"eslint-plugin-react-hooks": "^4.0.1 || ^3 || ^2.3.0 || ^1.7.0",
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-find-rules": "^4.0.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"in-publish": "^2.0.1",
|
||||
"react": ">= 0.13.0",
|
||||
"safe-publish-latest": "^1.1.4",
|
||||
"tape": "^5.3.1"
|
||||
"safe-publish-latest": "^2.0.0",
|
||||
"tape": "^5.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^5.16.0 || ^6.8.0 || ^7.2.0",
|
||||
"eslint-plugin-import": "^2.25.2",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-react": "^7.26.0",
|
||||
"eslint-plugin-react-hooks": "^4.0.1 || ^3 || ^2.3.0 || ^1.7.0"
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
"node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
36
packages/eslint-config-airbnb/rules/react.js
vendored
36
packages/eslint-config-airbnb/rules/react.js
vendored
@@ -506,8 +506,7 @@ module.exports = {
|
||||
|
||||
// Prevent usage of `javascript:` URLs
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-script-url.md
|
||||
// TODO: enable, semver-major
|
||||
'react/jsx-no-script-url': ['off', [
|
||||
'react/jsx-no-script-url': ['error', [
|
||||
{
|
||||
name: 'Link',
|
||||
props: ['to'],
|
||||
@@ -516,8 +515,7 @@ module.exports = {
|
||||
|
||||
// Disallow unnecessary fragments
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-useless-fragment.md
|
||||
// TODO: enable, semver-major
|
||||
'react/jsx-no-useless-fragment': 'off',
|
||||
'react/jsx-no-useless-fragment': 'error',
|
||||
|
||||
// Prevent adjacent inline elements not separated by whitespace
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-adjacent-inline-elements.md
|
||||
@@ -526,10 +524,8 @@ module.exports = {
|
||||
|
||||
// Enforce a specific function type for function components
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/function-component-definition.md
|
||||
// TODO: enable! semver-minor, but do it in a major to be safe
|
||||
// TODO: investigate if setting namedComponents to expression vs declaration is problematic
|
||||
'react/function-component-definition': ['off', {
|
||||
namedComponents: 'function-expression',
|
||||
'react/function-component-definition': ['error', {
|
||||
namedComponents: ['function-declaration', 'function-expression'],
|
||||
unnamedComponents: 'function-expression',
|
||||
}],
|
||||
|
||||
@@ -539,23 +535,31 @@ module.exports = {
|
||||
|
||||
// Prevent react contexts from taking non-stable values
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/e2eaadae316f9506d163812a09424eb42698470a/docs/rules/jsx-no-constructed-context-values.md
|
||||
// TODO: enable, semver-minor
|
||||
'react/jsx-no-constructed-context-values': 'off',
|
||||
'react/jsx-no-constructed-context-values': 'error',
|
||||
|
||||
// Prevent creating unstable components inside components
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/c2a790a3472eea0f6de984bdc3ee2a62197417fb/docs/rules/no-unstable-nested-components.md
|
||||
// TODO: enable, semver-major
|
||||
'react/no-unstable-nested-components': 'off',
|
||||
'react/no-unstable-nested-components': 'error',
|
||||
|
||||
// Enforce that namespaces are not used in React elements
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/8785c169c25b09b33c95655bf508cf46263bc53f/docs/rules/no-namespace.md
|
||||
// TODO: enable, semver-minor
|
||||
'react/no-namespace': 'off',
|
||||
'react/no-namespace': 'error',
|
||||
|
||||
// Prefer exact proptype definitions
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/8785c169c25b09b33c95655bf508cf46263bc53f/docs/rules/prefer-exact-props.md
|
||||
// TODO: enable, semver-major, just in case
|
||||
'react/prefer-exact-props': 'off',
|
||||
'react/prefer-exact-props': 'error',
|
||||
|
||||
// Lifecycle methods should be methods on the prototype, not class fields
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/21e01b61af7a38fc86d94f27eb66cda8054582ed/docs/rules/no-arrow-function-lifecycle.md
|
||||
'react/no-arrow-function-lifecycle': 'error',
|
||||
|
||||
// Prevent usage of invalid attributes
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/21e01b61af7a38fc86d94f27eb66cda8054582ed/docs/rules/no-invalid-html-attribute.md
|
||||
'react/no-invalid-html-attribute': 'error',
|
||||
|
||||
// Prevent declaring unused methods of component class
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/21e01b61af7a38fc86d94f27eb66cda8054582ed/docs/rules/no-unused-class-component-methods.md
|
||||
'react/no-unused-class-component-methods': 'error',
|
||||
},
|
||||
|
||||
settings: {
|
||||
|
||||
@@ -4,23 +4,25 @@ import eslintrc from '..';
|
||||
import reactRules from '../rules/react';
|
||||
import reactA11yRules from '../rules/react-a11y';
|
||||
|
||||
const rules = {
|
||||
// It is okay to import devDependencies in tests.
|
||||
'import/no-extraneous-dependencies': [2, { devDependencies: true }],
|
||||
// this doesn't matter for tests
|
||||
'lines-between-class-members': 0,
|
||||
// otherwise we need some junk in our fixture code
|
||||
'react/no-unused-class-component-methods': 0,
|
||||
};
|
||||
const cli = new (CLIEngine || ESLint)({
|
||||
useEslintrc: false,
|
||||
baseConfig: eslintrc,
|
||||
|
||||
rules: {
|
||||
// It is okay to import devDependencies in tests.
|
||||
'import/no-extraneous-dependencies': [2, { devDependencies: true }],
|
||||
// this doesn't matter for tests
|
||||
'lines-between-class-members': 0,
|
||||
},
|
||||
...(CLIEngine ? { rules } : { overrideConfig: { rules } }),
|
||||
});
|
||||
|
||||
function lint(text) {
|
||||
async function lint(text) {
|
||||
// @see https://eslint.org/docs/developer-guide/nodejs-api.html#executeonfiles
|
||||
// @see https://eslint.org/docs/developer-guide/nodejs-api.html#executeontext
|
||||
const linter = CLIEngine ? cli.executeOnText(text) : cli.lintText(text);
|
||||
return linter.results[0];
|
||||
const linter = CLIEngine ? cli.executeOnText(text) : await cli.lintText(text);
|
||||
return (CLIEngine ? linter.results : linter)[0];
|
||||
}
|
||||
|
||||
function wrapComponent(body) {
|
||||
@@ -40,9 +42,8 @@ test('validate react methods order', (t) => {
|
||||
t.deepEqual(reactA11yRules.plugins, ['jsx-a11y', 'react']);
|
||||
});
|
||||
|
||||
t.test('passes a good component', (t) => {
|
||||
t.plan(3);
|
||||
const result = lint(wrapComponent(`
|
||||
t.test('passes a good component', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
componentDidMount() {}
|
||||
handleSubmit() {}
|
||||
onButtonAClick() {}
|
||||
@@ -59,9 +60,8 @@ test('validate react methods order', (t) => {
|
||||
t.notOk(result.errorCount, 'no errors');
|
||||
});
|
||||
|
||||
t.test('order: when random method is first', (t) => {
|
||||
t.plan(2);
|
||||
const result = lint(wrapComponent(`
|
||||
t.test('order: when random method is first', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
someMethod() {}
|
||||
componentDidMount() {}
|
||||
setFoo() {}
|
||||
@@ -75,9 +75,8 @@ test('validate react methods order', (t) => {
|
||||
t.deepEqual(result.messages.map((msg) => msg.ruleId), ['react/sort-comp'], 'fails due to sort');
|
||||
});
|
||||
|
||||
t.test('order: when random method after lifecycle methods', (t) => {
|
||||
t.plan(2);
|
||||
const result = lint(wrapComponent(`
|
||||
t.test('order: when random method after lifecycle methods', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
componentDidMount() {}
|
||||
someMethod() {}
|
||||
setFoo() {}
|
||||
@@ -91,9 +90,8 @@ test('validate react methods order', (t) => {
|
||||
t.deepEqual(result.messages.map((msg) => msg.ruleId), ['react/sort-comp'], 'fails due to sort');
|
||||
});
|
||||
|
||||
t.test('order: when handler method with `handle` prefix after method with `on` prefix', (t) => {
|
||||
t.plan(2);
|
||||
const result = lint(wrapComponent(`
|
||||
t.test('order: when handler method with `handle` prefix after method with `on` prefix', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
componentDidMount() {}
|
||||
onButtonAClick() {}
|
||||
handleSubmit() {}
|
||||
@@ -106,9 +104,8 @@ test('validate react methods order', (t) => {
|
||||
t.deepEqual(result.messages.map((msg) => msg.ruleId), ['react/sort-comp'], 'fails due to sort');
|
||||
});
|
||||
|
||||
t.test('order: when lifecycle methods after event handler methods', (t) => {
|
||||
t.plan(2);
|
||||
const result = lint(wrapComponent(`
|
||||
t.test('order: when lifecycle methods after event handler methods', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
handleSubmit() {}
|
||||
componentDidMount() {}
|
||||
setFoo() {}
|
||||
@@ -120,9 +117,8 @@ test('validate react methods order', (t) => {
|
||||
t.deepEqual(result.messages.map((msg) => msg.ruleId), ['react/sort-comp'], 'fails due to sort');
|
||||
});
|
||||
|
||||
t.test('order: when event handler methods after getters and setters', (t) => {
|
||||
t.plan(2);
|
||||
const result = lint(wrapComponent(`
|
||||
t.test('order: when event handler methods after getters and setters', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
componentDidMount() {}
|
||||
setFoo() {}
|
||||
getFoo() {}
|
||||
|
||||
49
packages/eslint-config-airbnb/whitespace-async.js
Executable file
49
packages/eslint-config-airbnb/whitespace-async.js
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
const { ESLint } = require('eslint');
|
||||
|
||||
const baseConfig = require('.');
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
|
||||
function getSeverity(ruleConfig) {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
async function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = assign({}, config);
|
||||
const cli = new ESLint({
|
||||
useEslintrc: false,
|
||||
baseConfig: config
|
||||
});
|
||||
const baseRules = (await cli.calculateConfigForFile(require.resolve('./'))).rules;
|
||||
|
||||
entries(baseRules).forEach((rule) => {
|
||||
const ruleName = rule[0];
|
||||
const ruleConfig = rule[1];
|
||||
const severity = getSeverity(ruleConfig);
|
||||
|
||||
if (rulesToError.indexOf(ruleName) === -1 && severity === 'error') {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
errorsOnly.rules[ruleName] = ['warn'].concat(ruleConfig.slice(1));
|
||||
} else if (typeof ruleConfig === 'number') {
|
||||
errorsOnly.rules[ruleName] = 1;
|
||||
} else {
|
||||
errorsOnly.rules[ruleName] = 'warn';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return errorsOnly;
|
||||
}
|
||||
|
||||
onlyErrorOnRules(whitespaceRules, baseConfig).then((config) => console.log(JSON.stringify(config)));
|
||||
@@ -1,105 +1,55 @@
|
||||
const assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
/* eslint global-require: 0 */
|
||||
|
||||
const { CLIEngine } = require('eslint');
|
||||
|
||||
const baseConfig = require('.');
|
||||
if (CLIEngine) {
|
||||
/* eslint no-inner-declarations: 0 */
|
||||
const assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
const baseConfig = require('.');
|
||||
|
||||
function getSeverity(ruleConfig) {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
|
||||
function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = assign({}, config);
|
||||
const cli = new CLIEngine({ baseConfig: config, useEslintrc: false });
|
||||
const baseRules = cli.getConfigForFile(require.resolve('./')).rules;
|
||||
|
||||
entries(baseRules).forEach((rule) => {
|
||||
const ruleName = rule[0];
|
||||
const ruleConfig = rule[1];
|
||||
const severity = getSeverity(ruleConfig);
|
||||
|
||||
if (rulesToError.indexOf(ruleName) === -1 && severity === 'error') {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
errorsOnly.rules[ruleName] = ['warn'].concat(ruleConfig.slice(1));
|
||||
} else if (typeof ruleConfig === 'number') {
|
||||
errorsOnly.rules[ruleName] = 1;
|
||||
} else {
|
||||
errorsOnly.rules[ruleName] = 'warn';
|
||||
}
|
||||
function getSeverity(ruleConfig) {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
});
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
return errorsOnly;
|
||||
function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = assign({}, config);
|
||||
const cli = new CLIEngine({ baseConfig: config, useEslintrc: false });
|
||||
const baseRules = cli.getConfigForFile(require.resolve('./')).rules;
|
||||
|
||||
entries(baseRules).forEach((rule) => {
|
||||
const ruleName = rule[0];
|
||||
const ruleConfig = rule[1];
|
||||
const severity = getSeverity(ruleConfig);
|
||||
|
||||
if (rulesToError.indexOf(ruleName) === -1 && severity === 'error') {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
errorsOnly.rules[ruleName] = ['warn'].concat(ruleConfig.slice(1));
|
||||
} else if (typeof ruleConfig === 'number') {
|
||||
errorsOnly.rules[ruleName] = 1;
|
||||
} else {
|
||||
errorsOnly.rules[ruleName] = 'warn';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return errorsOnly;
|
||||
}
|
||||
|
||||
module.exports = onlyErrorOnRules(whitespaceRules, baseConfig);
|
||||
} else {
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
module.exports = JSON.parse(String(execSync(path.join(__dirname, 'whitespace-async.js'))));
|
||||
}
|
||||
|
||||
module.exports = onlyErrorOnRules([
|
||||
'array-bracket-newline',
|
||||
'array-bracket-spacing',
|
||||
'array-element-newline',
|
||||
'arrow-spacing',
|
||||
'block-spacing',
|
||||
'comma-spacing',
|
||||
'computed-property-spacing',
|
||||
'dot-location',
|
||||
'eol-last',
|
||||
'func-call-spacing',
|
||||
'function-paren-newline',
|
||||
'generator-star-spacing',
|
||||
'implicit-arrow-linebreak',
|
||||
'indent',
|
||||
'key-spacing',
|
||||
'keyword-spacing',
|
||||
'line-comment-position',
|
||||
'linebreak-style',
|
||||
'multiline-ternary',
|
||||
'newline-per-chained-call',
|
||||
'no-irregular-whitespace',
|
||||
'no-mixed-spaces-and-tabs',
|
||||
'no-multi-spaces',
|
||||
'no-regex-spaces',
|
||||
'no-spaced-func',
|
||||
'no-trailing-spaces',
|
||||
'no-whitespace-before-property',
|
||||
'nonblock-statement-body-position',
|
||||
'object-curly-newline',
|
||||
'object-curly-spacing',
|
||||
'object-property-newline',
|
||||
'one-var-declaration-per-line',
|
||||
'operator-linebreak',
|
||||
'padded-blocks',
|
||||
'padding-line-between-statements',
|
||||
'rest-spread-spacing',
|
||||
'semi-spacing',
|
||||
'semi-style',
|
||||
'space-before-blocks',
|
||||
'space-before-function-paren',
|
||||
'space-in-parens',
|
||||
'space-infix-ops',
|
||||
'space-unary-ops',
|
||||
'spaced-comment',
|
||||
'switch-colon-spacing',
|
||||
'template-tag-spacing',
|
||||
'import/newline-after-import',
|
||||
// eslint-plugin-react rules
|
||||
'react/jsx-child-element-spacing',
|
||||
'react/jsx-closing-bracket-location',
|
||||
'react/jsx-closing-tag-location',
|
||||
'react/jsx-curly-spacing',
|
||||
'react/jsx-equals-spacing',
|
||||
'react/jsx-first-prop-newline',
|
||||
'react/jsx-indent',
|
||||
'react/jsx-indent-props',
|
||||
'react/jsx-max-props-per-line',
|
||||
'react/jsx-one-expression-per-line',
|
||||
'react/jsx-space-before-closing',
|
||||
'react/jsx-tag-spacing',
|
||||
'react/jsx-wrap-multilines',
|
||||
], baseConfig);
|
||||
|
||||
64
packages/eslint-config-airbnb/whitespaceRules.js
Normal file
64
packages/eslint-config-airbnb/whitespaceRules.js
Normal file
@@ -0,0 +1,64 @@
|
||||
module.exports = [
|
||||
'array-bracket-newline',
|
||||
'array-bracket-spacing',
|
||||
'array-element-newline',
|
||||
'arrow-spacing',
|
||||
'block-spacing',
|
||||
'comma-spacing',
|
||||
'computed-property-spacing',
|
||||
'dot-location',
|
||||
'eol-last',
|
||||
'func-call-spacing',
|
||||
'function-paren-newline',
|
||||
'generator-star-spacing',
|
||||
'implicit-arrow-linebreak',
|
||||
'indent',
|
||||
'key-spacing',
|
||||
'keyword-spacing',
|
||||
'line-comment-position',
|
||||
'linebreak-style',
|
||||
'multiline-ternary',
|
||||
'newline-per-chained-call',
|
||||
'no-irregular-whitespace',
|
||||
'no-mixed-spaces-and-tabs',
|
||||
'no-multi-spaces',
|
||||
'no-regex-spaces',
|
||||
'no-spaced-func',
|
||||
'no-trailing-spaces',
|
||||
'no-whitespace-before-property',
|
||||
'nonblock-statement-body-position',
|
||||
'object-curly-newline',
|
||||
'object-curly-spacing',
|
||||
'object-property-newline',
|
||||
'one-var-declaration-per-line',
|
||||
'operator-linebreak',
|
||||
'padded-blocks',
|
||||
'padding-line-between-statements',
|
||||
'rest-spread-spacing',
|
||||
'semi-spacing',
|
||||
'semi-style',
|
||||
'space-before-blocks',
|
||||
'space-before-function-paren',
|
||||
'space-in-parens',
|
||||
'space-infix-ops',
|
||||
'space-unary-ops',
|
||||
'spaced-comment',
|
||||
'switch-colon-spacing',
|
||||
'template-tag-spacing',
|
||||
'import/newline-after-import',
|
||||
|
||||
// eslint-plugin-react rules
|
||||
'react/jsx-child-element-spacing',
|
||||
'react/jsx-closing-bracket-location',
|
||||
'react/jsx-closing-tag-location',
|
||||
'react/jsx-curly-spacing',
|
||||
'react/jsx-equals-spacing',
|
||||
'react/jsx-first-prop-newline',
|
||||
'react/jsx-indent',
|
||||
'react/jsx-indent-props',
|
||||
'react/jsx-max-props-per-line',
|
||||
'react/jsx-one-expression-per-line',
|
||||
'react/jsx-space-before-closing',
|
||||
'react/jsx-tag-spacing',
|
||||
'react/jsx-wrap-multilines',
|
||||
];
|
||||
Reference in New Issue
Block a user