mirror of
https://github.com/airbnb/javascript.git
synced 2026-01-14 10:38:03 -05:00
Compare commits
259 Commits
eslint-con
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e2ef178a2 | ||
|
|
99ade7a6b1 | ||
|
|
11f986fdc7 | ||
|
|
6499695ac1 | ||
|
|
f45bd1ebc0 | ||
|
|
e6080c7bee | ||
|
|
b912288e4b | ||
|
|
39b970f702 | ||
|
|
d1705c389e | ||
|
|
e6f292286b | ||
|
|
7a8f568769 | ||
|
|
c25bce83be | ||
|
|
f20eca9f64 | ||
|
|
932951adc2 | ||
|
|
5f019b1b11 | ||
|
|
b23992033c | ||
|
|
09adc22031 | ||
|
|
51a37d0fa5 | ||
|
|
0681a43e0a | ||
|
|
55899b57a6 | ||
|
|
e95b1f2754 | ||
|
|
11ab37144b | ||
|
|
46ae3e2256 | ||
|
|
cb191776db | ||
|
|
cda44dad40 | ||
|
|
2fc5e2d52c | ||
|
|
749f4c2bd0 | ||
|
|
4aee38f1e7 | ||
|
|
18a08b862b | ||
|
|
fd77bbebb7 | ||
|
|
7916d6f538 | ||
|
|
01f046dc05 | ||
|
|
0f3ca32323 | ||
|
|
95b6b43d63 | ||
|
|
240a3789db | ||
|
|
0e627e2fa3 | ||
|
|
7982931ba7 | ||
|
|
69fc1bf195 | ||
|
|
5c01a10949 | ||
|
|
bf536566ce | ||
|
|
917c8d92a3 | ||
|
|
8091e39343 | ||
|
|
fd96a4fd57 | ||
|
|
81157eec23 | ||
|
|
4ef69edc63 | ||
|
|
d601701730 | ||
|
|
49d08a2f13 | ||
|
|
0d747c6d96 | ||
|
|
1fb7d76add | ||
|
|
38f1488918 | ||
|
|
c6b1a43c48 | ||
|
|
6947138ee3 | ||
|
|
6fb4f8e878 | ||
|
|
ca0ff97f17 | ||
|
|
0b1f62372e | ||
|
|
7dbb7b154f | ||
|
|
75a908aacf | ||
|
|
f6f63b89f6 | ||
|
|
866f441d05 | ||
|
|
5143a7a97a | ||
|
|
3cbf96de7c | ||
|
|
5155aa5fc1 | ||
|
|
cbf9ade10a | ||
|
|
206d25b55a | ||
|
|
a0e94052d5 | ||
|
|
42c0e2ea13 | ||
|
|
7fdc87a8be | ||
|
|
1677ba6c6a | ||
|
|
7c0f28af8b | ||
|
|
fd2f5a1dae | ||
|
|
b4377fb030 | ||
|
|
34b5bc39f1 | ||
|
|
d4e39c9b10 | ||
|
|
baaa5e8d26 | ||
|
|
274c8d5701 | ||
|
|
38bc026fe4 | ||
|
|
445322db64 | ||
|
|
152bd5e85a | ||
|
|
afc2cc3432 | ||
|
|
371537f393 | ||
|
|
c05ffb2417 | ||
|
|
97a3238020 | ||
|
|
e0bb393519 | ||
|
|
c4000b932a | ||
|
|
31c6f21878 | ||
|
|
91cab81f69 | ||
|
|
d8cb404da7 | ||
|
|
52e710c14e | ||
|
|
1bc8cabd44 | ||
|
|
37ebbba44c | ||
|
|
930a6f2e4c | ||
|
|
366bfa6638 | ||
|
|
f3d3a075cd | ||
|
|
eac8cc605b | ||
|
|
be6966b251 | ||
|
|
4fc997b97e | ||
|
|
96f11d8c81 | ||
|
|
c12a08c479 | ||
|
|
10a6d02c66 | ||
|
|
ef6c478a2b | ||
|
|
6734b78911 | ||
|
|
fdc812a0a5 | ||
|
|
8aec65a4d3 | ||
|
|
ea5b991a4f | ||
|
|
2a6bec1132 | ||
|
|
82dbec3c99 | ||
|
|
122788230a | ||
|
|
4ee7326393 | ||
|
|
7fbed3b55c | ||
|
|
30927d2503 | ||
|
|
f5c14cae2f | ||
|
|
428c9ddb7e | ||
|
|
af8bdf17dd | ||
|
|
d5d406a849 | ||
|
|
35914b1402 | ||
|
|
1fb4592122 | ||
|
|
5641278fa1 | ||
|
|
dc3af3a90e | ||
|
|
1eadb93e37 | ||
|
|
0cf78acab0 | ||
|
|
730b749274 | ||
|
|
4d837646b7 | ||
|
|
1b540ba14e | ||
|
|
711aeb650d | ||
|
|
9c181108a7 | ||
|
|
ea5ec0c524 | ||
|
|
db8b6ceb33 | ||
|
|
b9ff0aee71 | ||
|
|
fb3214c9d6 | ||
|
|
66cd156a48 | ||
|
|
63098cbb6c | ||
|
|
1f786e154f | ||
|
|
5620bd5620 | ||
|
|
f0df3a8680 | ||
|
|
37d48dbf60 | ||
|
|
e5de51e55f | ||
|
|
eee79a5455 | ||
|
|
b7015dd0b3 | ||
|
|
36f23d7886 | ||
|
|
e149b05366 | ||
|
|
f0492d59bd | ||
|
|
25b64d7f46 | ||
|
|
8996aa7c53 | ||
|
|
05c3bb0018 | ||
|
|
d3c7b84d9e | ||
|
|
b30b0e4d91 | ||
|
|
2c5c88d048 | ||
|
|
ee2f22a10c | ||
|
|
aa43bb2398 | ||
|
|
82170f9127 | ||
|
|
5ebfe3e5b8 | ||
|
|
337f60706f | ||
|
|
6006d6d2df | ||
|
|
a24dc34a4a | ||
|
|
1dc71d3839 | ||
|
|
973384be1b | ||
|
|
3dcc591123 | ||
|
|
c5bee75b1b | ||
|
|
5124de23da | ||
|
|
54955410ee | ||
|
|
197b50c076 | ||
|
|
f550ded6da | ||
|
|
562e3519b8 | ||
|
|
78457af2c5 | ||
|
|
5b462a04cd | ||
|
|
22adc06f56 | ||
|
|
fe2e451ba7 | ||
|
|
b587006077 | ||
|
|
8aee3e1600 | ||
|
|
cad3db3169 | ||
|
|
7aa0fa14d6 | ||
|
|
d34f807459 | ||
|
|
c48a060aff | ||
|
|
06b3ab11d9 | ||
|
|
c0ee2c4924 | ||
|
|
e4f3dd4eff | ||
|
|
0375265cbd | ||
|
|
d3628e2600 | ||
|
|
f075a0db50 | ||
|
|
d529ccaea3 | ||
|
|
a3355f90c4 | ||
|
|
e7062c32bb | ||
|
|
c75b66daa6 | ||
|
|
e279b6d3a8 | ||
|
|
6924bd3604 | ||
|
|
165af9b6c8 | ||
|
|
e6e6414c97 | ||
|
|
717ba5187a | ||
|
|
9890b40677 | ||
|
|
3493b060ec | ||
|
|
019e0f7e07 | ||
|
|
41ca203e3e | ||
|
|
651280e5a2 | ||
|
|
f86f19cefc | ||
|
|
4df908033f | ||
|
|
377fbcac88 | ||
|
|
6d05dd898a | ||
|
|
b5954c32b3 | ||
|
|
370793b3dd | ||
|
|
2e3adc98c7 | ||
|
|
5927c7f706 | ||
|
|
56b75dc359 | ||
|
|
64b965efe0 | ||
|
|
3fb312f181 | ||
|
|
8f78e1f44b | ||
|
|
5a32c33bf2 | ||
|
|
df2c99c814 | ||
|
|
ab72ab9e90 | ||
|
|
dee4f172e7 | ||
|
|
c66cfc3f89 | ||
|
|
8c94d53bf8 | ||
|
|
79047a9470 | ||
|
|
7932a52e4b | ||
|
|
1ca21aba79 | ||
|
|
295d1e61cb | ||
|
|
a204cdf38a | ||
|
|
530278467f | ||
|
|
bdba997ac7 | ||
|
|
1e0a696730 | ||
|
|
73f71d9ba4 | ||
|
|
089022aeff | ||
|
|
7f5a65832d | ||
|
|
25075b5f72 | ||
|
|
a23f93eb00 | ||
|
|
b447768ad3 | ||
|
|
b05573cae4 | ||
|
|
e6f591f660 | ||
|
|
282ef9ea90 | ||
|
|
d490ee1806 | ||
|
|
08f8093ed1 | ||
|
|
d03a712bba | ||
|
|
f0c767fd39 | ||
|
|
88e71e6e52 | ||
|
|
11ede40d55 | ||
|
|
e257deebd4 | ||
|
|
6b5922ca21 | ||
|
|
a490005ddf | ||
|
|
bb011c2f2f | ||
|
|
8148bfce3c | ||
|
|
19e9ce31fe | ||
|
|
61c7ae6189 | ||
|
|
8c686eac4b | ||
|
|
a344d6c8e7 | ||
|
|
2160a77baa | ||
|
|
ad0c44c6af | ||
|
|
42c647f31b | ||
|
|
b96341fb86 | ||
|
|
f6acb789a0 | ||
|
|
820745d610 | ||
|
|
8eacf24310 | ||
|
|
3b18fea1ed | ||
|
|
945c62f229 | ||
|
|
820ccf7652 | ||
|
|
792bb567e5 | ||
|
|
6c0a884179 | ||
|
|
030e23b13e | ||
|
|
036612ec3d | ||
|
|
6a50516df7 | ||
|
|
21493ad7e9 |
@@ -8,4 +8,7 @@ trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
# editorconfig-tools is unable to ignore longs strings or urls
|
||||
max_line_length = null
|
||||
max_line_length = off
|
||||
|
||||
[CHANGELOG.md]
|
||||
indent_size = false
|
||||
|
||||
26
.github/workflows/node-pretest.yml
vendored
Normal file
26
.github/workflows/node-pretest.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: 'Tests: pretest/posttest'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
pretest:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
package:
|
||||
- '..'
|
||||
- eslint-config-airbnb
|
||||
- eslint-config-airbnb-base
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: "packages/${{ matrix.package }}"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'nvm install lts/* && npm install'
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- run: npm run pretest
|
||||
163
.github/workflows/node.yml
vendored
Normal file
163
.github/workflows/node.yml
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
name: 'Tests: node.js'
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
latest: ${{ steps.set-matrix.outputs.requireds }}
|
||||
steps:
|
||||
- uses: ljharb/actions/node/matrix@main
|
||||
id: set-matrix
|
||||
with:
|
||||
versionsAsRoot: true
|
||||
type: 'majors'
|
||||
preset: '^12 || ^14 || ^16 || >= 17'
|
||||
|
||||
base:
|
||||
needs: [matrix]
|
||||
name: 'base config'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
|
||||
eslint:
|
||||
- 8
|
||||
- 7
|
||||
package:
|
||||
- eslint-config-airbnb-base
|
||||
exclude:
|
||||
- node-version: 10
|
||||
eslint: 8
|
||||
package: eslint-config-airbnb-base
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: "packages/${{ matrix.package }}"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'nvm install ${{ matrix.node-version }} && npm install'
|
||||
with:
|
||||
before_install: cd "packages/${{ matrix.package }}"
|
||||
node-version: ${{ matrix.node-version }}
|
||||
after_install: |
|
||||
npm install --no-save "eslint@${{ matrix.eslint }}"
|
||||
- run: node -pe "require('eslint/package.json').version"
|
||||
name: 'eslint version'
|
||||
- run: npm run travis
|
||||
- uses: codecov/codecov-action@v2
|
||||
|
||||
react:
|
||||
needs: [matrix]
|
||||
name: 'react config'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: ${{ fromJson(needs.matrix.outputs.latest) }}
|
||||
eslint:
|
||||
- 8
|
||||
- 7
|
||||
package:
|
||||
- eslint-config-airbnb
|
||||
react-hooks:
|
||||
- 4
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: "packages/${{ matrix.package }}"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'nvm install ${{ matrix.node-version }} && npm install'
|
||||
with:
|
||||
before_install: cd "packages/${{ matrix.package }}"
|
||||
node-version: ${{ matrix.node-version }}
|
||||
after_install: |
|
||||
npm install --no-save "eslint@${{ matrix.eslint }}"
|
||||
- run: node -pe "require('eslint/package.json').version"
|
||||
name: 'eslint version'
|
||||
- run: npm install --no-save "eslint-plugin-react-hooks@${{ matrix.react-hooks }}"
|
||||
if: ${{ matrix.react-hooks > 0}}
|
||||
- run: npm run travis
|
||||
- uses: codecov/codecov-action@v2
|
||||
|
||||
prepublish-base:
|
||||
name: 'prepublish tests (base config)'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
eslint:
|
||||
- 8
|
||||
- 7
|
||||
package:
|
||||
- eslint-config-airbnb-base
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: "packages/${{ matrix.package }}"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'nvm install lts/* && npm install'
|
||||
with:
|
||||
before_install: cd "packages/${{ matrix.package }}"
|
||||
node-version: lts/*
|
||||
after_install: |
|
||||
npm install --no-save "eslint@${{ matrix.eslint }}"
|
||||
- run: node -pe "require('eslint/package.json').version"
|
||||
name: 'eslint version'
|
||||
- run: npm run pretravis
|
||||
- run: npm run prepublishOnly
|
||||
- run: npm run posttravis
|
||||
|
||||
prepublish-react:
|
||||
name: 'prepublish tests (react config)'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
eslint:
|
||||
- 8
|
||||
- 7
|
||||
package:
|
||||
- eslint-config-airbnb
|
||||
react-hooks:
|
||||
- 4
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: "packages/${{ matrix.package }}"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/actions/node/install@main
|
||||
name: 'nvm install lts/* && npm install'
|
||||
with:
|
||||
before_install: cd "packages/${{ matrix.package }}"
|
||||
node-version: lts/*
|
||||
after_install: |
|
||||
npm install --no-save "eslint@${{ matrix.eslint }}"
|
||||
- run: npm install --no-save "eslint-plugin-react-hooks@${{ matrix.react-hooks }}"
|
||||
if: ${{ matrix.react-hooks > 0}}
|
||||
- run: node -pe "require('eslint/package.json').version"
|
||||
name: 'eslint version'
|
||||
- run: npm run pretravis
|
||||
- run: npm run prepublishOnly
|
||||
- run: npm run posttravis
|
||||
|
||||
node:
|
||||
name: 'node 10+'
|
||||
needs: [base, prepublish-base, react, prepublish-react]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: 'echo tests completed'
|
||||
15
.github/workflows/rebase.yml
vendored
Normal file
15
.github/workflows/rebase.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: Automatic Rebase
|
||||
|
||||
on: [pull_request_target]
|
||||
|
||||
jobs:
|
||||
_:
|
||||
name: "Automatic Rebase"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ljharb/rebase@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
12
.github/workflows/require-allow-edits.yml
vendored
Normal file
12
.github/workflows/require-allow-edits.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
name: Require “Allow Edits”
|
||||
|
||||
on: [pull_request_target]
|
||||
|
||||
jobs:
|
||||
_:
|
||||
name: "Require “Allow Edits”"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: ljharb/require-allow-edits@main
|
||||
55
.travis.yml
55
.travis.yml
@@ -1,55 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "11"
|
||||
- "10"
|
||||
- "9"
|
||||
- "8"
|
||||
- "7"
|
||||
- "6"
|
||||
- "5"
|
||||
- "4"
|
||||
before_install:
|
||||
- 'nvm install-latest-npm'
|
||||
install:
|
||||
- 'if [ -n "${PACKAGE-}" ]; then cd "packages/${PACKAGE}"; fi'
|
||||
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ] || [ "${TRAVIS_NODE_VERSION}" = "0.9" ]; then nvm install --latest-npm 0.8 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;'
|
||||
- 'if [ -n "${ESLINT}" ]; then npm install --no-save "eslint@${ESLINT}"; fi'
|
||||
script:
|
||||
- 'if [ -n "${PREPUBLISH-}" ]; then npm run pretravis && npm run prepublish && npm run posttravis; elif [ -n "${LINT-}" ]; then npm run lint; else npm run travis; fi'
|
||||
sudo: false
|
||||
env:
|
||||
matrix:
|
||||
- 'TEST=true ESLINT=5 PACKAGE=eslint-config-airbnb-base'
|
||||
- 'TEST=true ESLINT=5 PACKAGE=eslint-config-airbnb'
|
||||
- 'TEST=true ESLINT=4 PACKAGE=eslint-config-airbnb-base'
|
||||
- 'TEST=true ESLINT=4 PACKAGE=eslint-config-airbnb'
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- node_js: "lts/*"
|
||||
env: PREPUBLISH=true ESLINT=5 PACKAGE=eslint-config-airbnb-base
|
||||
- node_js: "lts/*"
|
||||
env: PREPUBLISH=true ESLINT=5 PACKAGE=eslint-config-airbnb
|
||||
- node_js: "lts/*"
|
||||
env: PREPUBLISH=true ESLINT=4 PACKAGE=eslint-config-airbnb-base
|
||||
- node_js: "lts/*"
|
||||
env: PREPUBLISH=true ESLINT=4 PACKAGE=eslint-config-airbnb
|
||||
- node_js: "lts/*"
|
||||
env: LINT=true
|
||||
exclude:
|
||||
- node_js: "5"
|
||||
env: TEST=true ESLINT=5 PACKAGE=eslint-config-airbnb-base
|
||||
- node_js: "5"
|
||||
env: TEST=true ESLINT=5 PACKAGE=eslint-config-airbnb
|
||||
- node_js: "4"
|
||||
env: TEST=true ESLINT=5 PACKAGE=eslint-config-airbnb-base
|
||||
- node_js: "4"
|
||||
env: TEST=true ESLINT=5 PACKAGE=eslint-config-airbnb
|
||||
allow_failures:
|
||||
- node_js: "9"
|
||||
- node_js: "7"
|
||||
- node_js: "5"
|
||||
- env: PREPUBLISH=true ESLINT=5 PACKAGE=eslint-config-airbnb-base
|
||||
- env: PREPUBLISH=true ESLINT=5 PACKAGE=eslint-config-airbnb
|
||||
- env: PREPUBLISH=true ESLINT=4 PACKAGE=eslint-config-airbnb-base
|
||||
- env: PREPUBLISH=true ESLINT=4 PACKAGE=eslint-config-airbnb
|
||||
3
CODE_OF_CONDUCT.md
Normal file
3
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,3 @@
|
||||
Airbnb has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full Code of Conduct text](https://airbnb.io/codeofconduct/) so that you can understand what actions will and will not be tolerated. Report violations to the maintainers of this project or to [opensource-conduct@airbnb.com](mailto:opensource-conduct@airbnb.com).
|
||||
|
||||
Reports sent to [opensource-conduct@airbnb.com](mailto:opensource-conduct@airbnb.com) are received by Airbnb's open source code of conduct moderation team, which is composed of Airbnb employees. All communications are private and confidential.
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
- Use an underscore for modifiers to other styles.
|
||||
|
||||
> Why? Similar to BEM, this naming convention makes it clear that the styles are intended to modify the element preceded by the underscore. Underscores do not need to be quoted, so they are preferred over other characters, such as dashes.
|
||||
> Why? Similar to [BEM](https://getbem.com/introduction/), this naming convention makes it clear that the styles are intended to modify the element preceded by the underscore. Underscores do not need to be quoted, so they are preferred over other characters, such as dashes.
|
||||
|
||||
```js
|
||||
// bad
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
|
||||
"comment": "MD007: Unordered list indentation: 2 spaces.",
|
||||
"ul-indent": {
|
||||
"indent": 2
|
||||
"indent": 2,
|
||||
"start_indented": true
|
||||
},
|
||||
|
||||
"comment": "MD009: Disallow trailing spaces!",
|
||||
@@ -68,7 +69,7 @@
|
||||
"no-multiple-space-closed-atx": true,
|
||||
|
||||
"comment": "MD022: Headers should be surrounded by blank lines.",
|
||||
"comment": "Some headers have preceeding HTML anchors. Unfortunate that we have to disable this, as it otherwise catches a real problem that trips up some Markdown renderers",
|
||||
"comment": "Some headers have preceding HTML anchors. Unfortunate that we have to disable this, as it otherwise catches a real problem that trips up some Markdown renderers",
|
||||
"blanks-around-headers": false,
|
||||
|
||||
"comment": "MD023: Headers must start at the beginning of the line.",
|
||||
@@ -110,7 +111,7 @@
|
||||
"blanks-around-fences": true,
|
||||
|
||||
"comment": "MD032: Lists should be surrounded by blank lines",
|
||||
"comment": "Some lists have preceeding HTML anchors. Unfortunate that we have to disable this, as it otherwise catches a real problem that trips up some Markdown renderers",
|
||||
"comment": "Some lists have preceding HTML anchors. Unfortunate that we have to disable this, as it otherwise catches a real problem that trips up some Markdown renderers",
|
||||
"blanks-around-lists": false,
|
||||
|
||||
"comment": "MD033: Disallow inline HTML",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* @version 0.3.0
|
||||
* @see https://github.com/SublimeLinter/SublimeLinter
|
||||
* @see http://www.jshint.com/docs/
|
||||
* @see https://www.jshint.com/docs/
|
||||
*/
|
||||
{
|
||||
"jshint_options":
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"description": "A mostly reasonable approach to JavaScript.",
|
||||
"scripts": {
|
||||
"preinstall": "npm run install:config && npm run install:config:base",
|
||||
"postinstall": "rm -rf node_modules/markdownlint-cli/node_modules/markdownlint",
|
||||
"install:config": "cd packages/eslint-config-airbnb && npm prune && npm install",
|
||||
"install:config:base": "cd packages/eslint-config-airbnb-base && npm prune && npm install",
|
||||
"lint": "markdownlint --config linters/.markdownlint.json README.md */README.md",
|
||||
@@ -39,6 +40,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/airbnb/javascript",
|
||||
"devDependencies": {
|
||||
"markdownlint-cli": "^0.13.0"
|
||||
"markdownlint": "^0.29.0",
|
||||
"markdownlint-cli": "^0.35.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// disable requiring trailing commas because it might be nice to revert to
|
||||
// being JSON at some point, and I don't want to make big changes now.
|
||||
"comma-dangle": 0,
|
||||
// we support node 4
|
||||
"prefer-destructuring": 0,
|
||||
|
||||
"max-len": 0,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,3 +1,77 @@
|
||||
15.0.0 / 2021-11-08
|
||||
==================
|
||||
- [breaking] drop eslint < 7, add eslint 8 (#2495)
|
||||
- [breaking] add `exports`
|
||||
- [patch] Improve `function-paren-newline` with `multiline-arguments` option (#2471)
|
||||
- [patch] update default value for complexity (#2420)
|
||||
- [patch] add disabled `no-unsafe-optional-chaining` rule
|
||||
- [patch] arthmetic -> arithmetic (#2341)
|
||||
- [patch] fix spelling of "than" (#2333)
|
||||
- [patch] add `no-nonoctal-decimal-escape` rule
|
||||
- [patch] `import/no-extraneous-dependencies`: Add .eslintrc.js to devDeps (#2329)
|
||||
- [guide] Spread operator => Spread syntax (#2423)
|
||||
- [guide] add references for eslint rules (#2419)
|
||||
- [Docs] HTTP => HTTPS (#2489)
|
||||
- [readme] some updates
|
||||
- [meta] use `prepublishOnly` script for npm 7+
|
||||
- [deps] update `eslint-plugin-import`, `eslint-plugin-react`, `object.entries`
|
||||
- [dev deps] update `@babel/runtime`, `tape`
|
||||
|
||||
14.2.1 / 2020-11-06
|
||||
==================
|
||||
- [base] `no-restricted-globals`: add better messages (#2320)
|
||||
- [base] add new core eslint rules, set to off
|
||||
- [deps] update `confusing-browser-globals`, `object.assign`
|
||||
- [deps] update `eslint-plugin-import`, use valid `import/no-cycle` `maxDepth` option (#2250, #2249)
|
||||
- [dev deps] update `@babel/runtime`, `eslint-find-rules`, `eslint-plugin-import`
|
||||
|
||||
14.2.0 / 2020-06-10
|
||||
==================
|
||||
- [new] add `eslint` `v7`
|
||||
- [minor] Disallow multiple empty lines (#2238)
|
||||
- [minor] Fix typo in no-multiple-empty-lines rule (#2168)
|
||||
- [patch] Include 'context' exception for `no-param-reassign` (#2230)
|
||||
- [patch] Allow triple-slash (///) comments (#2197)
|
||||
- [patch] Disable `prefer-object-spread` for `airbnb-base/legacy` (#2198)
|
||||
- [deps] update `eslint-plugin-import`, `eslint-plugin-react`, `babel-preset-airbnb`, `eslint-find-rules`, `in-publish`, `tape`, `object.entries`
|
||||
|
||||
14.1.0 / 2020-03-12
|
||||
==================
|
||||
- [minor] add new disabled rules, update eslint
|
||||
- [minor] enable `import/no-useless-path-segments` for commonjs (#2113)
|
||||
- [fix] `whitespace`: only set erroring rules to "warn"
|
||||
- Fix indentation with JSX Fragments (#2157)
|
||||
- [patch] `import/no-extraneous-dependencies`: Support karma config files (#2121)
|
||||
- [readme] normalize multiline word according to merriam-webster (#2138)
|
||||
- [deps] update `eslint`, `eslint-plugin-import`, `eslint-plugin-react`, `object.entries`, `confusing-browser-globals`
|
||||
- [dev deps] update `@babel/runtime`, `babel-preset-airbnb`, `safe-publish-latest`, `tape`
|
||||
- [tests] re-enable eslint rule `prefer-destructuring` internally (#2110)
|
||||
|
||||
14.0.0 / 2019-08-09
|
||||
==================
|
||||
- [breaking] `no-self-assign`: enable `props` option
|
||||
- [breaking] enable `no-useless-catch`
|
||||
- [breaking] enable `max-classes-per-file`
|
||||
- [breaking] enable `no-misleading-character-class`
|
||||
- [breaking] enable `no-async-promise-executor`
|
||||
- [breaking] enable `prefer-object-spread`
|
||||
- [breaking] `func-name-matching`: enable `considerPropertyDescriptor` option
|
||||
- [breaking] `padded-blocks`: enable `allowSingleLineBlocks` option (#1255)
|
||||
- [breaking] `no-multiple-empty-lines`: Restrict empty lines at beginning of file (#2042)
|
||||
- [breaking] Set 'strict' to 'never' (#1962)
|
||||
- [breaking] legacy: Enable 'strict' (#1962)
|
||||
- [breaking] Simplifies `no-mixed-operators` (#1864)
|
||||
- [breaking] Require parens for arrow function args (#1863)
|
||||
- [breaking] add eslint v6, drop eslint v4
|
||||
- [patch] `camelcase`: enable ignoreDestructuring
|
||||
- [patch] Add markers to spaced-comment block for Flow types (#1966)
|
||||
- [patch] Do not prefer destructuring for object assignment expression (#1583)
|
||||
- [deps] update `confusing-browser-globals`, `eslint-plugin-import`, `tape`, `babel-preset-airbnb`
|
||||
- [dev deps] update babel-related deps to latest
|
||||
- [dev deps] update `eslint-find-rules`, `eslint-plugin-import`
|
||||
- [tests] only run tests in non-lint per-package travis job
|
||||
- [tests] use `eclint` instead of `editorconfig-tools`
|
||||
|
||||
13.2.0 / 2019-07-01
|
||||
==================
|
||||
- [minor] Enforce dangling underscores in method names (#1907)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# eslint-config-airbnb-base
|
||||
# eslint-config-airbnb-base <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
|
||||
|
||||
[](http://badge.fury.io/js/eslint-config-airbnb-base)
|
||||
[][package-url]
|
||||
|
||||
[![github actions][actions-image]][actions-url]
|
||||
[![License][license-image]][license-url]
|
||||
[![Downloads][downloads-image]][downloads-url]
|
||||
|
||||
This package provides Airbnb's base JS .eslintrc (without React plugins) as an extensible shared config.
|
||||
|
||||
@@ -79,7 +83,7 @@ Lints ES5 and below. Requires `eslint` and `eslint-plugin-import`.
|
||||
Which produces and runs a command like:
|
||||
|
||||
```sh
|
||||
npm install --save-dev eslint-config-airbnb-base eslint@^3.0.1 eslint-plugin-import@^1.10.3
|
||||
npm install --save-dev eslint-config-airbnb-base eslint@^#.#.# eslint-plugin-import@^#.#.#
|
||||
```
|
||||
|
||||
2. Add `"extends": "airbnb-base/legacy"` to your .eslintrc
|
||||
@@ -97,3 +101,12 @@ Consider adding test cases if you're making complicated rules changes, like anyt
|
||||
You can run tests with `npm test`.
|
||||
|
||||
You can make sure this module lints with itself using `npm run lint`.
|
||||
|
||||
[package-url]: https://npmjs.org/package/eslint-config-airbnb-base
|
||||
[npm-version-svg]: https://versionbadg.es/airbnb/javascript.svg
|
||||
[license-image]: https://img.shields.io/npm/l/eslint-config-airbnb-base.svg
|
||||
[license-url]: LICENSE.md
|
||||
[downloads-image]: https://img.shields.io/npm/dm/eslint-config-airbnb-base.svg
|
||||
[downloads-url]: https://npm-stat.com/charts.html?package=eslint-config-airbnb-base
|
||||
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/airbnb/javascript
|
||||
[actions-url]: https://github.com/airbnb/javascript/actions
|
||||
|
||||
@@ -7,12 +7,11 @@ module.exports = {
|
||||
'./rules/variables',
|
||||
'./rules/es6',
|
||||
'./rules/imports',
|
||||
'./rules/strict',
|
||||
].map(require.resolve),
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
strict: 'error',
|
||||
},
|
||||
rules: {},
|
||||
};
|
||||
|
||||
@@ -27,6 +27,8 @@ module.exports = {
|
||||
property: '__defineSetter__',
|
||||
message: 'Please use Object.defineProperty instead.',
|
||||
}],
|
||||
'no-var': 'off'
|
||||
'no-var': 'off',
|
||||
'prefer-object-spread': 'off',
|
||||
strict: ['error', 'safe'],
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,18 +1,33 @@
|
||||
{
|
||||
"name": "eslint-config-airbnb-base",
|
||||
"version": "13.2.0",
|
||||
"version": "15.0.0",
|
||||
"description": "Airbnb's base JS ESLint config, following our styleguide",
|
||||
"main": "index.js",
|
||||
"exports": {
|
||||
".": "./index.js",
|
||||
"./legacy": "./legacy.js",
|
||||
"./whitespace": "./whitespace.js",
|
||||
"./rules/best-practices": "./rules/best-practices.js",
|
||||
"./rules/es6": "./rules/es6.js",
|
||||
"./rules/node": "./rules/node.js",
|
||||
"./rules/style": "./rules/style.js",
|
||||
"./rules/errors": "./rules/errors.js",
|
||||
"./rules/imports": "./rules/imports.js",
|
||||
"./rules/strict": "./rules/strict.js",
|
||||
"./rules/variables": "./rules/variables.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"prelint": "editorconfig-tools check * rules/* test/*",
|
||||
"prelint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git')",
|
||||
"lint": "eslint --report-unused-disable-directives .",
|
||||
"pretests-only": "node ./test/requires",
|
||||
"tests-only": "babel-tape-runner ./test/test-*.js",
|
||||
"prepublish": "(in-install || eslint-find-rules --unused) && (not-in-publish || npm test) && safe-publish-latest",
|
||||
"prepublishOnly": "eslint-find-rules --unused && npm test && safe-publish-latest",
|
||||
"prepublish": "not-in-publish || npm run prepublishOnly",
|
||||
"pretest": "npm run --silent lint",
|
||||
"test": "npm run --silent tests-only",
|
||||
"pretravis": ":",
|
||||
"travis": "npm run --silent test",
|
||||
"travis": "npm run --silent tests-only",
|
||||
"posttravis": ":"
|
||||
},
|
||||
"repository": {
|
||||
@@ -53,26 +68,25 @@
|
||||
},
|
||||
"homepage": "https://github.com/airbnb/javascript",
|
||||
"devDependencies": {
|
||||
"babel-preset-airbnb": "^2.5.3",
|
||||
"babel-tape-runner": "^2.0.1",
|
||||
"editorconfig-tools": "^0.1.1",
|
||||
"eslint": "^4.19.1 || ^5.3.0",
|
||||
"eslint-find-rules": "^3.3.1",
|
||||
"eslint-plugin-import": "^2.17.2",
|
||||
"in-publish": "^2.0.0",
|
||||
"safe-publish-latest": "^1.1.2",
|
||||
"tape": "^4.10.1"
|
||||
"@babel/runtime": "^7.25.6",
|
||||
"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.1.0",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"in-publish": "^2.0.1",
|
||||
"safe-publish-latest": "^2.0.0",
|
||||
"tape": "^5.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^4.19.1 || ^5.3.0",
|
||||
"eslint-plugin-import": "^2.17.2"
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-plugin-import": "^2.30.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
"node": "^10.12.0 || >=12.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"confusing-browser-globals": "^1.0.5",
|
||||
"object.assign": "^4.1.0",
|
||||
"object.entries": "^1.1.0"
|
||||
"confusing-browser-globals": "^1.0.11"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
rules: {
|
||||
// enforces getter/setter pairs in objects
|
||||
// https://eslint.org/docs/rules/accessor-pairs
|
||||
'accessor-pairs': 'off',
|
||||
|
||||
// enforces return statements in callbacks of array's methods
|
||||
@@ -8,10 +9,12 @@ module.exports = {
|
||||
'array-callback-return': ['error', { allowImplicit: true }],
|
||||
|
||||
// treat var statements as if they were block scoped
|
||||
// https://eslint.org/docs/rules/block-scoped-var
|
||||
'block-scoped-var': 'error',
|
||||
|
||||
// specify the maximum cyclomatic complexity allowed in a program
|
||||
complexity: ['off', 11],
|
||||
// https://eslint.org/docs/rules/complexity
|
||||
complexity: ['off', 20],
|
||||
|
||||
// enforce that class methods use "this"
|
||||
// https://eslint.org/docs/rules/class-methods-use-this
|
||||
@@ -20,15 +23,26 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// require return statements to either always or never specify values
|
||||
// https://eslint.org/docs/rules/consistent-return
|
||||
'consistent-return': 'error',
|
||||
|
||||
// specify curly brace conventions for all control statements
|
||||
curly: ['error', 'multi-line'],
|
||||
// https://eslint.org/docs/rules/curly
|
||||
curly: ['error', 'multi-line'], // multiline
|
||||
|
||||
// require default case in switch statements
|
||||
// https://eslint.org/docs/rules/default-case
|
||||
'default-case': ['error', { commentPattern: '^no default$' }],
|
||||
|
||||
// Enforce default clauses in switch statements to be last
|
||||
// https://eslint.org/docs/rules/default-case-last
|
||||
'default-case-last': 'error',
|
||||
|
||||
// https://eslint.org/docs/rules/default-param-last
|
||||
'default-param-last': 'error',
|
||||
|
||||
// encourages use of dot notation whenever possible
|
||||
// https://eslint.org/docs/rules/dot-notation
|
||||
'dot-notation': ['error', { allowKeywords: true }],
|
||||
|
||||
// enforces consistent newlines before or after dots
|
||||
@@ -39,24 +53,35 @@ module.exports = {
|
||||
// https://eslint.org/docs/rules/eqeqeq
|
||||
eqeqeq: ['error', 'always', { null: 'ignore' }],
|
||||
|
||||
// Require grouped accessor pairs in object literals and classes
|
||||
// https://eslint.org/docs/rules/grouped-accessor-pairs
|
||||
'grouped-accessor-pairs': 'error',
|
||||
|
||||
// make sure for-in loops have an if statement
|
||||
// https://eslint.org/docs/rules/guard-for-in
|
||||
'guard-for-in': 'error',
|
||||
|
||||
// enforce a maximum number of classes per file
|
||||
// https://eslint.org/docs/rules/max-classes-per-file
|
||||
// TODO: semver-major (eslint 5): enable
|
||||
'max-classes-per-file': ['off', 1],
|
||||
'max-classes-per-file': ['error', 1],
|
||||
|
||||
// disallow the use of alert, confirm, and prompt
|
||||
// https://eslint.org/docs/rules/no-alert
|
||||
// TODO: enable, semver-major
|
||||
'no-alert': 'warn',
|
||||
|
||||
// disallow use of arguments.caller or arguments.callee
|
||||
// https://eslint.org/docs/rules/no-caller
|
||||
'no-caller': 'error',
|
||||
|
||||
// disallow lexical declarations in case/default clauses
|
||||
// https://eslint.org/docs/rules/no-case-declarations.html
|
||||
// https://eslint.org/docs/rules/no-case-declarations
|
||||
'no-case-declarations': 'error',
|
||||
|
||||
// Disallow returning value in constructor
|
||||
// https://eslint.org/docs/rules/no-constructor-return
|
||||
'no-constructor-return': 'error',
|
||||
|
||||
// disallow division operators explicitly at beginning of regular expression
|
||||
// https://eslint.org/docs/rules/no-div-regex
|
||||
'no-div-regex': 'off',
|
||||
@@ -79,16 +104,25 @@ module.exports = {
|
||||
// https://eslint.org/docs/rules/no-empty-pattern
|
||||
'no-empty-pattern': 'error',
|
||||
|
||||
// Disallow empty static blocks
|
||||
// https://eslint.org/docs/latest/rules/no-empty-static-block
|
||||
// TODO: semver-major, enable
|
||||
'no-empty-static-block': 'off',
|
||||
|
||||
// disallow comparisons to null without a type-checking operator
|
||||
// https://eslint.org/docs/rules/no-eq-null
|
||||
'no-eq-null': 'off',
|
||||
|
||||
// disallow use of eval()
|
||||
// https://eslint.org/docs/rules/no-eval
|
||||
'no-eval': 'error',
|
||||
|
||||
// disallow adding to native types
|
||||
// https://eslint.org/docs/rules/no-extend-native
|
||||
'no-extend-native': 'error',
|
||||
|
||||
// disallow unnecessary function binding
|
||||
// https://eslint.org/docs/rules/no-extra-bind
|
||||
'no-extra-bind': 'error',
|
||||
|
||||
// disallow Unnecessary Labels
|
||||
@@ -96,15 +130,19 @@ module.exports = {
|
||||
'no-extra-label': 'error',
|
||||
|
||||
// disallow fallthrough of case statements
|
||||
// https://eslint.org/docs/rules/no-fallthrough
|
||||
'no-fallthrough': 'error',
|
||||
|
||||
// disallow the use of leading or trailing decimal points in numeric literals
|
||||
// https://eslint.org/docs/rules/no-floating-decimal
|
||||
'no-floating-decimal': 'error',
|
||||
|
||||
// disallow reassignments of native objects or read-only globals
|
||||
// https://eslint.org/docs/rules/no-global-assign
|
||||
'no-global-assign': ['error', { exceptions: [] }],
|
||||
|
||||
// deprecated in favor of no-global-assign
|
||||
// https://eslint.org/docs/rules/no-native-reassign
|
||||
'no-native-reassign': 'off',
|
||||
|
||||
// disallow implicit type conversions
|
||||
@@ -121,21 +159,27 @@ module.exports = {
|
||||
'no-implicit-globals': 'off',
|
||||
|
||||
// disallow use of eval()-like methods
|
||||
// https://eslint.org/docs/rules/no-implied-eval
|
||||
'no-implied-eval': 'error',
|
||||
|
||||
// disallow this keywords outside of classes or class-like objects
|
||||
// https://eslint.org/docs/rules/no-invalid-this
|
||||
'no-invalid-this': 'off',
|
||||
|
||||
// disallow usage of __iterator__ property
|
||||
// https://eslint.org/docs/rules/no-iterator
|
||||
'no-iterator': 'error',
|
||||
|
||||
// disallow use of labels for anything other then loops and switches
|
||||
// disallow use of labels for anything other than loops and switches
|
||||
// https://eslint.org/docs/rules/no-labels
|
||||
'no-labels': ['error', { allowLoop: false, allowSwitch: false }],
|
||||
|
||||
// disallow unnecessary nested blocks
|
||||
// https://eslint.org/docs/rules/no-lone-blocks
|
||||
'no-lone-blocks': 'error',
|
||||
|
||||
// disallow creation of functions within loops
|
||||
// https://eslint.org/docs/rules/no-loop-func
|
||||
'no-loop-func': 'error',
|
||||
|
||||
// disallow magic numbers
|
||||
@@ -148,27 +192,43 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// disallow use of multiple spaces
|
||||
// https://eslint.org/docs/rules/no-multi-spaces
|
||||
'no-multi-spaces': ['error', {
|
||||
ignoreEOLComments: false,
|
||||
}],
|
||||
|
||||
// disallow use of multiline strings
|
||||
// https://eslint.org/docs/rules/no-multi-str
|
||||
'no-multi-str': 'error',
|
||||
|
||||
// disallow use of new operator when not part of the assignment or comparison
|
||||
// https://eslint.org/docs/rules/no-new
|
||||
'no-new': 'error',
|
||||
|
||||
// disallow use of new operator for Function object
|
||||
// https://eslint.org/docs/rules/no-new-func
|
||||
'no-new-func': 'error',
|
||||
|
||||
// disallows creating new instances of String, Number, and Boolean
|
||||
// https://eslint.org/docs/rules/no-new-wrappers
|
||||
'no-new-wrappers': 'error',
|
||||
|
||||
// Disallow \8 and \9 escape sequences in string literals
|
||||
// https://eslint.org/docs/rules/no-nonoctal-decimal-escape
|
||||
'no-nonoctal-decimal-escape': 'error',
|
||||
|
||||
// Disallow calls to the Object constructor without an argument
|
||||
// https://eslint.org/docs/latest/rules/no-object-constructor
|
||||
// TODO: enable, semver-major
|
||||
'no-object-constructor': 'off',
|
||||
|
||||
// disallow use of (old style) octal literals
|
||||
// https://eslint.org/docs/rules/no-octal
|
||||
'no-octal': 'error',
|
||||
|
||||
// disallow use of octal escape sequences in string literals, such as
|
||||
// var foo = 'Copyright \251';
|
||||
// https://eslint.org/docs/rules/no-octal-escape
|
||||
'no-octal-escape': 'error',
|
||||
|
||||
// disallow reassignment of function parameters
|
||||
@@ -181,6 +241,7 @@ module.exports = {
|
||||
'accumulator', // for reduce accumulators
|
||||
'e', // for e.returnvalue
|
||||
'ctx', // for Koa routing
|
||||
'context', // for Koa routing
|
||||
'req', // for Express requests
|
||||
'request', // for Express requests
|
||||
'res', // for Express responses
|
||||
@@ -191,9 +252,11 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// disallow usage of __proto__ property
|
||||
// https://eslint.org/docs/rules/no-proto
|
||||
'no-proto': 'error',
|
||||
|
||||
// disallow declaring the same variable more then once
|
||||
// disallow declaring the same variable more than once
|
||||
// https://eslint.org/docs/rules/no-redeclare
|
||||
'no-redeclare': 'error',
|
||||
|
||||
// disallow certain object properties
|
||||
@@ -239,28 +302,33 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// disallow use of assignment in return statement
|
||||
// https://eslint.org/docs/rules/no-return-assign
|
||||
'no-return-assign': ['error', 'always'],
|
||||
|
||||
// disallow redundant `return await`
|
||||
// https://eslint.org/docs/rules/no-return-await
|
||||
'no-return-await': 'error',
|
||||
|
||||
// disallow use of `javascript:` urls.
|
||||
// https://eslint.org/docs/rules/no-script-url
|
||||
'no-script-url': 'error',
|
||||
|
||||
// disallow self assignment
|
||||
// https://eslint.org/docs/rules/no-self-assign
|
||||
// TODO: semver-major: props -> true
|
||||
'no-self-assign': ['error', {
|
||||
props: false,
|
||||
props: true,
|
||||
}],
|
||||
|
||||
// disallow comparisons where both sides are exactly the same
|
||||
// https://eslint.org/docs/rules/no-self-compare
|
||||
'no-self-compare': 'error',
|
||||
|
||||
// disallow use of comma operator
|
||||
// https://eslint.org/docs/rules/no-sequences
|
||||
'no-sequences': 'error',
|
||||
|
||||
// restrict what can be thrown as an exception
|
||||
// https://eslint.org/docs/rules/no-throw-literal
|
||||
'no-throw-literal': 'error',
|
||||
|
||||
// disallow unmodified conditions of loops
|
||||
@@ -268,6 +336,7 @@ module.exports = {
|
||||
'no-unmodified-loop-condition': 'off',
|
||||
|
||||
// disallow usage of expressions in statement position
|
||||
// https://eslint.org/docs/rules/no-unused-expressions
|
||||
'no-unused-expressions': ['error', {
|
||||
allowShortCircuit: false,
|
||||
allowTernary: false,
|
||||
@@ -279,12 +348,12 @@ module.exports = {
|
||||
'no-unused-labels': 'error',
|
||||
|
||||
// disallow unnecessary .call() and .apply()
|
||||
// https://eslint.org/docs/rules/no-useless-call
|
||||
'no-useless-call': 'off',
|
||||
|
||||
// Disallow unnecessary catch clauses
|
||||
// https://eslint.org/docs/rules/no-useless-catch
|
||||
// TODO: enable, semver-major
|
||||
'no-useless-catch': 'off',
|
||||
'no-useless-catch': 'error',
|
||||
|
||||
// disallow useless string concatenation
|
||||
// https://eslint.org/docs/rules/no-useless-concat
|
||||
@@ -303,9 +372,11 @@ module.exports = {
|
||||
'no-void': 'error',
|
||||
|
||||
// disallow usage of configurable warning terms in comments: e.g. todo
|
||||
// https://eslint.org/docs/rules/no-warning-comments
|
||||
'no-warning-comments': ['off', { terms: ['todo', 'fixme', 'xxx'], location: 'start' }],
|
||||
|
||||
// disallow use of the with statement
|
||||
// https://eslint.org/docs/rules/no-with
|
||||
'no-with': 'error',
|
||||
|
||||
// require using Error objects as Promise rejection reasons
|
||||
@@ -316,7 +387,18 @@ 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,
|
||||
}],
|
||||
|
||||
// require use of the second argument for parseInt()
|
||||
// https://eslint.org/docs/rules/radix
|
||||
radix: 'error',
|
||||
|
||||
// require `await` in `async function` (note: this is a horrible rule that should never be used)
|
||||
@@ -328,6 +410,7 @@ module.exports = {
|
||||
'require-unicode-regexp': 'off',
|
||||
|
||||
// requires to declare all vars on top of their containing scope
|
||||
// https://eslint.org/docs/rules/vars-on-top
|
||||
'vars-on-top': 'error',
|
||||
|
||||
// require immediate function invocation to be wrapped in parentheses
|
||||
@@ -335,6 +418,7 @@ module.exports = {
|
||||
'wrap-iife': ['error', 'outside', { functionPrototypeMethods: false }],
|
||||
|
||||
// require or disallow Yoda conditions
|
||||
// https://eslint.org/docs/rules/yoda
|
||||
yoda: 'error'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,8 +10,7 @@ module.exports = {
|
||||
|
||||
// disallow using an async function as a Promise executor
|
||||
// https://eslint.org/docs/rules/no-async-promise-executor
|
||||
// TODO: enable, semver-major
|
||||
'no-async-promise-executor': 'off',
|
||||
'no-async-promise-executor': 'error',
|
||||
|
||||
// Disallow await inside of loops
|
||||
// https://eslint.org/docs/rules/no-await-in-loop
|
||||
@@ -27,6 +26,11 @@ module.exports = {
|
||||
// disallow use of console
|
||||
'no-console': 'warn',
|
||||
|
||||
// Disallows expressions where the operation doesn't affect the value
|
||||
// https://eslint.org/docs/rules/no-constant-binary-expression
|
||||
// TODO: semver-major, enable
|
||||
'no-constant-binary-expression': 'off',
|
||||
|
||||
// disallow use of constant expressions in conditions
|
||||
'no-constant-condition': 'warn',
|
||||
|
||||
@@ -39,6 +43,10 @@ module.exports = {
|
||||
// disallow duplicate arguments in functions
|
||||
'no-dupe-args': 'error',
|
||||
|
||||
// Disallow duplicate conditions in if-else-if chains
|
||||
// https://eslint.org/docs/rules/no-dupe-else-if
|
||||
'no-dupe-else-if': 'error',
|
||||
|
||||
// disallow duplicate keys when creating object literals
|
||||
'no-dupe-keys': 'error',
|
||||
|
||||
@@ -74,6 +82,9 @@ module.exports = {
|
||||
// disallow overwriting functions written as function declarations
|
||||
'no-func-assign': 'error',
|
||||
|
||||
// https://eslint.org/docs/rules/no-import-assign
|
||||
'no-import-assign': 'error',
|
||||
|
||||
// disallow function or variable declarations in nested blocks
|
||||
'no-inner-declarations': 'error',
|
||||
|
||||
@@ -83,14 +94,26 @@ module.exports = {
|
||||
// disallow irregular whitespace outside of strings and comments
|
||||
'no-irregular-whitespace': 'error',
|
||||
|
||||
// Disallow Number Literals That Lose Precision
|
||||
// https://eslint.org/docs/rules/no-loss-of-precision
|
||||
'no-loss-of-precision': 'error',
|
||||
|
||||
// Disallow characters which are made with multiple code points in character class syntax
|
||||
// https://eslint.org/docs/rules/no-misleading-character-class
|
||||
// TODO: enable, semver-major
|
||||
'no-misleading-character-class': 'off',
|
||||
'no-misleading-character-class': 'error',
|
||||
|
||||
// disallow the use of object properties of the global object (Math and JSON) as functions
|
||||
'no-obj-calls': 'error',
|
||||
|
||||
// Disallow new operators with global non-constructor functions
|
||||
// https://eslint.org/docs/latest/rules/no-new-native-nonconstructor
|
||||
// TODO: semver-major, enable
|
||||
'no-new-native-nonconstructor': 'off',
|
||||
|
||||
// Disallow returning values from Promise executor functions
|
||||
// https://eslint.org/docs/rules/no-promise-executor-return
|
||||
'no-promise-executor-return': 'error',
|
||||
|
||||
// disallow use of Object.prototypes builtins directly
|
||||
// https://eslint.org/docs/rules/no-prototype-builtins
|
||||
'no-prototype-builtins': 'error',
|
||||
@@ -98,6 +121,10 @@ module.exports = {
|
||||
// disallow multiple spaces in a regular expression literal
|
||||
'no-regex-spaces': 'error',
|
||||
|
||||
// Disallow returning values from setters
|
||||
// https://eslint.org/docs/rules/no-setter-return
|
||||
'no-setter-return': 'error',
|
||||
|
||||
// disallow sparse arrays
|
||||
'no-sparse-arrays': 'error',
|
||||
|
||||
@@ -112,6 +139,12 @@ module.exports = {
|
||||
// disallow unreachable statements after a return, throw, continue, or break statement
|
||||
'no-unreachable': 'error',
|
||||
|
||||
// Disallow loops with a body that allows only one iteration
|
||||
// https://eslint.org/docs/rules/no-unreachable-loop
|
||||
'no-unreachable-loop': ['error', {
|
||||
ignore: [], // WhileStatement, DoWhileStatement, ForStatement, ForInStatement, ForOfStatement
|
||||
}],
|
||||
|
||||
// disallow return/throw/break/continue inside finally blocks
|
||||
// https://eslint.org/docs/rules/no-unsafe-finally
|
||||
'no-unsafe-finally': 'error',
|
||||
@@ -119,13 +152,27 @@ module.exports = {
|
||||
// disallow negating the left operand of relational operators
|
||||
// https://eslint.org/docs/rules/no-unsafe-negation
|
||||
'no-unsafe-negation': 'error',
|
||||
|
||||
// disallow use of optional chaining in contexts where the undefined value is not allowed
|
||||
// https://eslint.org/docs/rules/no-unsafe-optional-chaining
|
||||
'no-unsafe-optional-chaining': ['error', { disallowArithmeticOperators: true }],
|
||||
|
||||
// Disallow Unused Private Class Members
|
||||
// https://eslint.org/docs/rules/no-unused-private-class-members
|
||||
// TODO: enable once eslint 7 is dropped (which is semver-major)
|
||||
'no-unused-private-class-members': 'off',
|
||||
|
||||
// Disallow useless backreferences in regular expressions
|
||||
// https://eslint.org/docs/rules/no-useless-backreference
|
||||
'no-useless-backreference': 'error',
|
||||
|
||||
// disallow negation of the left operand of an in expression
|
||||
// deprecated in favor of no-unsafe-negation
|
||||
'no-negated-in-lhs': 'off',
|
||||
|
||||
// Disallow assignments that can lead to race conditions due to usage of await or yield
|
||||
// https://eslint.org/docs/rules/require-atomic-updates
|
||||
// TODO: enable, semver-major
|
||||
// note: not enabled because it is very buggy
|
||||
'require-atomic-updates': 'off',
|
||||
|
||||
// disallow comparisons with the value NaN
|
||||
|
||||
@@ -21,9 +21,7 @@ module.exports = {
|
||||
|
||||
// require parens in arrow function arguments
|
||||
// https://eslint.org/docs/rules/arrow-parens
|
||||
'arrow-parens': ['error', 'as-needed', {
|
||||
requireForBlockBody: true,
|
||||
}],
|
||||
'arrow-parens': ['error', 'always'],
|
||||
|
||||
// require space before/after arrow function's arrow
|
||||
// https://eslint.org/docs/rules/arrow-spacing
|
||||
@@ -55,13 +53,22 @@ module.exports = {
|
||||
|
||||
// disallow importing from the same path more than once
|
||||
// https://eslint.org/docs/rules/no-duplicate-imports
|
||||
// replaced by https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md
|
||||
// replaced by https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md
|
||||
'no-duplicate-imports': 'off',
|
||||
|
||||
// disallow symbol constructor
|
||||
// https://eslint.org/docs/rules/no-new-symbol
|
||||
'no-new-symbol': 'error',
|
||||
|
||||
// Disallow specified names in exports
|
||||
// https://eslint.org/docs/rules/no-restricted-exports
|
||||
'no-restricted-exports': ['error', {
|
||||
restrictedNamedExports: [
|
||||
'default', // use `export default` to provide a default export
|
||||
'then', // this will cause tons of confusion when your module is dynamically `import()`ed, and will break in most node ESM versions
|
||||
],
|
||||
}],
|
||||
|
||||
// disallow specific imports
|
||||
// https://eslint.org/docs/rules/no-restricted-imports
|
||||
'no-restricted-imports': ['off', {
|
||||
@@ -120,7 +127,7 @@ module.exports = {
|
||||
},
|
||||
AssignmentExpression: {
|
||||
array: true,
|
||||
object: true,
|
||||
object: false,
|
||||
},
|
||||
}, {
|
||||
enforceForRenamedProperties: false,
|
||||
@@ -138,7 +145,7 @@ module.exports = {
|
||||
// https://eslint.org/docs/rules/prefer-rest-params
|
||||
'prefer-rest-params': 'error',
|
||||
|
||||
// suggest using the spread operator instead of .apply()
|
||||
// suggest using the spread syntax instead of .apply()
|
||||
// https://eslint.org/docs/rules/prefer-spread
|
||||
'prefer-spread': 'error',
|
||||
|
||||
|
||||
@@ -33,40 +33,40 @@ module.exports = {
|
||||
// Static analysis:
|
||||
|
||||
// ensure imports point to files/modules that can be resolved
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md
|
||||
'import/no-unresolved': ['error', { commonjs: true, caseSensitive: true }],
|
||||
|
||||
// ensure named imports coupled with named exports
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/named.md#when-not-to-use-it
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/named.md#when-not-to-use-it
|
||||
'import/named': 'error',
|
||||
|
||||
// ensure default import coupled with default export
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/default.md#when-not-to-use-it
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/default.md#when-not-to-use-it
|
||||
'import/default': 'off',
|
||||
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/namespace.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/namespace.md
|
||||
'import/namespace': 'off',
|
||||
|
||||
// Helpful warnings:
|
||||
|
||||
// disallow invalid exports, e.g. multiple defaults
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/export.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/export.md
|
||||
'import/export': 'error',
|
||||
|
||||
// do not allow a default import name to match a named export
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-named-as-default.md
|
||||
'import/no-named-as-default': 'error',
|
||||
|
||||
// warn on accessing default export property names that are also named exports
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default-member.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-named-as-default-member.md
|
||||
'import/no-named-as-default-member': 'error',
|
||||
|
||||
// disallow use of jsdoc-marked-deprecated imports
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-deprecated.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-deprecated.md
|
||||
'import/no-deprecated': 'off',
|
||||
|
||||
// Forbid the use of extraneous packages
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md
|
||||
// paths are treated both as absolute paths, and relative to process.cwd()
|
||||
'import/no-extraneous-dependencies': ['error', {
|
||||
devDependencies: [
|
||||
@@ -90,51 +90,53 @@ module.exports = {
|
||||
'**/Gruntfile{,.js}', // grunt config
|
||||
'**/protractor.conf.js', // protractor config
|
||||
'**/protractor.conf.*.js', // protractor config
|
||||
'**/karma.conf.js', // karma config
|
||||
'**/.eslintrc.js' // eslint config
|
||||
],
|
||||
optionalDependencies: false,
|
||||
}],
|
||||
|
||||
// Forbid mutable exports
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md
|
||||
'import/no-mutable-exports': 'error',
|
||||
|
||||
// Module systems:
|
||||
|
||||
// disallow require()
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-commonjs.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-commonjs.md
|
||||
'import/no-commonjs': 'off',
|
||||
|
||||
// disallow AMD require/define
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-amd.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-amd.md
|
||||
'import/no-amd': 'error',
|
||||
|
||||
// No Node.js builtin modules
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-nodejs-modules.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-nodejs-modules.md
|
||||
// TODO: enable?
|
||||
'import/no-nodejs-modules': 'off',
|
||||
|
||||
// Style guide:
|
||||
|
||||
// disallow non-import statements appearing before import statements
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/first.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/first.md
|
||||
'import/first': 'error',
|
||||
|
||||
// disallow non-import statements appearing before import statements
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/imports-first.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/imports-first.md
|
||||
// deprecated: use `import/first`
|
||||
'import/imports-first': 'off',
|
||||
|
||||
// disallow duplicate imports
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md
|
||||
'import/no-duplicates': 'error',
|
||||
|
||||
// disallow namespace imports
|
||||
// TODO: enable?
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-namespace.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-namespace.md
|
||||
'import/no-namespace': 'off',
|
||||
|
||||
// Ensure consistent use of file extension within the import path
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/extensions.md
|
||||
'import/extensions': ['error', 'ignorePackages', {
|
||||
js: 'never',
|
||||
mjs: 'never',
|
||||
@@ -142,62 +144,62 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// ensure absolute imports are above relative imports and that unassigned imports are ignored
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/order.md
|
||||
// TODO: enforce a stricter convention in module import order?
|
||||
'import/order': ['error', { groups: [['builtin', 'external', 'internal']] }],
|
||||
|
||||
// Require a newline after the last import/require in a group
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/newline-after-import.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/newline-after-import.md
|
||||
'import/newline-after-import': 'error',
|
||||
|
||||
// Require modules with a single export to use a default export
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md
|
||||
'import/prefer-default-export': 'error',
|
||||
|
||||
// Restrict which files can be imported in a given folder
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-restricted-paths.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-restricted-paths.md
|
||||
'import/no-restricted-paths': 'off',
|
||||
|
||||
// Forbid modules to have too many dependencies
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/max-dependencies.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/max-dependencies.md
|
||||
'import/max-dependencies': ['off', { max: 10 }],
|
||||
|
||||
// Forbid import of modules using absolute paths
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-absolute-path.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-absolute-path.md
|
||||
'import/no-absolute-path': 'error',
|
||||
|
||||
// Forbid require() calls with expressions
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-dynamic-require.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-dynamic-require.md
|
||||
'import/no-dynamic-require': 'error',
|
||||
|
||||
// prevent importing the submodules of other modules
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-internal-modules.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-internal-modules.md
|
||||
'import/no-internal-modules': ['off', {
|
||||
allow: [],
|
||||
}],
|
||||
|
||||
// Warn if a module could be mistakenly parsed as a script by a consumer
|
||||
// leveraging Unambiguous JavaScript Grammar
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/unambiguous.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/unambiguous.md
|
||||
// this should not be enabled until this proposal has at least been *presented* to TC39.
|
||||
// At the moment, it's not a thing.
|
||||
'import/unambiguous': 'off',
|
||||
|
||||
// Forbid Webpack loader syntax in imports
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-webpack-loader-syntax.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-webpack-loader-syntax.md
|
||||
'import/no-webpack-loader-syntax': 'error',
|
||||
|
||||
// Prevent unassigned imports
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unassigned-import.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-unassigned-import.md
|
||||
// importing for side effects is perfectly acceptable, if you need side effects.
|
||||
'import/no-unassigned-import': 'off',
|
||||
|
||||
// Prevent importing the default as if it were named
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-default.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-named-default.md
|
||||
'import/no-named-default': 'error',
|
||||
|
||||
// Reports if a module's default export is unnamed
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/d9b712ac7fd1fddc391f7b234827925c160d956f/docs/rules/no-anonymous-default-export.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/d9b712ac7fd1fddc391f7b234827925c160d956f/docs/rules/no-anonymous-default-export.md
|
||||
'import/no-anonymous-default-export': ['off', {
|
||||
allowArray: false,
|
||||
allowArrowFunction: false,
|
||||
@@ -208,54 +210,74 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// This rule enforces that all exports are declared at the bottom of the file.
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/98acd6afd04dcb6920b81330114e146dc8532ea4/docs/rules/exports-last.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/98acd6afd04dcb6920b81330114e146dc8532ea4/docs/rules/exports-last.md
|
||||
// TODO: enable?
|
||||
'import/exports-last': 'off',
|
||||
|
||||
// Reports when named exports are not grouped together in a single export declaration
|
||||
// or when multiple assignments to CommonJS module.exports or exports object are present
|
||||
// in a single file.
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/group-exports.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/group-exports.md
|
||||
'import/group-exports': 'off',
|
||||
|
||||
// forbid default exports. this is a terrible rule, do not use it.
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/no-default-export.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/no-default-export.md
|
||||
'import/no-default-export': 'off',
|
||||
|
||||
// Prohibit named exports. this is a terrible rule, do not use it.
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/1ec80fa35fa1819e2d35a70e68fb6a149fb57c5e/docs/rules/no-named-export.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/1ec80fa35fa1819e2d35a70e68fb6a149fb57c5e/docs/rules/no-named-export.md
|
||||
'import/no-named-export': 'off',
|
||||
|
||||
// Forbid a module from importing itself
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/no-self-import.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/no-self-import.md
|
||||
'import/no-self-import': 'error',
|
||||
|
||||
// Forbid cyclical dependencies between modules
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/d81f48a2506182738409805f5272eff4d77c9348/docs/rules/no-cycle.md
|
||||
'import/no-cycle': ['error', { maxDepth: Infinity }],
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/d81f48a2506182738409805f5272eff4d77c9348/docs/rules/no-cycle.md
|
||||
'import/no-cycle': ['error', { maxDepth: '∞' }],
|
||||
|
||||
// Ensures that there are no useless path segments
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/ebafcbf59ec9f653b2ac2a0156ca3bcba0a7cf57/docs/rules/no-useless-path-segments.md
|
||||
'import/no-useless-path-segments': 'error',
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/ebafcbf59ec9f653b2ac2a0156ca3bcba0a7cf57/docs/rules/no-useless-path-segments.md
|
||||
'import/no-useless-path-segments': ['error', { commonjs: true }],
|
||||
|
||||
// dynamic imports require a leading comment with a webpackChunkName
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/ebafcbf59ec9f653b2ac2a0156ca3bcba0a7cf57/docs/rules/dynamic-import-chunkname.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/ebafcbf59ec9f653b2ac2a0156ca3bcba0a7cf57/docs/rules/dynamic-import-chunkname.md
|
||||
'import/dynamic-import-chunkname': ['off', {
|
||||
importFunctions: [],
|
||||
webpackChunknameFormat: '[0-9a-zA-Z-_/.]+',
|
||||
}],
|
||||
|
||||
// Use this rule to prevent imports to folders in relative parent paths.
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/c34f14f67f077acd5a61b3da9c0b0de298d20059/docs/rules/no-relative-parent-imports.md
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/c34f14f67f077acd5a61b3da9c0b0de298d20059/docs/rules/no-relative-parent-imports.md
|
||||
'import/no-relative-parent-imports': 'off',
|
||||
|
||||
// Reports modules without any exports, or with unused exports
|
||||
// https://github.com/benmosher/eslint-plugin-import/blob/f63dd261809de6883b13b6b5b960e6d7f42a7813/docs/rules/no-unused-modules.md
|
||||
// TODO: enable, semver-major
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/f63dd261809de6883b13b6b5b960e6d7f42a7813/docs/rules/no-unused-modules.md
|
||||
// TODO: enable once it supports CJS
|
||||
'import/no-unused-modules': ['off', {
|
||||
ignoreExports: [],
|
||||
missingExports: true,
|
||||
unusedExports: true,
|
||||
}],
|
||||
|
||||
// Reports the use of import declarations with CommonJS exports in any module except for the main module.
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/1012eb951767279ce3b540a4ec4f29236104bb5b/docs/rules/no-import-module-exports.md
|
||||
'import/no-import-module-exports': ['error', {
|
||||
exceptions: [],
|
||||
}],
|
||||
|
||||
// Use this rule to prevent importing packages through relative paths.
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/1012eb951767279ce3b540a4ec4f29236104bb5b/docs/rules/no-relative-packages.md
|
||||
'import/no-relative-packages': 'error',
|
||||
|
||||
// enforce a consistent style for type specifiers (inline or top-level)
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/d5fc8b670dc8e6903dbb7b0894452f60c03089f5/docs/rules/consistent-type-specifier-style.md
|
||||
// TODO, semver-major: enable (just in case)
|
||||
'import/consistent-type-specifier-style': ['off', 'prefer-inline'],
|
||||
|
||||
// Reports the use of empty named import blocks.
|
||||
// https://github.com/import-js/eslint-plugin-import/blob/d5fc8b670dc8e6903dbb7b0894452f60c03089f5/docs/rules/no-empty-named-blocks.md
|
||||
// TODO, semver-minor: enable
|
||||
'import/no-empty-named-blocks': 'off',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -21,8 +21,7 @@ module.exports = {
|
||||
'brace-style': ['error', '1tbs', { allowSingleLine: true }],
|
||||
|
||||
// require camel case names
|
||||
// TODO: semver-major (eslint 5): add ignoreDestructuring: false option
|
||||
camelcase: ['error', { properties: 'never' }],
|
||||
camelcase: ['error', { properties: 'never', ignoreDestructuring: false }],
|
||||
|
||||
// enforce or disallow capitalization of the first letter of a comment
|
||||
// https://eslint.org/docs/rules/capitalized-comments
|
||||
@@ -77,6 +76,9 @@ module.exports = {
|
||||
// enforce newline at the end of file, with no multiple empty lines
|
||||
'eol-last': ['error', 'always'],
|
||||
|
||||
// https://eslint.org/docs/rules/function-call-argument-newline
|
||||
'function-call-argument-newline': ['error', 'consistent'],
|
||||
|
||||
// enforce spacing between functions and their invocations
|
||||
// https://eslint.org/docs/rules/func-call-spacing
|
||||
'func-call-spacing': ['error', 'never'],
|
||||
@@ -84,9 +86,9 @@ module.exports = {
|
||||
// requires function names to match the name of the variable or property to which they are
|
||||
// assigned
|
||||
// https://eslint.org/docs/rules/func-name-matching
|
||||
// TODO: semver-major (eslint 5): add considerPropertyDescriptor: true
|
||||
'func-name-matching': ['off', 'always', {
|
||||
includeCommonJSModuleExports: false
|
||||
includeCommonJSModuleExports: false,
|
||||
considerPropertyDescriptor: true,
|
||||
}],
|
||||
|
||||
// require function expressions to have a name
|
||||
@@ -98,13 +100,13 @@ module.exports = {
|
||||
// TODO: enable
|
||||
'func-style': ['off', 'expression'],
|
||||
|
||||
// enforce consistent line breaks inside function parentheses
|
||||
// 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', 'consistent'],
|
||||
'function-paren-newline': ['error', 'multiline-arguments'],
|
||||
|
||||
// Blacklist certain identifiers to prevent them being used
|
||||
// https://eslint.org/docs/rules/id-blacklist
|
||||
'id-blacklist': 'off',
|
||||
// disallow specified identifiers
|
||||
// https://eslint.org/docs/rules/id-denylist
|
||||
'id-denylist': 'off',
|
||||
|
||||
// this option enforces minimum and maximum identifier lengths
|
||||
// (variable names, property names etc.)
|
||||
@@ -140,7 +142,7 @@ module.exports = {
|
||||
ImportDeclaration: 1,
|
||||
flatTernaryExpressions: false,
|
||||
// list derived from https://github.com/benjamn/ast-types/blob/HEAD/def/jsx.js
|
||||
ignoredNodes: ['JSXElement', 'JSXElement > *', 'JSXAttribute', 'JSXIdentifier', 'JSXNamespacedName', 'JSXMemberExpression', 'JSXSpreadAttribute', 'JSXExpressionContainer', 'JSXOpeningElement', 'JSXClosingElement', 'JSXText', 'JSXEmptyExpression', 'JSXSpreadChild'],
|
||||
ignoredNodes: ['JSXElement', 'JSXElement > *', 'JSXAttribute', 'JSXIdentifier', 'JSXNamespacedName', 'JSXMemberExpression', 'JSXSpreadAttribute', 'JSXExpressionContainer', 'JSXOpeningElement', 'JSXClosingElement', 'JSXFragment', 'JSXOpeningFragment', 'JSXClosingFragment', 'JSXText', 'JSXEmptyExpression', 'JSXSpreadChild'],
|
||||
ignoreComments: false
|
||||
}],
|
||||
|
||||
@@ -189,6 +191,13 @@ module.exports = {
|
||||
after: 'always',
|
||||
}],
|
||||
|
||||
// Require or disallow logical assignment logical operator shorthand
|
||||
// https://eslint.org/docs/latest/rules/logical-assignment-operators
|
||||
// TODO, semver-major: enable
|
||||
'logical-assignment-operators': ['off', 'always', {
|
||||
enforceForIfStatements: true,
|
||||
}],
|
||||
|
||||
// specify the maximum depth that blocks can be nested
|
||||
'max-depth': ['off', 4],
|
||||
|
||||
@@ -285,7 +294,7 @@ module.exports = {
|
||||
// disallow un-paren'd mixes of different operators
|
||||
// https://eslint.org/docs/rules/no-mixed-operators
|
||||
'no-mixed-operators': ['error', {
|
||||
// the list of arthmetic groups disallows mixing `%` and `**`
|
||||
// the list of arithmetic groups disallows mixing `%` and `**`
|
||||
// with other arithmetic operators.
|
||||
groups: [
|
||||
['%', '**'],
|
||||
@@ -293,14 +302,10 @@ module.exports = {
|
||||
['%', '-'],
|
||||
['%', '*'],
|
||||
['%', '/'],
|
||||
['**', '+'],
|
||||
['**', '-'],
|
||||
['**', '*'],
|
||||
['**', '/'],
|
||||
['&', '|', '^', '~', '<<', '>>', '>>>'],
|
||||
['==', '!=', '===', '!==', '>', '>=', '<', '<='],
|
||||
['/', '*'],
|
||||
['&', '|', '<<', '>>', '>>>'],
|
||||
['==', '!=', '===', '!=='],
|
||||
['&&', '||'],
|
||||
['in', 'instanceof']
|
||||
],
|
||||
allowSamePrecedence: false
|
||||
}],
|
||||
@@ -312,8 +317,9 @@ module.exports = {
|
||||
// https://eslint.org/docs/rules/no-multi-assign
|
||||
'no-multi-assign': ['error'],
|
||||
|
||||
// disallow multiple empty lines and only one newline at the end
|
||||
'no-multiple-empty-lines': ['error', { max: 2, maxEOF: 0 }],
|
||||
// disallow multiple empty lines, only one newline at the end, and no new lines at the beginning
|
||||
// https://eslint.org/docs/rules/no-multiple-empty-lines
|
||||
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }],
|
||||
|
||||
// disallow negated conditions
|
||||
// https://eslint.org/docs/rules/no-negated-condition
|
||||
@@ -352,7 +358,8 @@ module.exports = {
|
||||
],
|
||||
|
||||
// disallow space between function identifier and application
|
||||
'no-spaced-func': 'error',
|
||||
// deprecated in favor of func-call-spacing
|
||||
'no-spaced-func': 'off',
|
||||
|
||||
// disallow tab characters entirely
|
||||
'no-tabs': 'error',
|
||||
@@ -422,22 +429,25 @@ module.exports = {
|
||||
'operator-linebreak': ['error', 'before', { overrides: { '=': 'none' } }],
|
||||
|
||||
// disallow padding within blocks
|
||||
// TODO, semver-major: uncomment option
|
||||
'padded-blocks': ['error', {
|
||||
blocks: 'never',
|
||||
classes: 'never',
|
||||
switches: 'never',
|
||||
// allowSingleLineBlocks: true,
|
||||
}, {
|
||||
allowSingleLineBlocks: true,
|
||||
}],
|
||||
|
||||
// Require or disallow padding lines between statements
|
||||
// https://eslint.org/docs/rules/padding-line-between-statements
|
||||
'padding-line-between-statements': 'off',
|
||||
|
||||
// Disallow the use of Math.pow in favor of the ** operator
|
||||
// https://eslint.org/docs/rules/prefer-exponentiation-operator
|
||||
'prefer-exponentiation-operator': 'error',
|
||||
|
||||
// Prefer use of an object spread over Object.assign
|
||||
// https://eslint.org/docs/rules/prefer-object-spread
|
||||
// TODO: semver-major (eslint 5): enable
|
||||
'prefer-object-spread': 'off',
|
||||
'prefer-object-spread': 'error',
|
||||
|
||||
// require quotes around object literal property names
|
||||
// https://eslint.org/docs/rules/quote-props.html
|
||||
@@ -497,11 +507,11 @@ module.exports = {
|
||||
'spaced-comment': ['error', 'always', {
|
||||
line: {
|
||||
exceptions: ['-', '+'],
|
||||
markers: ['=', '!'], // space here to support sprockets directives
|
||||
markers: ['=', '!', '/'], // space here to support sprockets directives, slash for TS /// comments
|
||||
},
|
||||
block: {
|
||||
exceptions: ['-', '+'],
|
||||
markers: ['=', '!'], // space here to support sprockets directives
|
||||
markers: ['=', '!', ':', '::'], // space here to support sprockets directives and flow comment types
|
||||
balanced: true,
|
||||
}
|
||||
}],
|
||||
|
||||
@@ -16,7 +16,22 @@ module.exports = {
|
||||
'no-label-var': 'error',
|
||||
|
||||
// disallow specific globals
|
||||
'no-restricted-globals': ['error', 'isFinite', 'isNaN'].concat(confusingBrowserGlobals),
|
||||
'no-restricted-globals': [
|
||||
'error',
|
||||
{
|
||||
name: 'isFinite',
|
||||
message:
|
||||
'Use Number.isFinite instead https://github.com/airbnb/javascript#standard-library--isfinite',
|
||||
},
|
||||
{
|
||||
name: 'isNaN',
|
||||
message:
|
||||
'Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnan',
|
||||
},
|
||||
].concat(confusingBrowserGlobals.map((g) => ({
|
||||
name: g,
|
||||
message: `Use window.${g} instead. https://github.com/facebook/create-react-app/blob/HEAD/packages/confusing-browser-globals/README.md`,
|
||||
}))),
|
||||
|
||||
// disallow declaration of variables already declared in the outer scope
|
||||
'no-shadow': 'error',
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
/* eslint
|
||||
strict: 0,
|
||||
global-require: 0,
|
||||
*/
|
||||
/* eslint strict: 0, global-require: 0 */
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@ import index from '..';
|
||||
|
||||
const files = { ...{ index } }; // object spread is to test parsing
|
||||
|
||||
fs.readdirSync(path.join(__dirname, '../rules')).forEach((name) => {
|
||||
const rulesDir = path.join(__dirname, '../rules');
|
||||
fs.readdirSync(rulesDir).forEach((name) => {
|
||||
// eslint-disable-next-line import/no-dynamic-require
|
||||
files[name] = require(`../rules/${name}`); // eslint-disable-line global-require
|
||||
files[name] = require(path.join(rulesDir, name)); // eslint-disable-line global-require
|
||||
});
|
||||
|
||||
Object.keys(files).forEach((
|
||||
@@ -26,7 +27,7 @@ Object.keys(files).forEach((
|
||||
|
||||
// scan rules for react/ and fail if any exist
|
||||
const reactRuleIds = Object.keys(config.rules)
|
||||
.filter(ruleId => ruleId.indexOf('react/') === 0);
|
||||
.filter((ruleId) => ruleId.indexOf('react/') === 0);
|
||||
t.deepEquals(reactRuleIds, [], 'there are no react/ rules');
|
||||
});
|
||||
});
|
||||
|
||||
49
packages/eslint-config-airbnb-base/whitespace-async.js
Executable file
49
packages/eslint-config-airbnb-base/whitespace-async.js
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { isArray } = Array;
|
||||
const { entries } = Object;
|
||||
const { ESLint } = require('eslint');
|
||||
|
||||
const baseConfig = require('.');
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
|
||||
function getSeverity(ruleConfig) {
|
||||
if (isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
async function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = { ...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 (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,78 +1,61 @@
|
||||
const assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
const CLIEngine = require('eslint').CLIEngine;
|
||||
/* eslint global-require: 0 */
|
||||
|
||||
const baseConfig = require('.');
|
||||
const { isArray } = Array;
|
||||
const { entries } = Object;
|
||||
const { CLIEngine } = require('eslint');
|
||||
|
||||
function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = assign({}, config);
|
||||
const cli = new CLIEngine({ baseConfig: config, useEslintrc: false });
|
||||
const baseRules = cli.getConfigForFile('./').rules;
|
||||
if (CLIEngine) {
|
||||
/* eslint no-inner-declarations: 0 */
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
entries(baseRules).forEach((rule) => {
|
||||
const ruleName = rule[0];
|
||||
const ruleConfig = rule[1];
|
||||
const baseConfig = require('.');
|
||||
|
||||
if (rulesToError.indexOf(ruleName) === -1) {
|
||||
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';
|
||||
}
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
|
||||
function getSeverity(ruleConfig) {
|
||||
if (isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
});
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
return errorsOnly;
|
||||
function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = { ...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 (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');
|
||||
|
||||
// NOTE: ESLint adds runtime statistics to the output (so it's no longer JSON) if TIMING is set
|
||||
module.exports = JSON.parse(String(execSync(path.join(__dirname, 'whitespace-async.js'), {
|
||||
env: {
|
||||
...process.env,
|
||||
TIMING: undefined,
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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'
|
||||
];
|
||||
@@ -4,7 +4,5 @@
|
||||
// disable requiring trailing commas because it might be nice to revert to
|
||||
// being JSON at some point, and I don't want to make big changes now.
|
||||
"comma-dangle": 0,
|
||||
// we support node 4
|
||||
"prefer-destructuring": 0,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,3 +1,94 @@
|
||||
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)
|
||||
- [patch] Fix ignoreNonDOM typo in jsx-a11y/aria-role rule (#2318)
|
||||
- [patch] Fixed `handle` and `on` ordering in `sort-comp` rule (#2287)
|
||||
- [deps] update `eslint-plugin-jsx-a11y`, `eslint-plugin-react`
|
||||
- [deps] update `eslint-config-airbnb-base`, `object.assign`
|
||||
- [dev deps] update `@babel/runtime`, `eslint-find-rules`, `eslint-plugin-import`, `eslint-plugin-jsx-a11y`, `eslint-plugin-react`
|
||||
|
||||
18.2.0 / 2020-06-18
|
||||
==================
|
||||
- [new] add `eslint` `v7` (#2240)
|
||||
- [minor] Allow using `eslint-plugin-react-hooks` v3 and v4 (#2235, #2207)
|
||||
- [minor] Fix typo in no-multiple-empty-lines rule (#2168)
|
||||
- [patch] set `explicitSpread` to ignore for `react/jsx-props-no-spreading` (#2237)
|
||||
- [patch] relax `eslint-plugin-react-hooks` down to v2.3, due to a controversial change in v2.5
|
||||
- [readme] fix typo (#2194)
|
||||
- [deps] update `eslint-config-airbnb-base`, `eslint-plugin-jsx-a11y`, `eslint-plugin-import`, `eslint-plugin-react`, `babel-preset-airbnb`, `eslint-find-rules`, `in-publish`, `tape`, `object.entries`
|
||||
- [tests] fix for eslint 7
|
||||
|
||||
18.1.0 / 2020-03-12
|
||||
==================
|
||||
- [minor] Support eslint-plugin-react-hooks@2 (#2090)
|
||||
- [minor] add new disabled rules, update eslint
|
||||
- [fix] `whitespace`: only set erroring rules to "warn"
|
||||
- [patch] Remove duplicate `componentDidCatch` (#2108)
|
||||
- [patch] Add `static-variables` to `sort-comp` rule (#2109)
|
||||
- [readme] clarify hooks section in readme (#2074)
|
||||
- [deps] update `eslint`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, `eslint-config-airbnb-base`, `eslint-plugin-import`, `object.entries`
|
||||
- [dev deps] update `@babel/runtime`, `babel-preset-airbnb`, `safe-publish-latest`, `tape`
|
||||
- [tests] re-enable eslint rule `prefer-destructuring` internally (#2110)
|
||||
- [tests] fix eslint errors from c66cfc3 (#2112)
|
||||
|
||||
18.0.1 / 2019-08-13
|
||||
==================
|
||||
- [patch] `react/state-in-constructor`: fix incorrect configuration
|
||||
|
||||
18.0.0 / 2019-08-10
|
||||
==================
|
||||
- [breaking] add eslint v6, drop eslint v4
|
||||
- [deps] [breaking] update `eslint-config-airbnb-base`, `eslint-plugin-react`, `eslint-find-rules`, `eslint-plugin-import`
|
||||
- [breaking] Remove rules/strict from 'extends' (#1962)
|
||||
- [breaking] set react version to "detect"
|
||||
- [breaking] disable `label-has-for`; enable `control-has-associated-label`
|
||||
- [breaking] enable `react/jsx-props-no-spreading`
|
||||
- [breaking] enable `react/jsx-fragments`
|
||||
- [minor] enable `react/static-property-placement`
|
||||
- [minor] enable `react/state-in-constructor`
|
||||
- [minor] enable `react/jsx-curly-newline`
|
||||
- [react] Add missing/unsafe lifecycle methods to react/sort-comp rule (#2043)
|
||||
- [react] add componentDidCatch to lifecycle for react/sort-comp (#2060)
|
||||
- [react] add `react-hooks` plugin (#2022)
|
||||
- [dev deps] update babel-related deps to latest
|
||||
- [tests] only run tests in non-lint per-package travis job
|
||||
- [tests] use `eclint` instead of `editorconfig-tools`
|
||||
- [meta] add disabled config for new react and a11y rules
|
||||
|
||||
|
||||
17.1.1 / 2019-07-01
|
||||
==================
|
||||
- [patch] Turn off `react/no-multi-comp` (#2006)
|
||||
@@ -376,11 +467,11 @@
|
||||
[space-in-parens]: https://eslint.org/docs/rules/space-in-parens
|
||||
[template-curly-spacing]: https://eslint.org/docs/rules/template-curly-spacing
|
||||
|
||||
[react/jsx-space-before-closing]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-space-before-closing.md
|
||||
[react/sort-comp]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md
|
||||
[react/display-name]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md
|
||||
[react/jsx-no-bind]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md
|
||||
[react/no-is-mounted]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md
|
||||
[react/prefer-es6-class]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md
|
||||
[react/jsx-quotes]: https://github.com/yannickcr/eslint-plugin-react/blob/f817e37beddddc84b4788969f07c524fa7f0823b/docs/rules/jsx-quotes.md
|
||||
[react/prefer-stateless-function]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md
|
||||
[react/jsx-space-before-closing]: https://github.com/jsx-eslint/eslint-plugin-react/blob/HEAD/docs/rules/jsx-space-before-closing.md
|
||||
[react/sort-comp]: https://github.com/jsx-eslint/eslint-plugin-react/blob/HEAD/docs/rules/sort-comp.md
|
||||
[react/display-name]: https://github.com/jsx-eslint/eslint-plugin-react/blob/HEAD/docs/rules/display-name.md
|
||||
[react/jsx-no-bind]: https://github.com/jsx-eslint/eslint-plugin-react/blob/HEAD/docs/rules/jsx-no-bind.md
|
||||
[react/no-is-mounted]: https://github.com/jsx-eslint/eslint-plugin-react/blob/HEAD/docs/rules/no-is-mounted.md
|
||||
[react/prefer-es6-class]: https://github.com/jsx-eslint/eslint-plugin-react/blob/HEAD/docs/rules/prefer-es6-class.md
|
||||
[react/jsx-quotes]: https://github.com/jsx-eslint/eslint-plugin-react/blob/f817e37beddddc84b4788969f07c524fa7f0823b/docs/rules/jsx-quotes.md
|
||||
[react/prefer-stateless-function]: https://github.com/jsx-eslint/eslint-plugin-react/blob/HEAD/docs/rules/prefer-stateless-function.md
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# eslint-config-airbnb
|
||||
|
||||
[](http://badge.fury.io/js/eslint-config-airbnb)
|
||||
[](https://badge.fury.io/js/eslint-config-airbnb)
|
||||
|
||||
This package provides Airbnb's .eslintrc as an extensible shared config.
|
||||
|
||||
@@ -10,7 +10,9 @@ We export three ESLint configurations for your usage.
|
||||
|
||||
### eslint-config-airbnb
|
||||
|
||||
Our default export contains all of our ESLint rules, including ECMAScript 6+ and React. It requires `eslint`, `eslint-plugin-import`, `eslint-plugin-react`, and `eslint-plugin-jsx-a11y`. If you don't need React, see [eslint-config-airbnb-base](https://npmjs.com/eslint-config-airbnb-base).
|
||||
Our default export contains most of our ESLint rules, including ECMAScript 6+ and React. It requires `eslint`, `eslint-plugin-import`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, and `eslint-plugin-jsx-a11y`. Note that it does not enable our React Hooks rules. To enable those, see the [`eslint-config-airbnb/hooks` section](#eslint-config-airbnbhooks).
|
||||
|
||||
If you don't need React, see [eslint-config-airbnb-base](https://npmjs.com/eslint-config-airbnb-base).
|
||||
|
||||
1. Install the correct versions of each package, which are listed by the command:
|
||||
|
||||
@@ -39,7 +41,7 @@ Our default export contains all of our ESLint rules, including ECMAScript 6+ and
|
||||
Which produces and runs a command like:
|
||||
|
||||
```sh
|
||||
npm install --save-dev eslint-config-airbnb eslint@^#.#.# eslint-plugin-jsx-a11y@^#.#.# eslint-plugin-import@^#.#.# eslint-plugin-react@^#.#.#
|
||||
npm install --save-dev eslint-config-airbnb eslint@^#.#.# eslint-plugin-jsx-a11y@^#.#.# eslint-plugin-import@^#.#.# eslint-plugin-react@^#.#.# eslint-plugin-react-hooks@^#.#.#
|
||||
```
|
||||
|
||||
If using **npm < 5**, Windows users can either install all the peer dependencies manually, or use the [install-peerdeps](https://github.com/nathanhleung/install-peerdeps) cli tool.
|
||||
@@ -51,10 +53,14 @@ Our default export contains all of our ESLint rules, including ECMAScript 6+ and
|
||||
The cli will produce and run a command like:
|
||||
|
||||
```sh
|
||||
npm install --save-dev eslint-config-airbnb eslint@^#.#.# eslint-plugin-jsx-a11y@^#.#.# eslint-plugin-import@^#.#.# eslint-plugin-react@^#.#.#
|
||||
npm install --save-dev eslint-config-airbnb eslint@^#.#.# eslint-plugin-jsx-a11y@^#.#.# eslint-plugin-import@^#.#.# eslint-plugin-react@^#.#.# eslint-plugin-react-hooks@^#.#.#
|
||||
```
|
||||
|
||||
2. Add `"extends": "airbnb"` to your .eslintrc
|
||||
2. Add `"extends": "airbnb"` to your `.eslintrc`
|
||||
|
||||
### eslint-config-airbnb/hooks
|
||||
|
||||
This entry point enables the linting rules for React hooks (requires v16.8+). To use, add `"extends": ["airbnb", "airbnb/hooks"]` to your `.eslintrc`.
|
||||
|
||||
### eslint-config-airbnb/whitespace
|
||||
|
||||
|
||||
6
packages/eslint-config-airbnb/hooks.js
Normal file
6
packages/eslint-config-airbnb/hooks.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'./rules/react-hooks.js',
|
||||
].map(require.resolve),
|
||||
rules: {}
|
||||
};
|
||||
@@ -1,7 +1,6 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint-config-airbnb-base',
|
||||
'eslint-config-airbnb-base/rules/strict',
|
||||
'./rules/react',
|
||||
'./rules/react-a11y',
|
||||
].map(require.resolve),
|
||||
|
||||
@@ -1,19 +1,31 @@
|
||||
{
|
||||
"name": "eslint-config-airbnb",
|
||||
"version": "17.1.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": "editorconfig-tools check * rules/* test/*",
|
||||
"prelint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git')",
|
||||
"lint": "eslint .",
|
||||
"pretests-only": "node ./test/requires",
|
||||
"tests-only": "babel-tape-runner ./test/test-*.js",
|
||||
"prepublish": "(in-install || eslint-find-rules --unused) && (not-in-publish || npm test) && safe-publish-latest",
|
||||
"prepublishOnly": "eslint-find-rules --unused && npm test && safe-publish-latest",
|
||||
"prepublish": "not-in-publish || npm run prepublishOnly",
|
||||
"pretest": "npm run --silent lint",
|
||||
"test": "npm run --silent tests-only",
|
||||
"link:eslint": "cd node_modules/eslint && npm link --production && cd -",
|
||||
"pretravis": "npm run link:eslint && cd ../eslint-config-airbnb-base && npm link eslint && npm install && npm link && cd - && npm link --no-save eslint-config-airbnb-base",
|
||||
"travis": "npm run --silent test",
|
||||
"pretravis": "npm run link:eslint && cd ../eslint-config-airbnb-base && npm link --no-save eslint && npm install && npm link && cd - && npm link --no-save eslint-config-airbnb-base",
|
||||
"travis": "npm run --silent tests-only",
|
||||
"posttravis": "npm unlink --no-save eslint-config-airbnb-base eslint >/dev/null &"
|
||||
},
|
||||
"repository": {
|
||||
@@ -54,31 +66,32 @@
|
||||
},
|
||||
"homepage": "https://github.com/airbnb/javascript",
|
||||
"dependencies": {
|
||||
"eslint-config-airbnb-base": "^13.2.0",
|
||||
"object.assign": "^4.1.0",
|
||||
"object.entries": "^1.1.0"
|
||||
"eslint-config-airbnb-base": "^15.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-airbnb": "^2.6.0",
|
||||
"babel-tape-runner": "^2.0.1",
|
||||
"editorconfig-tools": "^0.1.1",
|
||||
"eslint": "^4.19.1 || ^5.3.0",
|
||||
"eslint-find-rules": "^3.3.1",
|
||||
"eslint-plugin-import": "^2.18.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.2.3",
|
||||
"eslint-plugin-react": "^7.14.2",
|
||||
"in-publish": "^2.0.0",
|
||||
"@babel/runtime": "^7.25.6",
|
||||
"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.1.0",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.0",
|
||||
"eslint-plugin-react": "^7.36.1",
|
||||
"eslint-plugin-react-hooks": "^5.1.0",
|
||||
"in-publish": "^2.0.1",
|
||||
"react": ">= 0.13.0",
|
||||
"safe-publish-latest": "^1.1.2",
|
||||
"tape": "^4.11.0"
|
||||
"safe-publish-latest": "^2.0.0",
|
||||
"tape": "^5.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^4.19.1 || ^5.3.0",
|
||||
"eslint-plugin-import": "^2.18.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.2.3",
|
||||
"eslint-plugin-react": "^7.14.2"
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.0",
|
||||
"eslint-plugin-react": "^7.36.1",
|
||||
"eslint-plugin-react-hooks": "^5.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
"node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
321
packages/eslint-config-airbnb/rules/react-a11y.js
vendored
321
packages/eslint-config-airbnb/rules/react-a11y.js
vendored
@@ -11,29 +11,13 @@ module.exports = {
|
||||
},
|
||||
|
||||
rules: {
|
||||
// Enforce that anchors have content
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-has-content.md
|
||||
'jsx-a11y/anchor-has-content': ['error', { components: [] }],
|
||||
|
||||
// Require ARIA roles to be valid and non-abstract
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md
|
||||
'jsx-a11y/aria-role': ['error', { ignoreNonDom: false }],
|
||||
|
||||
// Enforce all aria-* props are valid.
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-props.md
|
||||
'jsx-a11y/aria-props': 'error',
|
||||
|
||||
// Enforce ARIA state and property values are valid.
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-proptypes.md
|
||||
'jsx-a11y/aria-proptypes': 'error',
|
||||
|
||||
// Enforce that elements that do not support ARIA roles, states, and
|
||||
// properties do not have those attributes.
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-unsupported-elements.md
|
||||
'jsx-a11y/aria-unsupported-elements': 'error',
|
||||
// ensure emoji are accessible
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/accessible-emoji.md
|
||||
// disabled; rule is deprecated
|
||||
'jsx-a11y/accessible-emoji': 'off',
|
||||
|
||||
// Enforce that all elements that require alternative text have meaningful information
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md
|
||||
'jsx-a11y/alt-text': ['error', {
|
||||
elements: ['img', 'object', 'area', 'input[type="image"]'],
|
||||
img: [],
|
||||
@@ -42,22 +26,100 @@ module.exports = {
|
||||
'input[type="image"]': [],
|
||||
}],
|
||||
|
||||
// Prevent img alt text from containing redundant words like "image", "picture", or "photo"
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md
|
||||
'jsx-a11y/img-redundant-alt': 'error',
|
||||
// Enforce that anchors have content
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-has-content.md
|
||||
'jsx-a11y/anchor-has-content': ['error', { components: [] }],
|
||||
|
||||
// require that JSX labels use "htmlFor"
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/label-has-for.md
|
||||
'jsx-a11y/label-has-for': ['error', {
|
||||
components: [],
|
||||
required: {
|
||||
every: ['nesting', 'id'],
|
||||
},
|
||||
allowChildren: false,
|
||||
// ensure <a> tags are valid
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/0745af376cdc8686d85a361ce36952b1fb1ccf6e/docs/rules/anchor-is-valid.md
|
||||
'jsx-a11y/anchor-is-valid': ['error', {
|
||||
components: ['Link'],
|
||||
specialLink: ['to'],
|
||||
aspects: ['noHref', 'invalidHref', 'preferButton'],
|
||||
}],
|
||||
|
||||
// elements with aria-activedescendant must be tabbable
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-activedescendant-has-tabindex.md
|
||||
'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
|
||||
|
||||
// Enforce all aria-* props are valid.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-props.md
|
||||
'jsx-a11y/aria-props': 'error',
|
||||
|
||||
// Enforce ARIA state and property values are valid.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-proptypes.md
|
||||
'jsx-a11y/aria-proptypes': 'error',
|
||||
|
||||
// Require ARIA roles to be valid and non-abstract
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md
|
||||
'jsx-a11y/aria-role': ['error', { ignoreNonDOM: false }],
|
||||
|
||||
// Enforce that elements that do not support ARIA roles, states, and
|
||||
// properties do not have those attributes.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-unsupported-elements.md
|
||||
'jsx-a11y/aria-unsupported-elements': 'error',
|
||||
|
||||
// Ensure the autocomplete attribute is correct and suitable for the form field it is used with
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/29c68596b15c4ff0a40daae6d4a2670e36e37d35/docs/rules/autocomplete-valid.md
|
||||
'jsx-a11y/autocomplete-valid': ['off', {
|
||||
inputComponents: [],
|
||||
}],
|
||||
|
||||
// require onClick be accompanied by onKeyUp/onKeyDown/onKeyPress
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/click-events-have-key-events.md
|
||||
'jsx-a11y/click-events-have-key-events': 'error',
|
||||
|
||||
// Enforce that a control (an interactive element) has a text label.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/control-has-associated-label.md
|
||||
'jsx-a11y/control-has-associated-label': ['error', {
|
||||
labelAttributes: ['label'],
|
||||
controlComponents: [],
|
||||
ignoreElements: [
|
||||
'audio',
|
||||
'canvas',
|
||||
'embed',
|
||||
'input',
|
||||
'textarea',
|
||||
'tr',
|
||||
'video',
|
||||
],
|
||||
ignoreRoles: [
|
||||
'grid',
|
||||
'listbox',
|
||||
'menu',
|
||||
'menubar',
|
||||
'radiogroup',
|
||||
'row',
|
||||
'tablist',
|
||||
'toolbar',
|
||||
'tree',
|
||||
'treegrid',
|
||||
],
|
||||
depth: 5,
|
||||
}],
|
||||
|
||||
// ensure <hX> tags have content and are not aria-hidden
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/heading-has-content.md
|
||||
'jsx-a11y/heading-has-content': ['error', { components: [''] }],
|
||||
|
||||
// require HTML elements to have a "lang" prop
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/html-has-lang.md
|
||||
'jsx-a11y/html-has-lang': 'error',
|
||||
|
||||
// ensure iframe elements have a unique title
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/iframe-has-title.md
|
||||
'jsx-a11y/iframe-has-title': 'error',
|
||||
|
||||
// Prevent img alt text from containing redundant words like "image", "picture", or "photo"
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md
|
||||
'jsx-a11y/img-redundant-alt': 'error',
|
||||
|
||||
// Elements with an interactive role and interaction handlers must be focusable
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/interactive-supports-focus.md
|
||||
'jsx-a11y/interactive-supports-focus': 'error',
|
||||
|
||||
// Enforce that a label tag has a text label and an associated control.
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/b800f40a2a69ad48015ae9226fbe879f946757ed/docs/rules/label-has-associated-control.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/b800f40a2a69ad48015ae9226fbe879f946757ed/docs/rules/label-has-associated-control.md
|
||||
'jsx-a11y/label-has-associated-control': ['error', {
|
||||
labelComponents: [],
|
||||
labelAttributes: [],
|
||||
@@ -66,77 +128,44 @@ module.exports = {
|
||||
depth: 25
|
||||
}],
|
||||
|
||||
// require HTML element's lang prop to be valid
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/lang.md
|
||||
'jsx-a11y/lang': 'error',
|
||||
|
||||
// media elements must have captions
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/media-has-caption.md
|
||||
'jsx-a11y/media-has-caption': ['error', {
|
||||
audio: [],
|
||||
video: [],
|
||||
track: [],
|
||||
}],
|
||||
|
||||
// require that mouseover/out come with focus/blur, for keyboard-only users
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/mouse-events-have-key-events.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/mouse-events-have-key-events.md
|
||||
'jsx-a11y/mouse-events-have-key-events': 'error',
|
||||
|
||||
// Prevent use of `accessKey`
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md
|
||||
'jsx-a11y/no-access-key': 'error',
|
||||
|
||||
// require onBlur instead of onChange
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-onchange.md
|
||||
'jsx-a11y/no-onchange': 'off',
|
||||
|
||||
// Elements with an interactive role and interaction handlers must be focusable
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/interactive-supports-focus.md
|
||||
'jsx-a11y/interactive-supports-focus': 'error',
|
||||
|
||||
// Enforce that elements with ARIA roles must have all required attributes
|
||||
// for that role.
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-has-required-aria-props.md
|
||||
'jsx-a11y/role-has-required-aria-props': 'error',
|
||||
|
||||
// Enforce that elements with explicit or implicit roles defined contain
|
||||
// only aria-* properties supported by that role.
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-supports-aria-props.md
|
||||
'jsx-a11y/role-supports-aria-props': 'error',
|
||||
|
||||
// Enforce tabIndex value is not greater than zero.
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/tabindex-no-positive.md
|
||||
'jsx-a11y/tabindex-no-positive': 'error',
|
||||
|
||||
// ensure <hX> tags have content and are not aria-hidden
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/heading-has-content.md
|
||||
'jsx-a11y/heading-has-content': ['error', { components: [''] }],
|
||||
|
||||
// require HTML elements to have a "lang" prop
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/html-has-lang.md
|
||||
'jsx-a11y/html-has-lang': 'error',
|
||||
|
||||
// require HTML element's lang prop to be valid
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/lang.md
|
||||
'jsx-a11y/lang': 'error',
|
||||
// prohibit autoFocus prop
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md
|
||||
'jsx-a11y/no-autofocus': ['error', { ignoreNonDOM: true }],
|
||||
|
||||
// prevent distracting elements, like <marquee> and <blink>
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-distracting-elements.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-distracting-elements.md
|
||||
'jsx-a11y/no-distracting-elements': ['error', {
|
||||
elements: ['marquee', 'blink'],
|
||||
}],
|
||||
|
||||
// only allow <th> to have the "scope" attr
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/scope.md
|
||||
'jsx-a11y/scope': 'error',
|
||||
|
||||
// require onClick be accompanied by onKeyUp/onKeyDown/onKeyPress
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/click-events-have-key-events.md
|
||||
'jsx-a11y/click-events-have-key-events': 'error',
|
||||
|
||||
// Enforce that DOM elements without semantic behavior not have interaction handlers
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-static-element-interactions.md
|
||||
'jsx-a11y/no-static-element-interactions': ['error', {
|
||||
handlers: [
|
||||
'onClick',
|
||||
'onMouseDown',
|
||||
'onMouseUp',
|
||||
'onKeyPress',
|
||||
'onKeyDown',
|
||||
'onKeyUp',
|
||||
]
|
||||
// WAI-ARIA roles should not be used to convert an interactive element to non-interactive
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-interactive-element-to-noninteractive-role.md
|
||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': ['error', {
|
||||
tr: ['none', 'presentation'],
|
||||
}],
|
||||
|
||||
// A non-interactive element does not support event handlers (mouse and key handlers)
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-noninteractive-element-interactions.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-noninteractive-element-interactions.md
|
||||
'jsx-a11y/no-noninteractive-element-interactions': ['error', {
|
||||
handlers: [
|
||||
'onClick',
|
||||
@@ -148,42 +177,8 @@ module.exports = {
|
||||
]
|
||||
}],
|
||||
|
||||
// ensure emoji are accessible
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/accessible-emoji.md
|
||||
'jsx-a11y/accessible-emoji': 'error',
|
||||
|
||||
// elements with aria-activedescendant must be tabbable
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-activedescendant-has-tabindex.md
|
||||
'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
|
||||
|
||||
// ensure iframe elements have a unique title
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/iframe-has-title.md
|
||||
'jsx-a11y/iframe-has-title': 'error',
|
||||
|
||||
// prohibit autoFocus prop
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md
|
||||
'jsx-a11y/no-autofocus': ['error', { ignoreNonDOM: true }],
|
||||
|
||||
// ensure HTML elements do not specify redundant ARIA roles
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-redundant-roles.md
|
||||
'jsx-a11y/no-redundant-roles': 'error',
|
||||
|
||||
// media elements must have captions
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/media-has-caption.md
|
||||
'jsx-a11y/media-has-caption': ['error', {
|
||||
audio: [],
|
||||
video: [],
|
||||
track: [],
|
||||
}],
|
||||
|
||||
// WAI-ARIA roles should not be used to convert an interactive element to non-interactive
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-interactive-element-to-noninteractive-role.md
|
||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': ['error', {
|
||||
tr: ['none', 'presentation'],
|
||||
}],
|
||||
|
||||
// WAI-ARIA roles should not be used to convert a non-interactive element to interactive
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-noninteractive-element-to-interactive-role.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-noninteractive-element-to-interactive-role.md
|
||||
'jsx-a11y/no-noninteractive-element-to-interactive-role': ['error', {
|
||||
ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
|
||||
ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
|
||||
@@ -193,18 +188,82 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Tab key navigation should be limited to elements on the page that can be interacted with.
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-noninteractive-tabindex.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-noninteractive-tabindex.md
|
||||
'jsx-a11y/no-noninteractive-tabindex': ['error', {
|
||||
tags: [],
|
||||
roles: ['tabpanel'],
|
||||
allowExpressionValues: true,
|
||||
}],
|
||||
|
||||
// ensure <a> tags are valid
|
||||
// https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/0745af376cdc8686d85a361ce36952b1fb1ccf6e/docs/rules/anchor-is-valid.md
|
||||
'jsx-a11y/anchor-is-valid': ['error', {
|
||||
components: ['Link'],
|
||||
specialLink: ['to'],
|
||||
aspects: ['noHref', 'invalidHref', 'preferButton'],
|
||||
// require onBlur instead of onChange
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-onchange.md
|
||||
'jsx-a11y/no-onchange': 'off',
|
||||
|
||||
// ensure HTML elements do not specify redundant ARIA roles
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-redundant-roles.md
|
||||
'jsx-a11y/no-redundant-roles': ['error', {
|
||||
nav: ['navigation'],
|
||||
}],
|
||||
|
||||
// Enforce that DOM elements without semantic behavior not have interaction handlers
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-static-element-interactions.md
|
||||
'jsx-a11y/no-static-element-interactions': ['error', {
|
||||
handlers: [
|
||||
'onClick',
|
||||
'onMouseDown',
|
||||
'onMouseUp',
|
||||
'onKeyPress',
|
||||
'onKeyDown',
|
||||
'onKeyUp',
|
||||
]
|
||||
}],
|
||||
|
||||
// Enforce that elements with ARIA roles must have all required attributes
|
||||
// for that role.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-has-required-aria-props.md
|
||||
'jsx-a11y/role-has-required-aria-props': 'error',
|
||||
|
||||
// Enforce that elements with explicit or implicit roles defined contain
|
||||
// only aria-* properties supported by that role.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-supports-aria-props.md
|
||||
'jsx-a11y/role-supports-aria-props': 'error',
|
||||
|
||||
// only allow <th> to have the "scope" attr
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/scope.md
|
||||
'jsx-a11y/scope': 'error',
|
||||
|
||||
// Enforce tabIndex value is not greater than zero.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/tabindex-no-positive.md
|
||||
'jsx-a11y/tabindex-no-positive': 'error',
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Rules that no longer exist in eslint-plugin-jsx-a11y
|
||||
// ----------------------------------------------------
|
||||
|
||||
// require that JSX labels use "htmlFor"
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/label-has-for.md
|
||||
// deprecated: replaced by `label-has-associated-control` rule
|
||||
'jsx-a11y/label-has-for': ['off', {
|
||||
components: [],
|
||||
required: {
|
||||
every: ['nesting', 'id'],
|
||||
},
|
||||
allowChildren: false,
|
||||
}],
|
||||
|
||||
// Ensures anchor text is not ambiguous
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/93f78856655696a55309440593e0948c6fb96134/docs/rules/anchor-ambiguous-text.md
|
||||
// TODO: semver-major, enable
|
||||
'jsx-a11y/anchor-ambiguous-text': 'off',
|
||||
|
||||
// Enforce that aria-hidden="true" is not set on focusable elements.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/93f78856655696a55309440593e0948c6fb96134/docs/rules/no-aria-hidden-on-focusable.md
|
||||
// TODO: semver-major, enable
|
||||
'jsx-a11y/no-aria-hidden-on-focusable': 'off',
|
||||
|
||||
// Enforces using semantic DOM elements over the ARIA role property.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/93f78856655696a55309440593e0948c6fb96134/docs/rules/prefer-tag-over-role.md
|
||||
// TODO: semver-major, enable
|
||||
'jsx-a11y/prefer-tag-over-role': 'off',
|
||||
},
|
||||
};
|
||||
|
||||
21
packages/eslint-config-airbnb/rules/react-hooks.js
vendored
Normal file
21
packages/eslint-config-airbnb/rules/react-hooks.js
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
'react-hooks',
|
||||
],
|
||||
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
|
||||
rules: {
|
||||
// Enforce Rules of Hooks
|
||||
// https://github.com/facebook/react/blob/c11015ff4f610ac2924d1fc6d569a17657a404fd/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
|
||||
// Verify the list of the dependencies for Hooks like useEffect and similar
|
||||
// https://github.com/facebook/react/blob/1204c789776cb01fbaf3e9f032e7e2ba85a44137/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
|
||||
'react-hooks/exhaustive-deps': 'error',
|
||||
},
|
||||
};
|
||||
305
packages/eslint-config-airbnb/rules/react.js
vendored
305
packages/eslint-config-airbnb/rules/react.js
vendored
@@ -1,4 +1,3 @@
|
||||
const assign = require('object.assign');
|
||||
const baseStyleRules = require('eslint-config-airbnb-base/rules/style').rules;
|
||||
|
||||
const dangleRules = baseStyleRules['no-underscore-dangle'];
|
||||
@@ -15,11 +14,12 @@ module.exports = {
|
||||
},
|
||||
|
||||
// View link below for react rules documentation
|
||||
// https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react#list-of-supported-rules
|
||||
rules: {
|
||||
'no-underscore-dangle': [dangleRules[0], assign({}, dangleRules[1], {
|
||||
'no-underscore-dangle': [dangleRules[0], {
|
||||
...dangleRules[1],
|
||||
allow: dangleRules[1].allow.concat(['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__']),
|
||||
})],
|
||||
}],
|
||||
|
||||
// Specify whether double or single quotes should be used in JSX attributes
|
||||
// https://eslint.org/docs/rules/jsx-quotes
|
||||
@@ -46,12 +46,19 @@ module.exports = {
|
||||
],
|
||||
}],
|
||||
|
||||
// This rule enforces onChange or readonly attribute for checked property of input elements.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/checked-requires-onchange-or-readonly.md
|
||||
'react/checked-requires-onchange-or-readonly': ['off', {
|
||||
ignoreMissingProperties: false,
|
||||
ignoreExclusiveCheckedAttribute: false
|
||||
}],
|
||||
|
||||
// Prevent missing displayName in a React component definition
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/display-name.md
|
||||
'react/display-name': ['off', { ignoreTranspilerName: false }],
|
||||
|
||||
// Forbid certain propTypes (any, array, object)
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/forbid-prop-types.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/forbid-prop-types.md
|
||||
'react/forbid-prop-types': ['error', {
|
||||
forbid: ['any', 'array', 'object'],
|
||||
checkContextTypes: true,
|
||||
@@ -59,46 +66,47 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Forbid certain props on DOM Nodes
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/forbid-dom-props.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/forbid-dom-props.md
|
||||
'react/forbid-dom-props': ['off', { forbid: [] }],
|
||||
|
||||
// Enforce boolean attributes notation in JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md
|
||||
'react/jsx-boolean-value': ['error', 'never', { always: [] }],
|
||||
|
||||
// Validate closing bracket location in JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md
|
||||
'react/jsx-closing-bracket-location': ['error', 'line-aligned'],
|
||||
|
||||
// Validate closing tag location in JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md
|
||||
'react/jsx-closing-tag-location': 'error',
|
||||
|
||||
// Enforce or disallow spaces inside of curly braces in JSX attributes
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md
|
||||
'react/jsx-curly-spacing': ['error', 'never', { allowMultiline: true }],
|
||||
|
||||
// Enforce event handler naming conventions in JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-handler-names.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-handler-names.md
|
||||
'react/jsx-handler-names': ['off', {
|
||||
eventHandlerPrefix: 'handle',
|
||||
eventHandlerPropPrefix: 'on',
|
||||
}],
|
||||
|
||||
// Validate props indentation in JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-indent-props.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-indent-props.md
|
||||
'react/jsx-indent-props': ['error', 2],
|
||||
|
||||
// Validate JSX has key prop when in array or iterator
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-key.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-key.md
|
||||
// Turned off because it has too many false positives
|
||||
'react/jsx-key': 'off',
|
||||
|
||||
// Limit maximum of props on a single line in JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-max-props-per-line.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-max-props-per-line.md
|
||||
'react/jsx-max-props-per-line': ['error', { maximum: 1, when: 'multiline' }],
|
||||
|
||||
// Prevent usage of .bind() in JSX props
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md
|
||||
'react/jsx-no-bind': ['error', {
|
||||
ignoreRefs: true,
|
||||
allowArrowFunctions: true,
|
||||
@@ -108,26 +116,26 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Prevent duplicate props in JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-duplicate-props.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-duplicate-props.md
|
||||
'react/jsx-no-duplicate-props': ['error', { ignoreCase: true }],
|
||||
|
||||
// Prevent usage of unwrapped JSX strings
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-literals.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-literals.md
|
||||
'react/jsx-no-literals': ['off', { noStrings: true }],
|
||||
|
||||
// Disallow undeclared variables in JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md
|
||||
'react/jsx-no-undef': 'error',
|
||||
|
||||
// Enforce PascalCase for user-defined JSX components
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md
|
||||
'react/jsx-pascal-case': ['error', {
|
||||
allowAllCaps: true,
|
||||
ignore: [],
|
||||
}],
|
||||
|
||||
// Enforce propTypes declarations alphabetical sorting
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-prop-types.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/sort-prop-types.md
|
||||
'react/sort-prop-types': ['off', {
|
||||
ignoreCase: true,
|
||||
callbacksLast: false,
|
||||
@@ -139,7 +147,7 @@ module.exports = {
|
||||
'react/jsx-sort-prop-types': 'off',
|
||||
|
||||
// Enforce props alphabetical sorting
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md
|
||||
'react/jsx-sort-props': ['off', {
|
||||
ignoreCase: true,
|
||||
callbacksLast: false,
|
||||
@@ -150,74 +158,74 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Enforce defaultProps declarations alphabetical sorting
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-sort-default-props.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-sort-default-props.md
|
||||
'react/jsx-sort-default-props': ['off', {
|
||||
ignoreCase: true,
|
||||
}],
|
||||
|
||||
// Prevent React to be incorrectly marked as unused
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md
|
||||
'react/jsx-uses-react': ['error'],
|
||||
|
||||
// Prevent variables used in JSX to be incorrectly marked as unused
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md
|
||||
'react/jsx-uses-vars': 'error',
|
||||
|
||||
// Prevent usage of dangerous JSX properties
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-danger.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger.md
|
||||
'react/no-danger': 'warn',
|
||||
|
||||
// Prevent usage of deprecated methods
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-deprecated.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-deprecated.md
|
||||
'react/no-deprecated': ['error'],
|
||||
|
||||
// Prevent usage of setState in componentDidMount
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md
|
||||
// this is necessary for server-rendering
|
||||
'react/no-did-mount-set-state': 'off',
|
||||
|
||||
// Prevent usage of setState in componentDidUpdate
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md
|
||||
'react/no-did-update-set-state': 'error',
|
||||
|
||||
// Prevent usage of setState in componentWillUpdate
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-will-update-set-state.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-will-update-set-state.md
|
||||
'react/no-will-update-set-state': 'error',
|
||||
|
||||
// Prevent direct mutation of this.state
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md
|
||||
'react/no-direct-mutation-state': 'off',
|
||||
|
||||
// Prevent usage of isMounted
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md
|
||||
'react/no-is-mounted': 'error',
|
||||
|
||||
// Prevent multiple component definition per file
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md
|
||||
'react/no-multi-comp': 'off',
|
||||
|
||||
// Prevent usage of setState
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-set-state.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-set-state.md
|
||||
'react/no-set-state': 'off',
|
||||
|
||||
// Prevent using string references
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md
|
||||
'react/no-string-refs': 'error',
|
||||
|
||||
// Prevent usage of unknown DOM property
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md
|
||||
'react/no-unknown-property': 'error',
|
||||
|
||||
// Require ES6 class declarations over React.createClass
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md
|
||||
'react/prefer-es6-class': ['error', 'always'],
|
||||
|
||||
// Require stateless functions when not using lifecycle methods, setState or ref
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md
|
||||
'react/prefer-stateless-function': ['error', { ignorePureComponents: true }],
|
||||
|
||||
// Prevent missing props validation in a React component definition
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prop-types.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prop-types.md
|
||||
'react/prop-types': ['error', {
|
||||
ignore: [],
|
||||
customValidators: [],
|
||||
@@ -225,24 +233,26 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Prevent missing React when using JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md
|
||||
'react/react-in-jsx-scope': 'error',
|
||||
|
||||
// Require render() methods to return something
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-render-return.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-render-return.md
|
||||
'react/require-render-return': 'error',
|
||||
|
||||
// Prevent extra closing tags for components without children
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md
|
||||
'react/self-closing-comp': 'error',
|
||||
|
||||
// Enforce component methods order
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/sort-comp.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/sort-comp.md
|
||||
'react/sort-comp': ['error', {
|
||||
order: [
|
||||
'static-variables',
|
||||
'static-methods',
|
||||
'instance-variables',
|
||||
'lifecycle',
|
||||
'/^handle.+$/',
|
||||
'/^on.+$/',
|
||||
'getters',
|
||||
'setters',
|
||||
@@ -265,13 +275,19 @@ module.exports = {
|
||||
'getInitialState',
|
||||
'state',
|
||||
'getChildContext',
|
||||
'getDerivedStateFromProps',
|
||||
'componentWillMount',
|
||||
'UNSAFE_componentWillMount',
|
||||
'componentDidMount',
|
||||
'componentWillReceiveProps',
|
||||
'UNSAFE_componentWillReceiveProps',
|
||||
'shouldComponentUpdate',
|
||||
'componentWillUpdate',
|
||||
'UNSAFE_componentWillUpdate',
|
||||
'getSnapshotBeforeUpdate',
|
||||
'componentDidUpdate',
|
||||
'componentWillUnmount',
|
||||
'componentDidCatch',
|
||||
'componentWillUnmount'
|
||||
],
|
||||
rendering: [
|
||||
'/^render.+$/',
|
||||
@@ -281,7 +297,7 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Prevent missing parentheses around multilines JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-wrap-multilines.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-wrap-multilines.md
|
||||
'react/jsx-wrap-multilines': ['error', {
|
||||
declaration: 'parens-new-line',
|
||||
assignment: 'parens-new-line',
|
||||
@@ -293,55 +309,55 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Require that the first prop in a JSX element be on a new line when the element is multiline
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-first-prop-new-line.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-first-prop-new-line.md
|
||||
'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
|
||||
|
||||
// Enforce spacing around jsx equals signs
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-equals-spacing.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-equals-spacing.md
|
||||
'react/jsx-equals-spacing': ['error', 'never'],
|
||||
|
||||
// Enforce JSX indentation
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-indent.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-indent.md
|
||||
'react/jsx-indent': ['error', 2],
|
||||
|
||||
// Disallow target="_blank" on links
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/ac102885765be5ff37847a871f239c6703e1c7cc/docs/rules/jsx-no-target-blank.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/ac102885765be5ff37847a871f239c6703e1c7cc/docs/rules/jsx-no-target-blank.md
|
||||
'react/jsx-no-target-blank': ['error', { enforceDynamicLinks: 'always' }],
|
||||
|
||||
// only .jsx files may have JSX
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md
|
||||
'react/jsx-filename-extension': ['error', { extensions: ['.jsx'] }],
|
||||
|
||||
// prevent accidental JS comments from being injected into JSX as text
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-comment-textnodes.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-comment-textnodes.md
|
||||
'react/jsx-no-comment-textnodes': 'error',
|
||||
|
||||
// disallow using React.render/ReactDOM.render's return value
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-render-return-value.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-render-return-value.md
|
||||
'react/no-render-return-value': 'error',
|
||||
|
||||
// require a shouldComponentUpdate method, or PureRenderMixin
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-optimization.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-optimization.md
|
||||
'react/require-optimization': ['off', { allowDecorators: [] }],
|
||||
|
||||
// warn against using findDOMNode()
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-find-dom-node.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-find-dom-node.md
|
||||
'react/no-find-dom-node': 'error',
|
||||
|
||||
// Forbid certain props on Components
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/forbid-component-props.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-component-props.md
|
||||
'react/forbid-component-props': ['off', { forbid: [] }],
|
||||
|
||||
// Forbid certain elements
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/forbid-elements.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-elements.md
|
||||
'react/forbid-elements': ['off', { forbid: [], }],
|
||||
|
||||
// Prevent problem with children and props.dangerouslySetInnerHTML
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-danger-with-children.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-danger-with-children.md
|
||||
'react/no-danger-with-children': 'error',
|
||||
|
||||
// Prevent unused propType definitions
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-unused-prop-types.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unused-prop-types.md
|
||||
'react/no-unused-prop-types': ['error', {
|
||||
customValidators: [
|
||||
],
|
||||
@@ -349,19 +365,19 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Require style prop value be an object or var
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/style-prop-object.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/style-prop-object.md
|
||||
'react/style-prop-object': 'error',
|
||||
|
||||
// Prevent invalid characters from appearing in markup
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-unescaped-entities.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unescaped-entities.md
|
||||
'react/no-unescaped-entities': 'error',
|
||||
|
||||
// Prevent passing of children as props
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-children-prop.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-children-prop.md
|
||||
'react/no-children-prop': 'error',
|
||||
|
||||
// Validate whitespace in and around the JSX opening and closing brackets
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-tag-spacing.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-tag-spacing.md
|
||||
'react/jsx-tag-spacing': ['error', {
|
||||
closingSlash: 'never',
|
||||
beforeSelfClosing: 'always',
|
||||
@@ -370,44 +386,44 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Enforce spaces before the closing bracket of self-closing JSX elements
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-space-before-closing.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-space-before-closing.md
|
||||
// Deprecated in favor of jsx-tag-spacing
|
||||
'react/jsx-space-before-closing': ['off', 'always'],
|
||||
|
||||
// Prevent usage of Array index in keys
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md
|
||||
'react/no-array-index-key': 'error',
|
||||
|
||||
// Enforce a defaultProps definition for every prop that is not a required prop
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/require-default-props.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/require-default-props.md
|
||||
'react/require-default-props': ['error', {
|
||||
forbidDefaultForRequired: true,
|
||||
}],
|
||||
|
||||
// Forbids using non-exported propTypes
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/forbid-foreign-prop-types.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-foreign-prop-types.md
|
||||
// this is intentionally set to "warn". it would be "error",
|
||||
// but it's only critical if you're stripping propTypes in production.
|
||||
'react/forbid-foreign-prop-types': ['warn', { allowInPropTypes: true }],
|
||||
|
||||
// Prevent void DOM elements from receiving children
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/void-dom-elements-no-children.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/void-dom-elements-no-children.md
|
||||
'react/void-dom-elements-no-children': 'error',
|
||||
|
||||
// Enforce all defaultProps have a corresponding non-required PropType
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/9e13ae2c51e44872b45cc15bf1ac3a72105bdd0e/docs/rules/default-props-match-prop-types.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/9e13ae2c51e44872b45cc15bf1ac3a72105bdd0e/docs/rules/default-props-match-prop-types.md
|
||||
'react/default-props-match-prop-types': ['error', { allowRequiredDefaults: false }],
|
||||
|
||||
// Prevent usage of shouldComponentUpdate when extending React.PureComponent
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/9e13ae2c51e44872b45cc15bf1ac3a72105bdd0e/docs/rules/no-redundant-should-component-update.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/9e13ae2c51e44872b45cc15bf1ac3a72105bdd0e/docs/rules/no-redundant-should-component-update.md
|
||||
'react/no-redundant-should-component-update': 'error',
|
||||
|
||||
// Prevent unused state values
|
||||
// https://github.com/yannickcr/eslint-plugin-react/pull/1103/
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/pull/1103/
|
||||
'react/no-unused-state': 'error',
|
||||
|
||||
// Enforces consistent naming for boolean props
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/boolean-prop-naming.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/boolean-prop-naming.md
|
||||
'react/boolean-prop-naming': ['off', {
|
||||
propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],
|
||||
rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+',
|
||||
@@ -415,27 +431,27 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// Prevents common casing typos
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/73abadb697034b5ccb514d79fb4689836fe61f91/docs/rules/no-typos.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/73abadb697034b5ccb514d79fb4689836fe61f91/docs/rules/no-typos.md
|
||||
'react/no-typos': 'error',
|
||||
|
||||
// Enforce curly braces or disallow unnecessary curly braces in JSX props and/or children
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-curly-brace-presence.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-brace-presence.md
|
||||
'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }],
|
||||
|
||||
// One JSX Element Per Line
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-one-expression-per-line.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-one-expression-per-line.md
|
||||
'react/jsx-one-expression-per-line': ['error', { allow: 'single-child' }],
|
||||
|
||||
// Enforce consistent usage of destructuring assignment of props, state, and context
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/destructuring-assignment.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/destructuring-assignment.md
|
||||
'react/destructuring-assignment': ['error', 'always'],
|
||||
|
||||
// Prevent using this.state within a this.setState
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/no-access-state-in-setstate.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/no-access-state-in-setstate.md
|
||||
'react/no-access-state-in-setstate': 'error',
|
||||
|
||||
// Prevent usage of button elements without an explicit type attribute
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/button-has-type.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/button-has-type.md
|
||||
'react/button-has-type': ['error', {
|
||||
button: true,
|
||||
submit: true,
|
||||
@@ -446,25 +462,144 @@ module.exports = {
|
||||
'react/jsx-child-element-spacing': 'off',
|
||||
|
||||
// Prevent this from being used in stateless functional components
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/no-this-in-sfc.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/no-this-in-sfc.md
|
||||
'react/no-this-in-sfc': 'error',
|
||||
|
||||
// Validate JSX maximum depth
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/abe8381c0d6748047224c430ce47f02e40160ed0/docs/rules/jsx-max-depth.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/abe8381c0d6748047224c430ce47f02e40160ed0/docs/rules/jsx-max-depth.md
|
||||
'react/jsx-max-depth': 'off',
|
||||
|
||||
// Disallow multiple spaces between inline JSX props
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/ac102885765be5ff37847a871f239c6703e1c7cc/docs/rules/jsx-props-no-multi-spaces.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/ac102885765be5ff37847a871f239c6703e1c7cc/docs/rules/jsx-props-no-multi-spaces.md
|
||||
'react/jsx-props-no-multi-spaces': 'error',
|
||||
|
||||
// Prevent usage of UNSAFE_ methods
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/157cc932be2cfaa56b3f5b45df6f6d4322a2f660/docs/rules/no-unsafe.md
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/157cc932be2cfaa56b3f5b45df6f6d4322a2f660/docs/rules/no-unsafe.md
|
||||
'react/no-unsafe': 'off',
|
||||
|
||||
// Enforce shorthand or standard form for React fragments
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/bc976b837abeab1dffd90ac6168b746a83fc83cc/docs/rules/jsx-fragments.md
|
||||
// TODO: enable, semver-major
|
||||
'react/jsx-fragments': ['off', 'syntax'],
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/bc976b837abeab1dffd90ac6168b746a83fc83cc/docs/rules/jsx-fragments.md
|
||||
'react/jsx-fragments': ['error', 'syntax'],
|
||||
|
||||
// Enforce linebreaks in curly braces in JSX attributes and expressions.
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-newline.md
|
||||
'react/jsx-curly-newline': ['error', {
|
||||
multiline: 'consistent',
|
||||
singleline: 'consistent',
|
||||
}],
|
||||
|
||||
// Enforce state initialization style
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/state-in-constructor.md
|
||||
// TODO: set to "never" once babel-preset-airbnb supports public class fields
|
||||
'react/state-in-constructor': ['error', 'always'],
|
||||
|
||||
// Enforces where React component static properties should be positioned
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/static-property-placement.md
|
||||
// TODO: set to "static public field" once babel-preset-airbnb supports public class fields
|
||||
'react/static-property-placement': ['error', 'property assignment'],
|
||||
|
||||
// Disallow JSX props spreading
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md
|
||||
'react/jsx-props-no-spreading': ['error', {
|
||||
html: 'enforce',
|
||||
custom: 'enforce',
|
||||
explicitSpread: 'ignore',
|
||||
exceptions: [],
|
||||
}],
|
||||
|
||||
// Enforce that props are read-only
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-read-only-props.md
|
||||
'react/prefer-read-only-props': 'off',
|
||||
|
||||
// Prevent usage of `javascript:` URLs
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-script-url.md
|
||||
'react/jsx-no-script-url': ['error', [
|
||||
{
|
||||
name: 'Link',
|
||||
props: ['to'],
|
||||
},
|
||||
]],
|
||||
|
||||
// Disallow unnecessary fragments
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-useless-fragment.md
|
||||
'react/jsx-no-useless-fragment': 'error',
|
||||
|
||||
// Prevent adjacent inline elements not separated by whitespace
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-adjacent-inline-elements.md
|
||||
// TODO: enable? semver-major
|
||||
'react/no-adjacent-inline-elements': 'off',
|
||||
|
||||
// Enforce a specific function type for function components
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/function-component-definition.md
|
||||
'react/function-component-definition': ['error', {
|
||||
namedComponents: ['function-declaration', 'function-expression'],
|
||||
unnamedComponents: 'function-expression',
|
||||
}],
|
||||
|
||||
// Enforce a new line after jsx elements and expressions
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/e2eaadae316f9506d163812a09424eb42698470a/docs/rules/jsx-newline.md
|
||||
'react/jsx-newline': 'off',
|
||||
|
||||
// Prevent react contexts from taking non-stable values
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/e2eaadae316f9506d163812a09424eb42698470a/docs/rules/jsx-no-constructed-context-values.md
|
||||
'react/jsx-no-constructed-context-values': 'error',
|
||||
|
||||
// Prevent creating unstable components inside components
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/c2a790a3472eea0f6de984bdc3ee2a62197417fb/docs/rules/no-unstable-nested-components.md
|
||||
'react/no-unstable-nested-components': 'error',
|
||||
|
||||
// Enforce that namespaces are not used in React elements
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/8785c169c25b09b33c95655bf508cf46263bc53f/docs/rules/no-namespace.md
|
||||
'react/no-namespace': 'error',
|
||||
|
||||
// Prefer exact proptype definitions
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/8785c169c25b09b33c95655bf508cf46263bc53f/docs/rules/prefer-exact-props.md
|
||||
'react/prefer-exact-props': 'error',
|
||||
|
||||
// Lifecycle methods should be methods on the prototype, not class fields
|
||||
// https://github.com/jsx-eslint/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/jsx-eslint/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/jsx-eslint/eslint-plugin-react/blob/21e01b61af7a38fc86d94f27eb66cda8054582ed/docs/rules/no-unused-class-component-methods.md
|
||||
'react/no-unused-class-component-methods': 'error',
|
||||
|
||||
// Ensure destructuring and symmetric naming of useState hook value and setter variables
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/c8833f301314dab3e79ef7ac4cf863e4d5fa0019/docs/rules/hook-use-state.md
|
||||
// TODO: semver-major, enable
|
||||
'react/hook-use-state': 'off',
|
||||
|
||||
// Enforce sandbox attribute on iframe elements
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/c8833f301314dab3e79ef7ac4cf863e4d5fa0019/docs/rules/iframe-missing-sandbox.md
|
||||
// TODO: semver-major, enable
|
||||
'react/iframe-missing-sandbox': 'off',
|
||||
|
||||
// Prevent problematic leaked values from being rendered
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/c42b624d0fb9ad647583a775ab9751091eec066f/docs/rules/jsx-no-leaked-render.md
|
||||
// TODO: semver-major, enable
|
||||
'react/jsx-no-leaked-render': 'off',
|
||||
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/66b58dd4864678eb869a7bf434c72ff7ac530eb1/docs/rules/no-object-type-as-default-prop.md
|
||||
// TODO: semver-major, enable
|
||||
'react/no-object-type-as-default-prop': 'off',
|
||||
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/66b58dd4864678eb869a7bf434c72ff7ac530eb1/docs/rules/sort-default-props.md
|
||||
// TODO: semver-major, enable?
|
||||
'react/sort-default-props': ['off', {
|
||||
ignoreCase: false
|
||||
}],
|
||||
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/9668ee0762acd5c23f53cd3a372e2d8d9563944d/docs/rules/forward-ref-uses-ref.md
|
||||
// TODO: semver-major, enable
|
||||
'react/forward-ref-uses-ref': 'off',
|
||||
|
||||
// https://github.com/jsx-eslint/eslint-plugin-react/blob/9668ee0762acd5c23f53cd3a372e2d8d9563944d/docs/rules/jsx-props-no-spread-multi.md
|
||||
// TODO: semver-major, enable
|
||||
'react/jsx-props-no-spread-multi': 'off',
|
||||
},
|
||||
|
||||
settings: {
|
||||
@@ -475,7 +610,7 @@ module.exports = {
|
||||
},
|
||||
react: {
|
||||
pragma: 'React',
|
||||
version: '16.0'
|
||||
version: 'detect',
|
||||
},
|
||||
propWrapperFunctions: [
|
||||
'forbidExtraProps', // https://www.npmjs.com/package/airbnb-prop-types
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
/* eslint
|
||||
strict: 0,
|
||||
global-require: 0,
|
||||
*/
|
||||
/* eslint strict: 0, global-require: 0 */
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -12,6 +9,7 @@ test('all entry points parse', (t) => {
|
||||
t.doesNotThrow(() => require('../base'), 'base does not throw');
|
||||
t.doesNotThrow(() => require('../legacy'), 'legacy does not throw');
|
||||
t.doesNotThrow(() => require('../whitespace'), 'whitespace does not throw');
|
||||
t.doesNotThrow(() => require('../hooks'), 'hooks does not throw');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
@@ -6,13 +6,14 @@ const base = require('../base');
|
||||
|
||||
const files = { base };
|
||||
|
||||
fs.readdirSync(path.join(__dirname, '../rules')).forEach((name) => {
|
||||
const rulesDir = path.join(__dirname, '../rules');
|
||||
fs.readdirSync(rulesDir).forEach((name) => {
|
||||
if (name === 'react.js' || name === 'react-a11y.js') {
|
||||
return;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line import/no-dynamic-require
|
||||
files[name] = require(`../rules/${name}`); // eslint-disable-line global-require
|
||||
files[name] = require(path.join(rulesDir, name)); // eslint-disable-line global-require
|
||||
});
|
||||
|
||||
Object.keys(files).forEach((name) => {
|
||||
@@ -28,7 +29,7 @@ Object.keys(files).forEach((name) => {
|
||||
|
||||
// scan rules for react/ and fail if any exist
|
||||
const reactRuleIds = Object.keys(config.rules)
|
||||
.filter(ruleId => ruleId.indexOf('react/') === 0);
|
||||
.filter((ruleId) => ruleId.indexOf('react/') === 0);
|
||||
t.deepEquals(reactRuleIds, [], 'there are no react/ rules');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
import test from 'tape';
|
||||
import { CLIEngine } from 'eslint';
|
||||
import { CLIEngine, ESLint } from 'eslint';
|
||||
import eslintrc from '..';
|
||||
import reactRules from '../rules/react';
|
||||
import reactA11yRules from '../rules/react-a11y';
|
||||
|
||||
const cli = new CLIEngine({
|
||||
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 = cli.executeOnText(text);
|
||||
return linter.results[0];
|
||||
const linter = CLIEngine ? cli.executeOnText(text) : await cli.lintText(text);
|
||||
return (CLIEngine ? linter.results : linter)[0];
|
||||
}
|
||||
|
||||
function wrapComponent(body) {
|
||||
return `
|
||||
return `\
|
||||
import React from 'react';
|
||||
|
||||
export default class MyComponent extends React.Component {
|
||||
/* eslint no-empty-function: 0, class-methods-use-this: 0 */
|
||||
${body}
|
||||
}
|
||||
${body}}
|
||||
`;
|
||||
}
|
||||
|
||||
test('validate react prop order', (t) => {
|
||||
test('validate react methods order', (t) => {
|
||||
t.test('make sure our eslintrc has React and JSX linting dependencies', (t) => {
|
||||
t.plan(2);
|
||||
t.deepEqual(reactRules.plugins, ['react']);
|
||||
t.deepEqual(reactA11yRules.plugins, ['jsx-a11y', 'react']);
|
||||
});
|
||||
|
||||
t.test('passes a good component', (t) => {
|
||||
t.plan(3);
|
||||
const result = lint(wrapComponent(`
|
||||
componentWillMount() {}
|
||||
t.test('passes a good component', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
componentDidMount() {}
|
||||
handleSubmit() {}
|
||||
onButtonAClick() {}
|
||||
setFoo() {}
|
||||
getFoo() {}
|
||||
setBar() {}
|
||||
someMethod() {}
|
||||
renderDogs() {}
|
||||
render() { return <div />; }`));
|
||||
render() { return <div />; }
|
||||
`));
|
||||
|
||||
t.notOk(result.warningCount, 'no warnings');
|
||||
t.notOk(result.errorCount, 'no errors');
|
||||
t.deepEquals(result.messages, [], 'no messages in results');
|
||||
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() {}
|
||||
componentWillMount() {}
|
||||
componentDidMount() {}
|
||||
setFoo() {}
|
||||
getFoo() {}
|
||||
@@ -72,13 +72,11 @@ test('validate react prop order', (t) => {
|
||||
`));
|
||||
|
||||
t.ok(result.errorCount, 'fails');
|
||||
t.equal(result.messages[0].ruleId, 'react/sort-comp', 'fails due to sort');
|
||||
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(`
|
||||
componentWillMount() {}
|
||||
t.test('order: when random method after lifecycle methods', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
componentDidMount() {}
|
||||
someMethod() {}
|
||||
setFoo() {}
|
||||
@@ -89,6 +87,46 @@ test('validate react prop order', (t) => {
|
||||
`));
|
||||
|
||||
t.ok(result.errorCount, 'fails');
|
||||
t.equal(result.messages[0].ruleId, 'react/sort-comp', 'fails due to sort');
|
||||
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', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
componentDidMount() {}
|
||||
onButtonAClick() {}
|
||||
handleSubmit() {}
|
||||
setFoo() {}
|
||||
getFoo() {}
|
||||
render() { return <div />; }
|
||||
`));
|
||||
|
||||
t.ok(result.errorCount, 'fails');
|
||||
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', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
handleSubmit() {}
|
||||
componentDidMount() {}
|
||||
setFoo() {}
|
||||
getFoo() {}
|
||||
render() { return <div />; }
|
||||
`));
|
||||
|
||||
t.ok(result.errorCount, 'fails');
|
||||
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', async (t) => {
|
||||
const result = await lint(wrapComponent(`
|
||||
componentDidMount() {}
|
||||
setFoo() {}
|
||||
getFoo() {}
|
||||
handleSubmit() {}
|
||||
render() { return <div />; }
|
||||
`));
|
||||
|
||||
t.ok(result.errorCount, 'fails');
|
||||
t.deepEqual(result.messages.map((msg) => msg.ruleId), ['react/sort-comp'], 'fails due to sort');
|
||||
});
|
||||
});
|
||||
|
||||
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 { isArray } = Array;
|
||||
const { entries } = Object;
|
||||
const { ESLint } = require('eslint');
|
||||
|
||||
const baseConfig = require('.');
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
|
||||
function getSeverity(ruleConfig) {
|
||||
if (isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
async function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = { ...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 (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,92 +1,61 @@
|
||||
const assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
const CLIEngine = require('eslint').CLIEngine;
|
||||
/* eslint global-require: 0 */
|
||||
|
||||
const baseConfig = require('.');
|
||||
const { isArray } = Array;
|
||||
const { entries } = Object;
|
||||
const { CLIEngine } = require('eslint');
|
||||
|
||||
function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = assign({}, config);
|
||||
const cli = new CLIEngine({ baseConfig: config, useEslintrc: false });
|
||||
const baseRules = cli.getConfigForFile('./').rules;
|
||||
if (CLIEngine) {
|
||||
/* eslint no-inner-declarations: 0 */
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
entries(baseRules).forEach((rule) => {
|
||||
const ruleName = rule[0];
|
||||
const ruleConfig = rule[1];
|
||||
const baseConfig = require('.');
|
||||
|
||||
if (rulesToError.indexOf(ruleName) === -1) {
|
||||
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';
|
||||
}
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
|
||||
function getSeverity(ruleConfig) {
|
||||
if (isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
});
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
return errorsOnly;
|
||||
function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = { ...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 (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');
|
||||
|
||||
// NOTE: ESLint adds runtime statistics to the output (so it's no longer JSON) if TIMING is set
|
||||
module.exports = JSON.parse(String(execSync(path.join(__dirname, 'whitespace-async.js'), {
|
||||
env: {
|
||||
...process.env,
|
||||
TIMING: undefined,
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
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',
|
||||
];
|
||||
@@ -25,14 +25,14 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
## Basic Rules
|
||||
|
||||
- Only include one React component per file.
|
||||
- However, multiple [Stateless, or Pure, Components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions) are allowed per file. eslint: [`react/no-multi-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless).
|
||||
- However, multiple [Stateless, or Pure, Components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions) are allowed per file. eslint: [`react/no-multi-comp`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless).
|
||||
- Always use JSX syntax.
|
||||
- Do not use `React.createElement` unless you’re initializing the app from a file that is not JSX.
|
||||
- [`react/forbid-prop-types`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md) will allow `arrays` and `objects` only if it is explicitly noted what `array` and `object` contains, using `arrayOf`, `objectOf`, or `shape`.
|
||||
- [`react/forbid-prop-types`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md) will allow `arrays` and `objects` only if it is explicitly noted what `array` and `object` contains, using `arrayOf`, `objectOf`, or `shape`.
|
||||
|
||||
## Class vs `React.createClass` vs stateless
|
||||
|
||||
- If you have internal state and/or refs, prefer `class extends React.Component` over `React.createClass`. eslint: [`react/prefer-es6-class`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md) [`react/prefer-stateless-function`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md)
|
||||
- If you have internal state and/or refs, prefer `class extends React.Component` over `React.createClass`. eslint: [`react/prefer-es6-class`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md) [`react/prefer-stateless-function`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -81,9 +81,9 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
|
||||
## Naming
|
||||
|
||||
- **Extensions**: Use `.jsx` extension for React components. eslint: [`react/jsx-filename-extension`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md)
|
||||
- **Extensions**: Use `.jsx` extension for React components. eslint: [`react/jsx-filename-extension`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md)
|
||||
- **Filename**: Use PascalCase for filenames. E.g., `ReservationCard.jsx`.
|
||||
- **Reference Naming**: Use PascalCase for React components and camelCase for their instances. eslint: [`react/jsx-pascal-case`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md)
|
||||
- **Reference Naming**: Use PascalCase for React components and camelCase for their instances. eslint: [`react/jsx-pascal-case`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -111,6 +111,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
// good
|
||||
import Footer from './Footer';
|
||||
```
|
||||
|
||||
- **Higher-order Component Naming**: Use a composite of the higher-order component’s name and the passed-in component’s name as the `displayName` on the generated component. For example, the higher-order component `withFoo()`, when passed a component `Bar` should produce a component with a `displayName` of `withFoo(Bar)`.
|
||||
|
||||
> Why? A component’s `displayName` may be used by developer tools or in error messages, and having a value that clearly expresses this relationship helps people understand what is happening.
|
||||
@@ -171,7 +172,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
|
||||
## Alignment
|
||||
|
||||
- Follow these alignment styles for JSX syntax. eslint: [`react/jsx-closing-bracket-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md) [`react/jsx-closing-tag-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md)
|
||||
- Follow these alignment styles for JSX syntax. eslint: [`react/jsx-closing-bracket-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md) [`react/jsx-closing-tag-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -213,6 +214,27 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
|
||||
// good
|
||||
{showButton && <Button />}
|
||||
|
||||
// good
|
||||
{someReallyLongConditional
|
||||
&& anotherLongConditional
|
||||
&& (
|
||||
<Foo
|
||||
superLongParam="bar"
|
||||
anotherSuperLongParam="baz"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
// good
|
||||
{someConditional ? (
|
||||
<Foo />
|
||||
) : (
|
||||
<Foo
|
||||
superLongParam="bar"
|
||||
anotherSuperLongParam="baz"
|
||||
/>
|
||||
)}
|
||||
```
|
||||
|
||||
## Quotes
|
||||
@@ -237,7 +259,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
|
||||
## Spacing
|
||||
|
||||
- Always include a single space in your self-closing tag. eslint: [`no-multi-spaces`](https://eslint.org/docs/rules/no-multi-spaces), [`react/jsx-tag-spacing`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md)
|
||||
- Always include a single space in your self-closing tag. eslint: [`no-multi-spaces`](https://eslint.org/docs/rules/no-multi-spaces), [`react/jsx-tag-spacing`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -254,7 +276,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
<Foo />
|
||||
```
|
||||
|
||||
- Do not pad JSX curly braces with spaces. eslint: [`react/jsx-curly-spacing`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md)
|
||||
- Do not pad JSX curly braces with spaces. eslint: [`react/jsx-curly-spacing`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -266,7 +288,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
|
||||
## Props
|
||||
|
||||
- Always use camelCase for prop names.
|
||||
- Always use camelCase for prop names, or PascalCase if the prop value is a React component.
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -279,10 +301,11 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
<Foo
|
||||
userName="hello"
|
||||
phoneNumber={12345678}
|
||||
Component={SomeComponent}
|
||||
/>
|
||||
```
|
||||
|
||||
- Omit the value of the prop when it is explicitly `true`. eslint: [`react/jsx-boolean-value`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md)
|
||||
- Omit the value of the prop when it is explicitly `true`. eslint: [`react/jsx-boolean-value`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -299,7 +322,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
<Foo hidden />
|
||||
```
|
||||
|
||||
- Always include an `alt` prop on `<img>` tags. If the image is presentational, `alt` can be an empty string or the `<img>` must have `role="presentation"`. eslint: [`jsx-a11y/alt-text`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md)
|
||||
- Always include an `alt` prop on `<img>` tags. If the image is presentational, `alt` can be an empty string or the `<img>` must have `role="presentation"`. eslint: [`jsx-a11y/alt-text`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -315,7 +338,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
<img src="hello.jpg" role="presentation" />
|
||||
```
|
||||
|
||||
- Do not use words like "image", "photo", or "picture" in `<img>` `alt` props. eslint: [`jsx-a11y/img-redundant-alt`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md)
|
||||
- Do not use words like "image", "photo", or "picture" in `<img>` `alt` props. eslint: [`jsx-a11y/img-redundant-alt`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md)
|
||||
|
||||
> Why? Screenreaders already announce `img` elements as images, so there is no need to include this information in the alt text.
|
||||
|
||||
@@ -327,7 +350,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
<img src="hello.jpg" alt="Me waving hello" />
|
||||
```
|
||||
|
||||
- Use only valid, non-abstract [ARIA roles](https://www.w3.org/TR/wai-aria/#usage_intro). eslint: [`jsx-a11y/aria-role`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md)
|
||||
- Use only valid, non-abstract [ARIA roles](https://www.w3.org/TR/wai-aria/#usage_intro). eslint: [`jsx-a11y/aria-role`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md)
|
||||
|
||||
```jsx
|
||||
// bad - not an ARIA role
|
||||
@@ -340,7 +363,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
<div role="button" />
|
||||
```
|
||||
|
||||
- Do not use `accessKey` on elements. eslint: [`jsx-a11y/no-access-key`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md)
|
||||
- Do not use `accessKey` on elements. eslint: [`jsx-a11y/no-access-key`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md)
|
||||
|
||||
> Why? Inconsistencies between keyboard shortcuts and keyboard commands used by people using screenreaders and keyboards complicate accessibility.
|
||||
|
||||
@@ -352,7 +375,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
<div />
|
||||
```
|
||||
|
||||
- Avoid using an array index as `key` prop, prefer a stable ID. eslint: [`react/no-array-index-key`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md)
|
||||
- Avoid using an array index as `key` prop, prefer a stable ID. eslint: [`react/no-array-index-key`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md)
|
||||
|
||||
> Why? Not using a stable ID [is an anti-pattern](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318) because it can negatively impact performance and cause issues with component state.
|
||||
|
||||
@@ -460,7 +483,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
|
||||
## Refs
|
||||
|
||||
- Always use ref callbacks. eslint: [`react/no-string-refs`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md)
|
||||
- Always use ref callbacks. eslint: [`react/no-string-refs`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -476,7 +499,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
|
||||
## Parentheses
|
||||
|
||||
- Wrap JSX tags in parentheses when they span more than one line. eslint: [`react/jsx-wrap-multilines`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md)
|
||||
- Wrap JSX tags in parentheses when they span more than one line. eslint: [`react/jsx-wrap-multilines`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -504,7 +527,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
|
||||
## Tags
|
||||
|
||||
- Always self-close tags that have no children. eslint: [`react/self-closing-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md)
|
||||
- Always self-close tags that have no children. eslint: [`react/self-closing-comp`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -514,7 +537,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
<Foo variant="stuff" />
|
||||
```
|
||||
|
||||
- If your component has multi-line properties, close its tag on a new line. eslint: [`react/jsx-closing-bracket-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md)
|
||||
- If your component has multiline properties, close its tag on a new line. eslint: [`react/jsx-closing-bracket-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -540,7 +563,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
{props.items.map((item, index) => (
|
||||
<Item
|
||||
key={item.key}
|
||||
onClick={(event) => doSomethingWith(event, item.name, index)}
|
||||
onClick={(event) => { doSomethingWith(event, item.name, index); }}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
@@ -548,7 +571,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
}
|
||||
```
|
||||
|
||||
- Bind event handlers for the render method in the constructor. eslint: [`react/jsx-no-bind`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md)
|
||||
- Bind event handlers for the render method in the constructor. eslint: [`react/jsx-no-bind`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md)
|
||||
|
||||
> Why? A bind call in the render path creates a brand new function on every single render. Do not use arrow functions in class fields, because it makes them [challenging to test and debug, and can negatively impact performance](https://medium.com/@charpeni/arrow-functions-in-class-properties-might-not-be-as-great-as-we-think-3b3551c440b1), and because conceptually, class fields are for data, not logic.
|
||||
|
||||
@@ -616,7 +639,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
}
|
||||
```
|
||||
|
||||
- Be sure to return a value in your `render` methods. eslint: [`react/require-render-return`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-render-return.md)
|
||||
- Be sure to return a value in your `render` methods. eslint: [`react/require-render-return`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-render-return.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -644,7 +667,8 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
1. `componentWillUpdate`
|
||||
1. `componentDidUpdate`
|
||||
1. `componentWillUnmount`
|
||||
1. *clickHandlers or eventHandlers* like `onClickSubmit()` or `onChangeDescription()`
|
||||
1. *event handlers starting with 'handle'* like `handleSubmit()` or `handleChangeDescription()`
|
||||
1. *event handlers starting with 'on'* like `onClickSubmit()` or `onChangeDescription()`
|
||||
1. *getter methods for `render`* like `getSelectReason()` or `getFooterContent()`
|
||||
1. *optional render methods* like `renderNavigation()` or `renderProfilePicture()`
|
||||
1. `render`
|
||||
@@ -681,7 +705,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
export default Link;
|
||||
```
|
||||
|
||||
- Ordering for `React.createClass`: eslint: [`react/sort-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md)
|
||||
- Ordering for `React.createClass`: eslint: [`react/sort-comp`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/sort-comp.md)
|
||||
|
||||
1. `displayName`
|
||||
1. `propTypes`
|
||||
@@ -707,7 +731,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
|
||||
## `isMounted`
|
||||
|
||||
- Do not use `isMounted`. eslint: [`react/no-is-mounted`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md)
|
||||
- Do not use `isMounted`. eslint: [`react/no-is-mounted`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md)
|
||||
|
||||
> Why? [`isMounted` is an anti-pattern][anti-pattern], is not available when using ES6 classes, and is on its way to being officially deprecated.
|
||||
|
||||
@@ -717,7 +741,7 @@ We don’t recommend using indexes for keys if the order of items may change.
|
||||
|
||||
This JSX/React style guide is also available in other languages:
|
||||
|
||||
-  **Chinese (Simplified)**: [JasonBoy/javascript](https://github.com/JasonBoy/javascript/tree/master/react)
|
||||
-  **Chinese (Simplified)**: [jhcccc/javascript](https://github.com/jhcccc/javascript/tree/master/react)
|
||||
-  **Chinese (Traditional)**: [jigsawye/javascript](https://github.com/jigsawye/javascript/tree/master/react)
|
||||
-  **Español**: [agrcrobles/javascript](https://github.com/agrcrobles/javascript/tree/master/react)
|
||||
-  **Japanese**: [mitsuruog/javascript-style-guide](https://github.com/mitsuruog/javascript-style-guide/tree/master/react)
|
||||
|
||||
Reference in New Issue
Block a user