mirror of
https://github.com/airbnb/javascript.git
synced 2026-01-14 13:28:05 -05:00
Compare commits
245 Commits
eslint-con
...
actions
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34b5bc39f1 | ||
|
|
d4e39c9b10 | ||
|
|
baaa5e8d26 | ||
|
|
274c8d5701 | ||
|
|
38bc026fe4 | ||
|
|
445322db64 | ||
|
|
152bd5e85a | ||
|
|
afc2cc3432 | ||
|
|
371537f393 | ||
|
|
c05ffb2417 | ||
|
|
97a3238020 | ||
|
|
e0bb393519 | ||
|
|
c4000b932a | ||
|
|
31c6f21878 | ||
|
|
91cab81f69 | ||
|
|
d8cb404da7 | ||
|
|
52e710c14e | ||
|
|
1bc8cabd44 | ||
|
|
37ebbba44c | ||
|
|
930a6f2e4c | ||
|
|
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 | ||
|
|
873f302b00 | ||
|
|
7ea44cfc79 | ||
|
|
9fbe07f282 | ||
|
|
a9a83d9150 | ||
|
|
76ff7c7f79 | ||
|
|
4539dbcf17 | ||
|
|
19701d4a0c | ||
|
|
1310ade9d0 | ||
|
|
5cd011dfa1 | ||
|
|
117d4fce49 | ||
|
|
447466681e | ||
|
|
60b96d3222 | ||
|
|
b85baeafed | ||
|
|
be07f7a020 | ||
|
|
495a62aaa9 | ||
|
|
da0cf08831 | ||
|
|
a71c2d1ad3 | ||
|
|
834d717c7b | ||
|
|
8694a87378 | ||
|
|
4f15da6146 | ||
|
|
6ef45d4bab | ||
|
|
96f95fa35e | ||
|
|
ebe96824e2 | ||
|
|
d78af39118 | ||
|
|
d8256fc886 | ||
|
|
25f11fb31e | ||
|
|
1439ebe78d | ||
|
|
b6c56cb070 | ||
|
|
955f4e93b8 | ||
|
|
95286eb496 | ||
|
|
070e6200bb | ||
|
|
387755e8fe | ||
|
|
218c4fefbb | ||
|
|
80920a07c5 | ||
|
|
5d25a2ee61 | ||
|
|
064e3bf8d5 | ||
|
|
ffe4fe967c | ||
|
|
69e34378c6 | ||
|
|
6ece1f58e9 | ||
|
|
0d6d854b5c | ||
|
|
21b65e943c | ||
|
|
74deb81d1f | ||
|
|
41a13e83ee | ||
|
|
03a0734fce | ||
|
|
24da5bb540 | ||
|
|
924dfb2682 | ||
|
|
9af5ee89eb | ||
|
|
32a7bf44c2 | ||
|
|
02b4eea345 | ||
|
|
e7ffd44b4a | ||
|
|
17e0454672 | ||
|
|
b8b2a0b0e0 | ||
|
|
48448a81cc | ||
|
|
5443d03de2 | ||
|
|
fcfd378dd8 | ||
|
|
d774b8979e | ||
|
|
ced1cb3ad8 |
@@ -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
|
||||
54
.travis.yml
54
.travis.yml
@@ -1,54 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "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
|
||||
339
README.md
339
README.md
@@ -71,6 +71,7 @@ Other Style Guides
|
||||
- `null`
|
||||
- `undefined`
|
||||
- `symbol`
|
||||
- `bigint`
|
||||
|
||||
```javascript
|
||||
const foo = 1;
|
||||
@@ -81,7 +82,7 @@ Other Style Guides
|
||||
console.log(foo, bar); // => 1, 9
|
||||
```
|
||||
|
||||
- Symbols cannot be faithfully polyfilled, so they should not be used when targeting browsers/environments that don't support them natively.
|
||||
- Symbols and BigInts cannot be faithfully polyfilled, so they should not be used when targeting browsers/environments that don’t support them natively.
|
||||
|
||||
<a name="types--complex"></a><a name="1.2"></a>
|
||||
- [1.2](#types--complex) **Complex**: When you access a complex type you work on a reference to its value.
|
||||
@@ -138,18 +139,22 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="references--block-scope"></a><a name="2.3"></a>
|
||||
- [2.3](#references--block-scope) Note that both `let` and `const` are block-scoped.
|
||||
- [2.3](#references--block-scope) Note that both `let` and `const` are block-scoped, whereas `var` is function-scoped.
|
||||
|
||||
```javascript
|
||||
// const and let only exist in the blocks they are defined in.
|
||||
{
|
||||
let a = 1;
|
||||
const b = 1;
|
||||
var c = 1;
|
||||
}
|
||||
console.log(a); // ReferenceError
|
||||
console.log(b); // ReferenceError
|
||||
console.log(c); // Prints 1
|
||||
```
|
||||
|
||||
In the above code, you can see that referencing `a` and `b` will produce a ReferenceError, while `c` contains the number. This is because `a` and `b` are block scoped, while `c` is scoped to the containing function.
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Objects
|
||||
@@ -217,7 +222,7 @@ Other Style Guides
|
||||
<a name="es6-object-concise"></a><a name="3.6"></a>
|
||||
- [3.4](#es6-object-concise) Use property value shorthand. eslint: [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand.html)
|
||||
|
||||
> Why? It is shorter to write and descriptive.
|
||||
> Why? It is shorter and descriptive.
|
||||
|
||||
```javascript
|
||||
const lukeSkywalker = 'Luke Skywalker';
|
||||
@@ -285,7 +290,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="objects--prototype-builtins"></a>
|
||||
- [3.7](#objects--prototype-builtins) Do not call `Object.prototype` methods directly, such as `hasOwnProperty`, `propertyIsEnumerable`, and `isPrototypeOf`.
|
||||
- [3.7](#objects--prototype-builtins) Do not call `Object.prototype` methods directly, such as `hasOwnProperty`, `propertyIsEnumerable`, and `isPrototypeOf`. eslint: [`no-prototype-builtins`](https://eslint.org/docs/rules/no-prototype-builtins)
|
||||
|
||||
> Why? These methods may be shadowed by properties on the object in question - consider `{ hasOwnProperty: false }` - or, the object may be a null object (`Object.create(null)`).
|
||||
|
||||
@@ -298,14 +303,14 @@ Other Style Guides
|
||||
|
||||
// best
|
||||
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
|
||||
console.log(has.call(object, key));
|
||||
/* or */
|
||||
import has from 'has'; // https://www.npmjs.com/package/has
|
||||
// ...
|
||||
console.log(has.call(object, key));
|
||||
console.log(has(object, key));
|
||||
```
|
||||
|
||||
<a name="objects--rest-spread"></a>
|
||||
- [3.8](#objects--rest-spread) Prefer the object spread operator over [`Object.assign`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) to shallow-copy objects. Use the object rest operator to get a new object with certain properties omitted.
|
||||
- [3.8](#objects--rest-spread) Prefer the object spread syntax over [`Object.assign`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) to shallow-copy objects. Use the object rest parameter syntax to get a new object with certain properties omitted. eslint: [`prefer-object-spread`](https://eslint.org/docs/rules/prefer-object-spread)
|
||||
|
||||
```javascript
|
||||
// very bad
|
||||
@@ -418,18 +423,16 @@ Other Style Guides
|
||||
});
|
||||
|
||||
// good
|
||||
[1, 2, 3].map(x => x + 1);
|
||||
[1, 2, 3].map((x) => x + 1);
|
||||
|
||||
// bad - no returned value means `acc` becomes undefined after the first iteration
|
||||
[[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
|
||||
const flatten = acc.concat(item);
|
||||
acc[index] = flatten;
|
||||
});
|
||||
|
||||
// good
|
||||
[[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
|
||||
const flatten = acc.concat(item);
|
||||
acc[index] = flatten;
|
||||
return flatten;
|
||||
});
|
||||
|
||||
@@ -498,7 +501,7 @@ Other Style Guides
|
||||
<a name="destructuring--object"></a><a name="5.1"></a>
|
||||
- [5.1](#destructuring--object) Use object destructuring when accessing and using multiple properties of an object. eslint: [`prefer-destructuring`](https://eslint.org/docs/rules/prefer-destructuring)
|
||||
|
||||
> Why? Destructuring saves you from creating temporary references for those properties.
|
||||
> Why? Destructuring saves you from creating temporary references for those properties, and from repetitive access of the object. Repeating object access creates more repetitive code, requires more reading, and creates more opportunities for mistakes. Destructuring objects also provides a single site of definition of the object structure that is used in the block, rather than requiring reading the entire block to determine what is used.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -650,7 +653,7 @@ Other Style Guides
|
||||
<a name="functions--declarations"></a><a name="7.1"></a>
|
||||
- [7.1](#functions--declarations) Use named function expressions instead of function declarations. eslint: [`func-style`](https://eslint.org/docs/rules/func-style)
|
||||
|
||||
> Why? Function declarations are hoisted, which means that it’s easy - too easy - to reference the function before it is defined in the file. This harms readability and maintainability. If you find that a function’s definition is large or complex enough that it is interfering with understanding the rest of the file, then perhaps it’s time to extract it to its own module! Don’t forget to explicitly name the expression, regardless of whether or not the name is inferred from the containing variable (which is often the case in modern browsers or when using compilers such as Babel). This eliminates any assumptions made about the Error's call stack. ([Discussion](https://github.com/airbnb/javascript/issues/794))
|
||||
> Why? Function declarations are hoisted, which means that it’s easy - too easy - to reference the function before it is defined in the file. This harms readability and maintainability. If you find that a function’s definition is large or complex enough that it is interfering with understanding the rest of the file, then perhaps it’s time to extract it to its own module! Don’t forget to explicitly name the expression, regardless of whether or not the name is inferred from the containing variable (which is often the case in modern browsers or when using compilers such as Babel). This eliminates any assumptions made about the Error’s call stack. ([Discussion](https://github.com/airbnb/javascript/issues/794))
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -783,7 +786,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="functions--defaults-last"></a><a name="7.9"></a>
|
||||
- [7.9](#functions--defaults-last) Always put default parameters last.
|
||||
- [7.9](#functions--defaults-last) Always put default parameters last. eslint: [`default-param-last`](https://eslint.org/docs/rules/default-param-last)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -872,7 +875,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="functions--spread-vs-apply"></a><a name="7.14"></a>
|
||||
- [7.14](#functions--spread-vs-apply) Prefer the use of the spread operator `...` to call variadic functions. eslint: [`prefer-spread`](https://eslint.org/docs/rules/prefer-spread)
|
||||
- [7.14](#functions--spread-vs-apply) Prefer the use of the spread syntax `...` to call variadic functions. eslint: [`prefer-spread`](https://eslint.org/docs/rules/prefer-spread)
|
||||
|
||||
> Why? It’s cleaner, you don’t need to supply a context, and you can not easily compose `new` with `apply`.
|
||||
|
||||
@@ -957,13 +960,13 @@ Other Style Guides
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
[1, 2, 3].map(number => {
|
||||
[1, 2, 3].map((number) => {
|
||||
const nextNumber = number + 1;
|
||||
`A string containing the ${nextNumber}.`;
|
||||
});
|
||||
|
||||
// good
|
||||
[1, 2, 3].map(number => `A string containing the ${number}.`);
|
||||
[1, 2, 3].map((number) => `A string containing the ${number + 1}.`);
|
||||
|
||||
// good
|
||||
[1, 2, 3].map((number) => {
|
||||
@@ -1002,14 +1005,14 @@ Other Style Guides
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(
|
||||
['get', 'post', 'put'].map((httpMethod) => Object.prototype.hasOwnProperty.call(
|
||||
httpMagicObjectWithAVeryLongName,
|
||||
httpMethod,
|
||||
)
|
||||
);
|
||||
|
||||
// good
|
||||
['get', 'post', 'put'].map(httpMethod => (
|
||||
['get', 'post', 'put'].map((httpMethod) => (
|
||||
Object.prototype.hasOwnProperty.call(
|
||||
httpMagicObjectWithAVeryLongName,
|
||||
httpMethod,
|
||||
@@ -1018,22 +1021,27 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="arrows--one-arg-parens"></a><a name="8.4"></a>
|
||||
- [8.4](#arrows--one-arg-parens) If your function takes a single argument and doesn’t use braces, omit the parentheses. Otherwise, always include parentheses around arguments for clarity and consistency. Note: it is also acceptable to always use parentheses, in which case use the [“always” option](https://eslint.org/docs/rules/arrow-parens#always) for eslint. eslint: [`arrow-parens`](https://eslint.org/docs/rules/arrow-parens.html)
|
||||
- [8.4](#arrows--one-arg-parens) Always include parentheses around arguments for clarity and consistency. eslint: [`arrow-parens`](https://eslint.org/docs/rules/arrow-parens.html)
|
||||
|
||||
> Why? Less visual clutter.
|
||||
> Why? Minimizes diff churn when adding or removing arguments.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
[1, 2, 3].map((x) => x * x);
|
||||
|
||||
// good
|
||||
[1, 2, 3].map(x => x * x);
|
||||
|
||||
// good
|
||||
[1, 2, 3].map((x) => x * x);
|
||||
|
||||
// bad
|
||||
[1, 2, 3].map(number => (
|
||||
`A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`
|
||||
));
|
||||
|
||||
// good
|
||||
[1, 2, 3].map((number) => (
|
||||
`A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`
|
||||
));
|
||||
|
||||
// bad
|
||||
[1, 2, 3].map(x => {
|
||||
const y = x + 1;
|
||||
@@ -1052,18 +1060,18 @@ Other Style Guides
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
|
||||
const itemHeight = (item) => item.height <= 256 ? item.largeSize : item.smallSize;
|
||||
|
||||
// bad
|
||||
const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
|
||||
const itemHeight = (item) => item.height >= 256 ? item.largeSize : item.smallSize;
|
||||
|
||||
// good
|
||||
const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize);
|
||||
const itemHeight = (item) => (item.height <= 256 ? item.largeSize : item.smallSize);
|
||||
|
||||
// good
|
||||
const itemHeight = (item) => {
|
||||
const { height, largeSize, smallSize } = item;
|
||||
return height > 256 ? largeSize : smallSize;
|
||||
return height <= 256 ? largeSize : smallSize;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -1251,6 +1259,39 @@ Other Style Guides
|
||||
}
|
||||
```
|
||||
|
||||
<a name="classes--methods-use-this"></a>
|
||||
- [9.7](#classes--methods-use-this) Class methods should use `this` or be made into a static method unless an external library or framework requires using specific non-static methods. Being an instance method should indicate that it behaves differently based on properties of the receiver. eslint: [`class-methods-use-this`](https://eslint.org/docs/rules/class-methods-use-this)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
class Foo {
|
||||
bar() {
|
||||
console.log('bar');
|
||||
}
|
||||
}
|
||||
|
||||
// good - this is used
|
||||
class Foo {
|
||||
bar() {
|
||||
console.log(this.bar);
|
||||
}
|
||||
}
|
||||
|
||||
// good - constructor is exempt
|
||||
class Foo {
|
||||
constructor() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// good - static methods aren't expected to use this
|
||||
class Foo {
|
||||
static bar() {
|
||||
console.log('bar');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Modules
|
||||
@@ -1373,6 +1414,7 @@ Other Style Guides
|
||||
|
||||
<a name="modules--multiline-imports-over-newlines"></a>
|
||||
- [10.8](#modules--multiline-imports-over-newlines) Multiline imports should be indented just like multiline array and object literals.
|
||||
eslint: [`object-curly-newline`](https://eslint.org/docs/rules/object-curly-newline)
|
||||
|
||||
> Why? The curly braces follow the same indentation rules as every other curly brace block in the style guide, as do the trailing commas.
|
||||
|
||||
@@ -1405,6 +1447,23 @@ Other Style Guides
|
||||
import barCss from 'bar.css';
|
||||
```
|
||||
|
||||
<a name="modules--import-extensions"></a>
|
||||
- [10.10](#modules--import-extensions) Do not include JavaScript filename extensions
|
||||
eslint: [`import/extensions`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md)
|
||||
> Why? Including extensions inhibits refactoring, and inappropriately hardcodes implementation details of the module you're importing in every consumer.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
import foo from './foo.js';
|
||||
import bar from './bar.jsx';
|
||||
import baz from './baz/index.jsx';
|
||||
|
||||
// good
|
||||
import foo from './foo';
|
||||
import bar from './bar';
|
||||
import baz from './baz';
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
## Iterators and Generators
|
||||
@@ -1450,7 +1509,7 @@ Other Style Guides
|
||||
});
|
||||
|
||||
// best (keeping it functional)
|
||||
const increasedByOne = numbers.map(num => num + 1);
|
||||
const increasedByOne = numbers.map((num) => num + 1);
|
||||
```
|
||||
|
||||
<a name="generators--nope"></a><a name="11.2"></a>
|
||||
@@ -1554,6 +1613,7 @@ Other Style Guides
|
||||
|
||||
const isJedi = getProp('jedi');
|
||||
```
|
||||
|
||||
<a name="es2016-properties--exponentiation-operator"></a>
|
||||
- [12.3](#es2016-properties--exponentiation-operator) Use exponentiation operator `**` when calculating exponentiations. eslint: [`no-restricted-properties`](https://eslint.org/docs/rules/no-restricted-properties).
|
||||
|
||||
@@ -1581,7 +1641,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="variables--one-const"></a><a name="13.2"></a>
|
||||
- [13.2](#variables--one-const) Use one `const` or `let` declaration per variable. eslint: [`one-var`](https://eslint.org/docs/rules/one-var.html)
|
||||
- [13.2](#variables--one-const) Use one `const` or `let` declaration per variable or assignment. eslint: [`one-var`](https://eslint.org/docs/rules/one-var.html)
|
||||
|
||||
> Why? It’s easier to add new variable declarations this way, and you never have to worry about swapping out a `;` for a `,` or introducing punctuation-only diffs. You can also step through each declaration with the debugger, instead of jumping through all of them at once.
|
||||
|
||||
@@ -1606,7 +1666,7 @@ Other Style Guides
|
||||
<a name="variables--const-let-group"></a><a name="13.3"></a>
|
||||
- [13.3](#variables--const-let-group) Group all your `const`s and then group all your `let`s.
|
||||
|
||||
> Why? This is helpful when later on you might need to assign a variable depending on one of the previous assigned variables.
|
||||
> Why? This is helpful when later on you might need to assign a variable depending on one of the previously assigned variables.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -1667,6 +1727,7 @@ Other Style Guides
|
||||
return name;
|
||||
}
|
||||
```
|
||||
|
||||
<a name="variables--no-chain-assignment"></a><a name="13.5"></a>
|
||||
- [13.5](#variables--no-chain-assignment) Don’t chain variable assignments. eslint: [`no-multi-assign`](https://eslint.org/docs/rules/no-multi-assign)
|
||||
|
||||
@@ -1802,7 +1863,7 @@ Other Style Guides
|
||||
## Hoisting
|
||||
|
||||
<a name="hoisting--about"></a><a name="14.1"></a>
|
||||
- [14.1](#hoisting--about) `var` declarations get hoisted to the top of their closest enclosing function scope, their assignment does not. `const` and `let` declarations are blessed with a new concept called [Temporal Dead Zones (TDZ)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone). It’s important to know why [typeof is no longer safe](http://es-discourse.com/t/why-typeof-is-no-longer-safe/15).
|
||||
- [14.1](#hoisting--about) `var` declarations get hoisted to the top of their closest enclosing function scope, their assignment does not. `const` and `let` declarations are blessed with a new concept called [Temporal Dead Zones (TDZ)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#temporal_dead_zone_tdz). It’s important to know why [typeof is no longer safe](https://web.archive.org/web/20200121061528/http://es-discourse.com/t/why-typeof-is-no-longer-safe/15).
|
||||
|
||||
```javascript
|
||||
// we know this wouldn’t work (assuming there
|
||||
@@ -1894,7 +1955,7 @@ Other Style Guides
|
||||
}
|
||||
```
|
||||
|
||||
- For more information refer to [JavaScript Scoping & Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting/) by [Ben Cherry](http://www.adequatelygood.com/).
|
||||
- For more information refer to [JavaScript Scoping & Hoisting](https://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting/) by [Ben Cherry](https://www.adequatelygood.com/).
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
|
||||
@@ -2043,7 +2104,8 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="comparison--no-mixed-operators"></a>
|
||||
- [15.8](#comparison--no-mixed-operators) When mixing operators, enclose them in parentheses. The only exception is the standard arithmetic operators (`+`, `-`, `*`, & `/`) since their precedence is broadly understood. eslint: [`no-mixed-operators`](https://eslint.org/docs/rules/no-mixed-operators.html)
|
||||
- [15.8](#comparison--no-mixed-operators) When mixing operators, enclose them in parentheses. The only exception is the standard arithmetic operators: `+`, `-`, and `**` since their precedence is broadly understood. We recommend enclosing `/` and `*` in parentheses because their precedence can be ambiguous when they are mixed.
|
||||
eslint: [`no-mixed-operators`](https://eslint.org/docs/rules/no-mixed-operators.html)
|
||||
|
||||
> Why? This improves readability and clarifies the developer’s intention.
|
||||
|
||||
@@ -2060,11 +2122,14 @@ Other Style Guides
|
||||
return d;
|
||||
}
|
||||
|
||||
// bad
|
||||
const bar = a + b / c * d;
|
||||
|
||||
// good
|
||||
const foo = (a && b < 0) || c > 0 || (d + 1 === 0);
|
||||
|
||||
// good
|
||||
const bar = (a ** b) - (5 % d);
|
||||
const bar = a ** b - (5 % d);
|
||||
|
||||
// good
|
||||
if (a || (b && c)) {
|
||||
@@ -2072,7 +2137,7 @@ Other Style Guides
|
||||
}
|
||||
|
||||
// good
|
||||
const bar = a + b / c * d;
|
||||
const bar = a + (b / c) * d;
|
||||
```
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
@@ -2080,7 +2145,7 @@ Other Style Guides
|
||||
## Blocks
|
||||
|
||||
<a name="blocks--braces"></a><a name="16.1"></a>
|
||||
- [16.1](#blocks--braces) Use braces with all multi-line blocks. eslint: [`nonblock-statement-body-position`](https://eslint.org/docs/rules/nonblock-statement-body-position)
|
||||
- [16.1](#blocks--braces) Use braces with all multiline blocks. eslint: [`nonblock-statement-body-position`](https://eslint.org/docs/rules/nonblock-statement-body-position)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2105,7 +2170,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="blocks--cuddled-elses"></a><a name="16.2"></a>
|
||||
- [16.2](#blocks--cuddled-elses) If you're using multi-line blocks with `if` and `else`, put `else` on the same line as your `if` block’s closing brace. eslint: [`brace-style`](https://eslint.org/docs/rules/brace-style.html)
|
||||
- [16.2](#blocks--cuddled-elses) If you’re using multiline blocks with `if` and `else`, put `else` on the same line as your `if` block’s closing brace. eslint: [`brace-style`](https://eslint.org/docs/rules/brace-style.html)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2249,7 +2314,7 @@ Other Style Guides
|
||||
}
|
||||
```
|
||||
|
||||
<a name="control-statement--value-selection"></a>
|
||||
<a name="control-statement--value-selection"></a><a name="control-statements--value-selection"></a>
|
||||
- [17.2](#control-statements--value-selection) Don't use selection operators in place of control statements.
|
||||
|
||||
```javascript
|
||||
@@ -2267,7 +2332,7 @@ Other Style Guides
|
||||
## Comments
|
||||
|
||||
<a name="comments--multiline"></a><a name="17.1"></a>
|
||||
- [18.1](#comments--multiline) Use `/** ... */` for multi-line comments.
|
||||
- [18.1](#comments--multiline) Use `/** ... */` for multiline comments.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2373,7 +2438,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="comments--actionitems"></a><a name="17.3"></a>
|
||||
- [18.4](#comments--actionitems) Prefixing your comments with `FIXME` or `TODO` helps other developers quickly understand if you're pointing out a problem that needs to be revisited, or if you're suggesting a solution to the problem that needs to be implemented. These are different than regular comments because they are actionable. The actions are `FIXME: -- need to figure this out` or `TODO: -- need to implement`.
|
||||
- [18.4](#comments--actionitems) Prefixing your comments with `FIXME` or `TODO` helps other developers quickly understand if you’re pointing out a problem that needs to be revisited, or if you’re suggesting a solution to the problem that needs to be implemented. These are different than regular comments because they are actionable. The actions are `FIXME: -- need to figure this out` or `TODO: -- need to implement`.
|
||||
|
||||
<a name="comments--fixme"></a><a name="17.4"></a>
|
||||
- [18.5](#comments--fixme) Use `// FIXME:` to annotate problems.
|
||||
@@ -2557,6 +2622,10 @@ Other Style Guides
|
||||
|
||||
// good
|
||||
const leds = stage.selectAll('.led').data(data);
|
||||
const svg = leds.enter().append('svg:svg');
|
||||
svg.classed('led', true).attr('width', (radius + margin) * 2);
|
||||
const g = svg.append('svg:g');
|
||||
g.attr('transform', `translate(${radius + margin},${radius + margin})`).call(tron.led);
|
||||
```
|
||||
|
||||
<a name="whitespace--after-blocks"></a><a name="18.7"></a>
|
||||
@@ -2658,8 +2727,62 @@ Other Style Guides
|
||||
}
|
||||
```
|
||||
|
||||
<a name="whitespace--no-multiple-blanks"></a>
|
||||
- [19.9](#whitespace--no-multiple-blanks) Do not use multiple blank lines to pad your code. eslint: [`no-multiple-empty-lines`](https://eslint.org/docs/rules/no-multiple-empty-lines)
|
||||
|
||||
<!-- markdownlint-disable MD012 -->
|
||||
```javascript
|
||||
// bad
|
||||
class Person {
|
||||
constructor(fullName, email, birthday) {
|
||||
this.fullName = fullName;
|
||||
|
||||
|
||||
this.email = email;
|
||||
|
||||
|
||||
this.setAge(birthday);
|
||||
}
|
||||
|
||||
|
||||
setAge(birthday) {
|
||||
const today = new Date();
|
||||
|
||||
|
||||
const age = this.getAge(today, birthday);
|
||||
|
||||
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
|
||||
getAge(today, birthday) {
|
||||
// ..
|
||||
}
|
||||
}
|
||||
|
||||
// good
|
||||
class Person {
|
||||
constructor(fullName, email, birthday) {
|
||||
this.fullName = fullName;
|
||||
this.email = email;
|
||||
this.setAge(birthday);
|
||||
}
|
||||
|
||||
setAge(birthday) {
|
||||
const today = new Date();
|
||||
const age = getAge(today, birthday);
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
getAge(today, birthday) {
|
||||
// ..
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<a name="whitespace--in-parens"></a><a name="18.9"></a>
|
||||
- [19.9](#whitespace--in-parens) Do not add spaces inside parentheses. eslint: [`space-in-parens`](https://eslint.org/docs/rules/space-in-parens.html)
|
||||
- [19.10](#whitespace--in-parens) Do not add spaces inside parentheses. eslint: [`space-in-parens`](https://eslint.org/docs/rules/space-in-parens.html)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2684,7 +2807,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="whitespace--in-brackets"></a><a name="18.10"></a>
|
||||
- [19.10](#whitespace--in-brackets) Do not add spaces inside brackets. eslint: [`array-bracket-spacing`](https://eslint.org/docs/rules/array-bracket-spacing.html)
|
||||
- [19.11](#whitespace--in-brackets) Do not add spaces inside brackets. eslint: [`array-bracket-spacing`](https://eslint.org/docs/rules/array-bracket-spacing.html)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2697,7 +2820,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="whitespace--in-braces"></a><a name="18.11"></a>
|
||||
- [19.11](#whitespace--in-braces) Add spaces inside curly braces. eslint: [`object-curly-spacing`](https://eslint.org/docs/rules/object-curly-spacing.html)
|
||||
- [19.12](#whitespace--in-braces) Add spaces inside curly braces. eslint: [`object-curly-spacing`](https://eslint.org/docs/rules/object-curly-spacing.html)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2708,7 +2831,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="whitespace--max-len"></a><a name="18.12"></a>
|
||||
- [19.12](#whitespace--max-len) Avoid having lines of code that are longer than 100 characters (including whitespace). Note: per [above](#strings--line-length), long strings are exempt from this rule, and should not be broken up. eslint: [`max-len`](https://eslint.org/docs/rules/max-len.html)
|
||||
- [19.13](#whitespace--max-len) Avoid having lines of code that are longer than 100 characters (including whitespace). Note: per [above](#strings--line-length), long strings are exempt from this rule, and should not be broken up. eslint: [`max-len`](https://eslint.org/docs/rules/max-len.html)
|
||||
|
||||
> Why? This ensures readability and maintainability.
|
||||
|
||||
@@ -2738,7 +2861,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="whitespace--block-spacing"></a>
|
||||
- [19.13](#whitespace--block-spacing) Require consistent spacing inside an open block token and the next token on the same line. This rule also enforces consistent spacing inside a close block token and previous token on the same line. eslint: [`block-spacing`](https://eslint.org/docs/rules/block-spacing)
|
||||
- [19.14](#whitespace--block-spacing) Require consistent spacing inside an open block token and the next token on the same line. This rule also enforces consistent spacing inside a close block token and previous token on the same line. eslint: [`block-spacing`](https://eslint.org/docs/rules/block-spacing)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2751,7 +2874,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="whitespace--comma-spacing"></a>
|
||||
- [19.14](#whitespace--comma-spacing) Avoid spaces before commas and require a space after commas. eslint: [`comma-spacing`](https://eslint.org/docs/rules/comma-spacing)
|
||||
- [19.15](#whitespace--comma-spacing) Avoid spaces before commas and require a space after commas. eslint: [`comma-spacing`](https://eslint.org/docs/rules/comma-spacing)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2764,7 +2887,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="whitespace--computed-property-spacing"></a>
|
||||
- [19.15](#whitespace--computed-property-spacing) Enforce spacing inside of computed properties. eslint: [`computed-property-spacing`](https://eslint.org/docs/rules/computed-property-spacing)
|
||||
- [19.16](#whitespace--computed-property-spacing) Enforce spacing inside of computed property brackets. eslint: [`computed-property-spacing`](https://eslint.org/docs/rules/computed-property-spacing)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2781,7 +2904,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="whitespace--func-call-spacing"></a>
|
||||
- [19.16](#whitespace--func-call-spacing) Enforce spacing between functions and their invocations. eslint: [`func-call-spacing`](https://eslint.org/docs/rules/func-call-spacing)
|
||||
- [19.17](#whitespace--func-call-spacing) Avoid spaces between functions and their invocations. eslint: [`func-call-spacing`](https://eslint.org/docs/rules/func-call-spacing)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -2795,36 +2918,45 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="whitespace--key-spacing"></a>
|
||||
- [19.17](#whitespace--key-spacing) Enforce spacing between keys and values in object literal properties. eslint: [`key-spacing`](https://eslint.org/docs/rules/key-spacing)
|
||||
- [19.18](#whitespace--key-spacing) Enforce spacing between keys and values in object literal properties. eslint: [`key-spacing`](https://eslint.org/docs/rules/key-spacing)
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
var obj = { "foo" : 42 };
|
||||
var obj2 = { "foo":42 };
|
||||
var obj = { foo : 42 };
|
||||
var obj2 = { foo:42 };
|
||||
|
||||
// good
|
||||
var obj = { "foo": 42 };
|
||||
var obj = { foo: 42 };
|
||||
```
|
||||
|
||||
<a name="whitespace--no-trailing-spaces"></a>
|
||||
- [19.18](#whitespace--no-trailing-spaces) Avoid trailing spaces at the end of lines. eslint: [`no-trailing-spaces`](https://eslint.org/docs/rules/no-trailing-spaces)
|
||||
- [19.19](#whitespace--no-trailing-spaces) Avoid trailing spaces at the end of lines. eslint: [`no-trailing-spaces`](https://eslint.org/docs/rules/no-trailing-spaces)
|
||||
|
||||
<a name="whitespace--no-multiple-empty-lines"></a>
|
||||
- [19.19](#whitespace--no-multiple-empty-lines) Avoid multiple empty lines and only allow one newline at the end of files. eslint: [`no-multiple-empty-lines`](https://eslint.org/docs/rules/no-multiple-empty-lines)
|
||||
- [19.20](#whitespace--no-multiple-empty-lines) Avoid multiple empty lines, only allow one newline at the end of files, and avoid a newline at the beginning of files. eslint: [`no-multiple-empty-lines`](https://eslint.org/docs/rules/no-multiple-empty-lines)
|
||||
|
||||
<!-- markdownlint-disable MD012 -->
|
||||
```javascript
|
||||
// bad
|
||||
// bad - multiple empty lines
|
||||
var x = 1;
|
||||
|
||||
|
||||
var y = 2;
|
||||
|
||||
// bad - 2+ newlines at end of file
|
||||
var x = 1;
|
||||
var y = 2;
|
||||
|
||||
|
||||
// bad - 1+ newline(s) at beginning of file
|
||||
|
||||
var x = 1;
|
||||
var y = 2;
|
||||
|
||||
// good
|
||||
var x = 1;
|
||||
|
||||
var y = 2;
|
||||
|
||||
```
|
||||
<!-- markdownlint-enable MD012 -->
|
||||
|
||||
@@ -2970,16 +3102,16 @@ Other Style Guides
|
||||
<a name="semicolons--required"></a><a name="20.1"></a>
|
||||
- [21.1](#semicolons--required) **Yup.** eslint: [`semi`](https://eslint.org/docs/rules/semi.html)
|
||||
|
||||
> Why? When JavaScript encounters a line break without a semicolon, it uses a set of rules called [Automatic Semicolon Insertion](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion) to determine whether or not it should regard that line break as the end of a statement, and (as the name implies) place a semicolon into your code before the line break if it thinks so. ASI contains a few eccentric behaviors, though, and your code will break if JavaScript misinterprets your line break. These rules will become more complicated as new features become a part of JavaScript. Explicitly terminating your statements and configuring your linter to catch missing semicolons will help prevent you from encountering issues.
|
||||
> Why? When JavaScript encounters a line break without a semicolon, it uses a set of rules called [Automatic Semicolon Insertion](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion) to determine whether it should regard that line break as the end of a statement, and (as the name implies) place a semicolon into your code before the line break if it thinks so. ASI contains a few eccentric behaviors, though, and your code will break if JavaScript misinterprets your line break. These rules will become more complicated as new features become a part of JavaScript. Explicitly terminating your statements and configuring your linter to catch missing semicolons will help prevent you from encountering issues.
|
||||
|
||||
```javascript
|
||||
// bad - raises exception
|
||||
const luke = {}
|
||||
const leia = {}
|
||||
[luke, leia].forEach(jedi => jedi.father = 'vader')
|
||||
[luke, leia].forEach((jedi) => jedi.father = 'vader')
|
||||
|
||||
// bad - raises exception
|
||||
const reaction = "No! That's impossible!"
|
||||
const reaction = "No! That’s impossible!"
|
||||
(async function meanwhileOnTheFalcon() {
|
||||
// handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
|
||||
// ...
|
||||
@@ -2999,7 +3131,7 @@ Other Style Guides
|
||||
});
|
||||
|
||||
// good
|
||||
const reaction = "No! That's impossible!";
|
||||
const reaction = "No! That’s impossible!";
|
||||
(async function meanwhileOnTheFalcon() {
|
||||
// handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
|
||||
// ...
|
||||
@@ -3021,7 +3153,7 @@ Other Style Guides
|
||||
- [22.1](#coercion--explicit) Perform type coercion at the beginning of the statement.
|
||||
|
||||
<a name="coercion--strings"></a><a name="21.2"></a>
|
||||
- [22.2](#coercion--strings) Strings: eslint: [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
|
||||
- [22.2](#coercion--strings) Strings: eslint: [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
|
||||
|
||||
```javascript
|
||||
// => this.reviewScore = 9;
|
||||
@@ -3042,6 +3174,8 @@ Other Style Guides
|
||||
<a name="coercion--numbers"></a><a name="21.3"></a>
|
||||
- [22.3](#coercion--numbers) Numbers: Use `Number` for type casting and `parseInt` always with a radix for parsing strings. eslint: [`radix`](https://eslint.org/docs/rules/radix) [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
|
||||
|
||||
> Why? The `parseInt` function produces an integer value dictated by interpretation of the contents of the string argument according to the specified radix. Leading whitespace in string is ignored. If radix is `undefined` or `0`, it is assumed to be `10` except when the number begins with the character pairs `0x` or `0X`, in which case a radix of 16 is assumed. This differs from ECMAScript 3, which merely discouraged (but allowed) octal interpretation. Many implementations have not adopted this behavior as of 2013. And, because older browsers must be supported, always specify a radix.
|
||||
|
||||
```javascript
|
||||
const inputValue = '4';
|
||||
|
||||
@@ -3065,7 +3199,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="coercion--comment-deviations"></a><a name="21.4"></a>
|
||||
- [22.4](#coercion--comment-deviations) If for whatever reason you are doing something wild and `parseInt` is your bottleneck and need to use Bitshift for [performance reasons](https://jsperf.com/coercion-vs-casting/3), leave a comment explaining why and what you're doing.
|
||||
- [22.4](#coercion--comment-deviations) If for whatever reason you are doing something wild and `parseInt` is your bottleneck and need to use Bitshift for [performance reasons](https://jsperf.com/coercion-vs-casting/3), leave a comment explaining why and what you’re doing.
|
||||
|
||||
```javascript
|
||||
// good
|
||||
@@ -3268,7 +3402,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="naming--Acronyms-and-Initialisms"></a>
|
||||
- [23.9](#naming--Acronyms-and-Initialisms) Acronyms and initialisms should always be all capitalized, or all lowercased.
|
||||
- [23.9](#naming--Acronyms-and-Initialisms) Acronyms and initialisms should always be all uppercased, or all lowercased.
|
||||
|
||||
> Why? Names are for readability, not to appease a computer algorithm.
|
||||
|
||||
@@ -3308,7 +3442,7 @@ Other Style Guides
|
||||
|
||||
> Why? This is an additional tool to assist in situations where the programmer would be unsure if a variable might ever change. UPPERCASE_VARIABLES are letting the programmer know that they can trust the variable (and its properties) not to change.
|
||||
- What about all `const` variables? - This is unnecessary, so uppercasing should not be used for constants within a file. It should be used for exported constants however.
|
||||
- What about exported objects? - Uppercase at the top level of export (e.g. `EXPORTED_OBJECT.key`) and maintain that all nested properties do not change.
|
||||
- What about exported objects? - Uppercase at the top level of export (e.g. `EXPORTED_OBJECT.key`) and maintain that all nested properties do not change.
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -3415,7 +3549,7 @@ Other Style Guides
|
||||
## Events
|
||||
|
||||
<a name="events--hash"></a><a name="24.1"></a>
|
||||
- [25.1](#events--hash) When attaching data payloads to events (whether DOM events or something more proprietary like Backbone events), pass an object literal (also known as a "hash") instead of a raw value. This allows a subsequent contributor to add more data to the event payload without finding and updating every handler for the event. For example, instead of:
|
||||
- [25.1](#events--hash) When attaching data payloads to events (whether DOM events or something more proprietary like Backbone events), pass an object literal (also known as a "hash") instead of a raw value. This allows a subsequent contributor to add more data to the event payload without finding and updating every handler for the event. For example, instead of:
|
||||
|
||||
```javascript
|
||||
// bad
|
||||
@@ -3488,7 +3622,7 @@ Other Style Guides
|
||||
```
|
||||
|
||||
<a name="jquery--queries"></a><a name="25.3"></a>
|
||||
- [26.3](#jquery--queries) For DOM queries use Cascading `$('.sidebar ul')` or parent > child `$('.sidebar > ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16)
|
||||
- [26.3](#jquery--queries) For DOM queries use Cascading `$('.sidebar ul')` or parent > child `$('.sidebar > ul')`. [jsPerf](https://jsperf.com/jquery-find-vs-context-sel/16)
|
||||
|
||||
<a name="jquery--find"></a><a name="25.4"></a>
|
||||
- [26.4](#jquery--find) Use `find` with scoped jQuery object queries.
|
||||
@@ -3613,12 +3747,12 @@ Other Style Guides
|
||||
|
||||
- [On Layout & Web Performance](https://www.kellegous.com/j/2013/01/26/layout-performance/)
|
||||
- [String vs Array Concat](https://jsperf.com/string-vs-array-concat/2)
|
||||
- [Try/Catch Cost In a Loop](https://jsperf.com/try-catch-in-loop-cost)
|
||||
- [Try/Catch Cost In a Loop](https://jsperf.com/try-catch-in-loop-cost/12)
|
||||
- [Bang Function](https://jsperf.com/bang-function)
|
||||
- [jQuery Find vs Context, Selector](https://jsperf.com/jquery-find-vs-context-sel/13)
|
||||
- [jQuery Find vs Context, Selector](https://jsperf.com/jquery-find-vs-context-sel/164)
|
||||
- [innerHTML vs textContent for script text](https://jsperf.com/innerhtml-vs-textcontent-for-script-text)
|
||||
- [Long String Concatenation](https://jsperf.com/ya-string-concat)
|
||||
- [Are Javascript functions like `map()`, `reduce()`, and `filter()` optimized for traversing arrays?](https://www.quora.com/JavaScript-programming-language-Are-Javascript-functions-like-map-reduce-and-filter-already-optimized-for-traversing-array/answer/Quildreen-Motta)
|
||||
- [Long String Concatenation](https://jsperf.com/ya-string-concat/38)
|
||||
- [Are JavaScript functions like `map()`, `reduce()`, and `filter()` optimized for traversing arrays?](https://www.quora.com/JavaScript-programming-language-Are-Javascript-functions-like-map-reduce-and-filter-already-optimized-for-traversing-array/answer/Quildreen-Motta)
|
||||
- Loading...
|
||||
|
||||
**[⬆ back to top](#table-of-contents)**
|
||||
@@ -3628,24 +3762,25 @@ Other Style Guides
|
||||
**Learning ES6+**
|
||||
|
||||
- [Latest ECMA spec](https://tc39.github.io/ecma262/)
|
||||
- [ExploringJS](http://exploringjs.com/)
|
||||
- [ExploringJS](https://exploringjs.com/)
|
||||
- [ES6 Compatibility Table](https://kangax.github.io/compat-table/es6/)
|
||||
- [Comprehensive Overview of ES6 Features](http://es6-features.org/)
|
||||
|
||||
**Read This**
|
||||
|
||||
- [Standard ECMA-262](http://www.ecma-international.org/ecma-262/6.0/index.html)
|
||||
- [Standard ECMA-262](https://www.ecma-international.org/ecma-262/6.0/index.html)
|
||||
|
||||
**Tools**
|
||||
|
||||
- Code Style Linters
|
||||
- [ESlint](https://eslint.org/) - [Airbnb Style .eslintrc](https://github.com/airbnb/javascript/blob/master/linters/.eslintrc)
|
||||
- [JSHint](http://jshint.com/) - [Airbnb Style .jshintrc](https://github.com/airbnb/javascript/blob/master/linters/.jshintrc)
|
||||
- Neutrino preset - [neutrino-preset-airbnb-base](https://neutrino.js.org/presets/neutrino-preset-airbnb-base/)
|
||||
- [JSHint](https://jshint.com/) - [Airbnb Style .jshintrc](https://github.com/airbnb/javascript/blob/master/linters/.jshintrc)
|
||||
- Neutrino Preset - [@neutrinojs/airbnb](https://neutrinojs.org/packages/airbnb/)
|
||||
|
||||
**Other Style Guides**
|
||||
|
||||
- [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
|
||||
- [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)
|
||||
- [Google JavaScript Style Guide (Old)](https://google.github.io/styleguide/javascriptguide.xml)
|
||||
- [jQuery Core Style Guidelines](https://contribute.jquery.org/style-guide/js/)
|
||||
- [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwaldron/idiomatic.js)
|
||||
- [StandardJS](https://standardjs.com)
|
||||
@@ -3655,13 +3790,13 @@ Other Style Guides
|
||||
- [Naming this in nested functions](https://gist.github.com/cjohansen/4135065) - Christian Johansen
|
||||
- [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52) - Ross Allen
|
||||
- [Popular JavaScript Coding Conventions on GitHub](http://sideeffect.kr/popularconvention/#javascript) - JeongHoon Byun
|
||||
- [Multiple var statements in JavaScript, not superfluous](http://benalman.com/news/2012/05/multiple-var-statements-javascript/) - Ben Alman
|
||||
- [Multiple var statements in JavaScript, not superfluous](https://benalman.com/news/2012/05/multiple-var-statements-javascript/) - Ben Alman
|
||||
|
||||
**Further Reading**
|
||||
|
||||
- [Understanding JavaScript Closures](https://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) - Angus Croll
|
||||
- [Basic JavaScript for the impatient programmer](http://www.2ality.com/2013/06/basic-javascript.html) - Dr. Axel Rauschmayer
|
||||
- [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz
|
||||
- [Basic JavaScript for the impatient programmer](https://www.2ality.com/2013/06/basic-javascript.html) - Dr. Axel Rauschmayer
|
||||
- [You Might Not Need jQuery](https://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz
|
||||
- [ES6 Features](https://github.com/lukehoban/es6features) - Luke Hoban
|
||||
- [Frontend Guidelines](https://github.com/bendc/frontend-guidelines) - Benjamin De Cock
|
||||
|
||||
@@ -3669,7 +3804,7 @@ Other Style Guides
|
||||
|
||||
- [JavaScript: The Good Parts](https://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford
|
||||
- [JavaScript Patterns](https://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov
|
||||
- [Pro JavaScript Design Patterns](https://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz
|
||||
- [Pro JavaScript Design Patterns](https://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz
|
||||
- [High Performance Web Sites: Essential Knowledge for Front-End Engineers](https://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders
|
||||
- [Maintainable JavaScript](https://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas
|
||||
- [JavaScript Web Applications](https://www.amazon.com/JavaScript-Web-Applications-Alex-MacCaw/dp/144930351X) - Alex MacCaw
|
||||
@@ -3678,23 +3813,23 @@ Other Style Guides
|
||||
- [Secrets of the JavaScript Ninja](https://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X) - John Resig and Bear Bibeault
|
||||
- [Human JavaScript](http://humanjavascript.com/) - Henrik Joreteg
|
||||
- [Superhero.js](http://superherojs.com/) - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy
|
||||
- [JSBooks](http://jsbooks.revolunet.com/) - Julien Bouquillon
|
||||
- [JSBooks](https://jsbooks.revolunet.com/) - Julien Bouquillon
|
||||
- [Third Party JavaScript](https://www.manning.com/books/third-party-javascript) - Ben Vinegar and Anton Kovalyov
|
||||
- [Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript](http://amzn.com/0321812182) - David Herman
|
||||
- [Eloquent JavaScript](http://eloquentjavascript.net/) - Marijn Haverbeke
|
||||
- [You Don’t Know JS: ES6 & Beyond](http://shop.oreilly.com/product/0636920033769.do) - Kyle Simpson
|
||||
- [Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript](https://amzn.com/0321812182) - David Herman
|
||||
- [Eloquent JavaScript](https://eloquentjavascript.net/) - Marijn Haverbeke
|
||||
- [You Don’t Know JS: ES6 & Beyond](https://shop.oreilly.com/product/0636920033769.do) - Kyle Simpson
|
||||
|
||||
**Blogs**
|
||||
|
||||
- [JavaScript Weekly](http://javascriptweekly.com/)
|
||||
- [JavaScript Weekly](https://javascriptweekly.com/)
|
||||
- [JavaScript, JavaScript...](https://javascriptweblog.wordpress.com/)
|
||||
- [Bocoup Weblog](https://bocoup.com/weblog)
|
||||
- [Adequately Good](http://www.adequatelygood.com/)
|
||||
- [Adequately Good](https://www.adequatelygood.com/)
|
||||
- [NCZOnline](https://www.nczonline.net/)
|
||||
- [Perfection Kills](http://perfectionkills.com/)
|
||||
- [Ben Alman](http://benalman.com/)
|
||||
- [Ben Alman](https://benalman.com/)
|
||||
- [Dmitry Baranovskiy](http://dmitry.baranovskiy.com/)
|
||||
- [nettuts](http://code.tutsplus.com/?s=javascript)
|
||||
- [nettuts](https://code.tutsplus.com/?s=javascript)
|
||||
|
||||
**Podcasts**
|
||||
|
||||
@@ -3708,18 +3843,15 @@ Other Style Guides
|
||||
This is a list of organizations that are using this style guide. Send us a pull request and we'll add you to the list.
|
||||
|
||||
- **123erfasst**: [123erfasst/javascript](https://github.com/123erfasst/javascript)
|
||||
- **3blades**: [3Blades](https://github.com/3blades)
|
||||
- **4Catalyzer**: [4Catalyzer/javascript](https://github.com/4Catalyzer/javascript)
|
||||
- **Aan Zee**: [AanZee/javascript](https://github.com/AanZee/javascript)
|
||||
- **Adult Swim**: [adult-swim/javascript](https://github.com/adult-swim/javascript)
|
||||
- **Airbnb**: [airbnb/javascript](https://github.com/airbnb/javascript)
|
||||
- **AloPeyk**: [AloPeyk](https://github.com/AloPeyk)
|
||||
- **AltSchool**: [AltSchool/javascript](https://github.com/AltSchool/javascript)
|
||||
- **Apartmint**: [apartmint/javascript](https://github.com/apartmint/javascript)
|
||||
- **Ascribe**: [ascribe/javascript](https://github.com/ascribe/javascript)
|
||||
- **Avalara**: [avalara/javascript](https://github.com/avalara/javascript)
|
||||
- **Avant**: [avantcredit/javascript](https://github.com/avantcredit/javascript)
|
||||
- **Axept**: [axept/javascript](https://github.com/axept/javascript)
|
||||
- **BashPros**: [BashPros/javascript](https://github.com/BashPros/javascript)
|
||||
- **Billabong**: [billabong/javascript](https://github.com/billabong/javascript)
|
||||
- **Bisk**: [bisk](https://github.com/Bisk/)
|
||||
- **Bonhomme**: [bonhommeparis/javascript](https://github.com/bonhommeparis/javascript)
|
||||
@@ -3727,18 +3859,18 @@ Other Style Guides
|
||||
- **CaseNine**: [CaseNine/javascript](https://github.com/CaseNine/javascript)
|
||||
- **Cerner**: [Cerner](https://github.com/cerner/)
|
||||
- **Chartboost**: [ChartBoost/javascript-style-guide](https://github.com/ChartBoost/javascript-style-guide)
|
||||
- **Coeur d'Alene Tribe**: [www.cdatribe-nsn.gov](https://www.cdatribe-nsn.gov)
|
||||
- **ComparaOnline**: [comparaonline/javascript](https://github.com/comparaonline/javascript-style-guide)
|
||||
- **Compass Learning**: [compasslearning/javascript-style-guide](https://github.com/compasslearning/javascript-style-guide)
|
||||
- **DailyMotion**: [dailymotion/javascript](https://github.com/dailymotion/javascript)
|
||||
- **DoSomething**: [DoSomething/eslint-config](https://github.com/DoSomething/eslint-config)
|
||||
- **Digitpaint** [digitpaint/javascript](https://github.com/digitpaint/javascript)
|
||||
- **Drupal**: [www.drupal.org](https://www.drupal.org/project/drupal)
|
||||
- **Drupal**: [www.drupal.org](https://git.drupalcode.org/project/drupal/blob/8.6.x/core/.eslintrc.json)
|
||||
- **Ecosia**: [ecosia/javascript](https://github.com/ecosia/javascript)
|
||||
- **Evernote**: [evernote/javascript-style-guide](https://github.com/evernote/javascript-style-guide)
|
||||
- **Evolution Gaming**: [evolution-gaming/javascript](https://github.com/evolution-gaming/javascript)
|
||||
- **EvozonJs**: [evozonjs/javascript](https://github.com/evozonjs/javascript)
|
||||
- **ExactTarget**: [ExactTarget/javascript](https://github.com/ExactTarget/javascript)
|
||||
- **Expensify** [Expensify/Style-Guide](https://github.com/Expensify/Style-Guide/blob/master/javascript.md)
|
||||
- **Flexberry**: [Flexberry/javascript-style-guide](https://github.com/Flexberry/javascript-style-guide)
|
||||
- **Gawker Media**: [gawkermedia](https://github.com/gawkermedia/)
|
||||
- **General Electric**: [GeneralElectric/javascript](https://github.com/GeneralElectric/javascript)
|
||||
@@ -3747,14 +3879,13 @@ Other Style Guides
|
||||
- **GreenChef**: [greenchef/javascript](https://github.com/greenchef/javascript)
|
||||
- **Grooveshark**: [grooveshark/javascript](https://github.com/grooveshark/javascript)
|
||||
- **Grupo-Abraxas**: [Grupo-Abraxas/javascript](https://github.com/Grupo-Abraxas/javascript)
|
||||
- **Happeo**: [happeo/javascript](https://github.com/happeo/javascript)
|
||||
- **Honey**: [honeyscience/javascript](https://github.com/honeyscience/javascript)
|
||||
- **How About We**: [howaboutwe/javascript](https://github.com/howaboutwe/javascript-style-guide)
|
||||
- **Huballin**: [huballin](https://github.com/huballin/)
|
||||
- **HubSpot**: [HubSpot/javascript](https://github.com/HubSpot/javascript)
|
||||
- **Hyper**: [hyperoslo/javascript-playbook](https://github.com/hyperoslo/javascript-playbook/blob/master/style.md)
|
||||
- **InterCity Group**: [intercitygroup/javascript-style-guide](https://github.com/intercitygroup/javascript-style-guide)
|
||||
- **Jam3**: [Jam3/Javascript-Code-Conventions](https://github.com/Jam3/Javascript-Code-Conventions)
|
||||
- **JeopardyBot**: [kesne/jeopardy-bot](https://github.com/kesne/jeopardy-bot/blob/master/STYLEGUIDE.md)
|
||||
- **JSSolutions**: [JSSolutions/javascript](https://github.com/JSSolutions/javascript)
|
||||
- **Kaplan Komputing**: [kaplankomputing/javascript](https://github.com/kaplankomputing/javascript)
|
||||
- **KickorStick**: [kickorstick](https://github.com/kickorstick/)
|
||||
@@ -3765,24 +3896,20 @@ Other Style Guides
|
||||
- **Mighty Spring**: [mightyspring/javascript](https://github.com/mightyspring/javascript)
|
||||
- **MinnPost**: [MinnPost/javascript](https://github.com/MinnPost/javascript)
|
||||
- **MitocGroup**: [MitocGroup/javascript](https://github.com/MitocGroup/javascript)
|
||||
- **ModCloth**: [modcloth/javascript](https://github.com/modcloth/javascript)
|
||||
- **Money Advice Service**: [moneyadviceservice/javascript](https://github.com/moneyadviceservice/javascript)
|
||||
- **Muber**: [muber](https://github.com/muber/)
|
||||
- **National Geographic**: [natgeo](https://github.com/natgeo/)
|
||||
- **Nimbl3**: [nimbl3/javascript](https://github.com/nimbl3/javascript)
|
||||
- **NullDev**: [NullDevCo/JavaScript-Styleguide](https://github.com/NullDevCo/JavaScript-Styleguide)
|
||||
- **Nulogy**: [nulogy/javascript](https://github.com/nulogy/javascript)
|
||||
- **Orange Hill Development**: [orangehill/javascript](https://github.com/orangehill/javascript)
|
||||
- **Orion Health**: [orionhealth/javascript](https://github.com/orionhealth/javascript)
|
||||
- **OutBoxSoft**: [OutBoxSoft/javascript](https://github.com/OutBoxSoft/javascript)
|
||||
- **Peerby**: [Peerby/javascript](https://github.com/Peerby/javascript)
|
||||
- **Pier 1**: [Pier1/javascript](https://github.com/pier1/javascript)
|
||||
- **Qotto**: [Qotto/javascript-style-guide](https://github.com/Qotto/javascript-style-guide)
|
||||
- **Razorfish**: [razorfish/javascript-style-guide](https://github.com/razorfish/javascript-style-guide)
|
||||
- **reddit**: [reddit/styleguide/javascript](https://github.com/reddit/styleguide/tree/master/javascript)
|
||||
- **React**: [facebook.github.io/react/contributing/how-to-contribute.html#style-guide](https://facebook.github.io/react/contributing/how-to-contribute.html#style-guide)
|
||||
- **REI**: [reidev/js-style-guide](https://github.com/rei/code-style-guides/)
|
||||
- **Ripple**: [ripple/javascript-style-guide](https://github.com/ripple/javascript-style-guide)
|
||||
- **Sainsbury's Supermarkets**: [jsainsburyplc](https://github.com/jsainsburyplc)
|
||||
- **SeekingAlpha**: [seekingalpha/javascript-style-guide](https://github.com/seekingalpha/javascript-style-guide)
|
||||
- **Sainsbury’s Supermarkets**: [jsainsburyplc](https://github.com/jsainsburyplc)
|
||||
- **Shutterfly**: [shutterfly/javascript](https://github.com/shutterfly/javascript)
|
||||
- **Sourcetoad**: [sourcetoad/javascript](https://github.com/sourcetoad/javascript)
|
||||
- **Springload**: [springload](https://github.com/springload/)
|
||||
@@ -3793,9 +3920,13 @@ Other Style Guides
|
||||
- **SysGarage**: [sysgarage/javascript-style-guide](https://github.com/sysgarage/javascript-style-guide)
|
||||
- **Syzygy Warsaw**: [syzygypl/javascript](https://github.com/syzygypl/javascript)
|
||||
- **Target**: [target/javascript](https://github.com/target/javascript)
|
||||
- **Terra**: [terra](https://github.com/cerner?utf8=%E2%9C%93&q=terra&type=&language=)
|
||||
- **TheLadders**: [TheLadders/javascript](https://github.com/TheLadders/javascript)
|
||||
- **The Nerdery**: [thenerdery/javascript-standards](https://github.com/thenerdery/javascript-standards)
|
||||
- **Tomify**: [tomprats](https://github.com/tomprats)
|
||||
- **Traitify**: [traitify/eslint-config-traitify](https://github.com/traitify/eslint-config-traitify)
|
||||
- **T4R Technology**: [T4R-Technology/javascript](https://github.com/T4R-Technology/javascript)
|
||||
- **UrbanSim**: [urbansim](https://github.com/urbansim/)
|
||||
- **VoxFeed**: [VoxFeed/javascript-style-guide](https://github.com/VoxFeed/javascript-style-guide)
|
||||
- **WeBox Studio**: [weboxstudio/javascript](https://github.com/weboxstudio/javascript)
|
||||
- **Weggo**: [Weggo/javascript](https://github.com/Weggo/javascript)
|
||||
@@ -3811,7 +3942,7 @@ Other Style Guides
|
||||
-  **Brazilian Portuguese**: [armoucar/javascript-style-guide](https://github.com/armoucar/javascript-style-guide)
|
||||
-  **Bulgarian**: [borislavvv/javascript](https://github.com/borislavvv/javascript)
|
||||
-  **Catalan**: [fpmweb/javascript-style-guide](https://github.com/fpmweb/javascript-style-guide)
|
||||
-  **Chinese (Simplified)**: [yuche/javascript](https://github.com/yuche/javascript)
|
||||
-  **Chinese (Simplified)**: [lin-123/javascript](https://github.com/lin-123/javascript)
|
||||
-  **Chinese (Traditional)**: [jigsawye/javascript](https://github.com/jigsawye/javascript)
|
||||
-  **French**: [nmussy/javascript-style-guide](https://github.com/nmussy/javascript-style-guide)
|
||||
-  **German**: [timofurrer/javascript-style-guide](https://github.com/timofurrer/javascript-style-guide)
|
||||
@@ -3823,7 +3954,7 @@ Other Style Guides
|
||||
-  **Thai**: [lvarayut/javascript-style-guide](https://github.com/lvarayut/javascript-style-guide)
|
||||
-  **Turkish**: [eraycetinay/javascript](https://github.com/eraycetinay/javascript)
|
||||
-  **Ukrainian**: [ivanzusko/javascript](https://github.com/ivanzusko/javascript)
|
||||
-  **Vietnam**: [hngiang/javascript-style-guide](https://github.com/hngiang/javascript-style-guide)
|
||||
-  **Vietnam**: [dangkyokhoang/javascript-style-guide](https://github.com/dangkyokhoang/javascript-style-guide)
|
||||
|
||||
## The JavaScript Style Guide Guide
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
"comment": "Be explicit by listing every available rule. https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md",
|
||||
"comment": "Note that there will be numeric gaps, not every MD number is implemented in markdownlint.",
|
||||
|
||||
"comment": "MD001: Header levels should only increment by one level at a time",
|
||||
"comment": "MD001: Header levels should only increment by one level at a time.",
|
||||
"header-increment": true,
|
||||
|
||||
"comment": "MD002: First header should be a top level header",
|
||||
"comment": "MD002: First header should be a top level header.",
|
||||
"first-header-h1": true,
|
||||
|
||||
"comment": "MD003: Header style: start with hashes",
|
||||
"comment": "MD003: Header style: start with hashes.",
|
||||
"header-style": {
|
||||
"style": "atx"
|
||||
},
|
||||
@@ -18,25 +18,26 @@
|
||||
"style": "dash"
|
||||
},
|
||||
|
||||
"comment": "MD005: Consistent indentation for list items at the same level",
|
||||
"comment": "MD005: Consistent indentation for list items at the same level.",
|
||||
"list-indent": true,
|
||||
|
||||
"comment": "MD006: Consider starting bulleted lists at the beginning of the line",
|
||||
"comment": "MD006: Consider starting bulleted lists at the beginning of the line.",
|
||||
"ul-start-left": false,
|
||||
|
||||
"comment": "MD007: Unordered list indentation: 2 spaces",
|
||||
"comment": "MD007: Unordered list indentation: 2 spaces.",
|
||||
"ul-indent": {
|
||||
"indent": 2
|
||||
"indent": 2,
|
||||
"start_indented": true
|
||||
},
|
||||
|
||||
"comment": "MD009: Disallow trailing spaces",
|
||||
"comment": "MD009: Disallow trailing spaces!",
|
||||
"no-trailing-spaces": {
|
||||
"br_spaces": 0,
|
||||
"comment": "Empty lines inside list items should not be indented",
|
||||
"comment": "Empty lines inside list items should not be indented.",
|
||||
"list_item_empty_lines": false
|
||||
},
|
||||
|
||||
"comment": "MD010: No hard tabs, not even in code blocks",
|
||||
"comment": "MD010: No hard tabs, not even in code blocks.",
|
||||
"no-hard-tabs": {
|
||||
"code_blocks": true
|
||||
},
|
||||
@@ -44,7 +45,7 @@
|
||||
"comment": "MD011: Prevent reversed link syntax",
|
||||
"no-reversed-links": true,
|
||||
|
||||
"comment": "MD012: Disallow multiple consecutive blank lines",
|
||||
"comment": "MD012: Disallow multiple consecutive blank lines.",
|
||||
"no-multiple-blanks": {
|
||||
"maximum": 1
|
||||
},
|
||||
@@ -52,37 +53,37 @@
|
||||
"comment": "MD013: Line length",
|
||||
"line-length": false,
|
||||
|
||||
"comment": "MD014: Disallow dollar signs used before commands without showing output",
|
||||
"comment": "MD014: Disallow use of dollar signs($) before commands without showing output.",
|
||||
"commands-show-output": true,
|
||||
|
||||
"comment": "MD018: Disallow space after hash on atx style header",
|
||||
"comment": "MD018: Disallow space after hash on atx style header.",
|
||||
"no-missing-space-atx": true,
|
||||
|
||||
"comment": "MD019: Dissalow multiple spaces after hash on atx style header",
|
||||
"comment": "MD019: Disallow multiple spaces after hash on atx style header.",
|
||||
"no-multiple-space-atx": true,
|
||||
|
||||
"comment": "MD020: No space inside hashes on closed atx style header",
|
||||
"comment": "MD020: No space should be inside hashes on closed atx style header.",
|
||||
"no-missing-space-closed-atx": true,
|
||||
|
||||
"comment": "MD021: Disallow multiple spaces inside hashes on closed atx style header",
|
||||
"comment": "MD021: Disallow multiple spaces inside hashes on closed atx style header.",
|
||||
"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": "MD022: Headers should be surrounded by blank lines.",
|
||||
"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",
|
||||
"comment": "MD023: Headers must start at the beginning of the line.",
|
||||
"header-start-left": true,
|
||||
|
||||
"comment": "MD024: Disallow multiple headers with the same content",
|
||||
"comment": "MD024: Disallow multiple headers with the same content.",
|
||||
"no-duplicate-header": true,
|
||||
|
||||
"comment": "MD025: Disallow multiple top level headers in the same document",
|
||||
"comment": "Gotta have a matching closing brace at the end",
|
||||
"comment": "MD025: Disallow multiple top level headers in the same document.",
|
||||
"comment": "Gotta have a matching closing brace at the end.",
|
||||
"single-h1": false,
|
||||
|
||||
"comment": "MD026: Disallow trailing punctuation in header",
|
||||
"comment": "Gotta have a semicolon after the ending closing brace",
|
||||
"comment": "MD026: Disallow trailing punctuation in header.",
|
||||
"comment": "You must have a semicolon after the ending closing brace.",
|
||||
"no-trailing-punctuation": {
|
||||
"punctuation" : ".,:!?"
|
||||
},
|
||||
@@ -110,14 +111,14 @@
|
||||
"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",
|
||||
"comment": "HTML is needed for explicit anchors",
|
||||
"no-inline-html": false,
|
||||
|
||||
"comment": "MD034: No bare URLs used",
|
||||
"comment": "MD034: No bare URLs should be used",
|
||||
"no-bare-urls": true,
|
||||
|
||||
"comment": "MD035: Horizontal rule style",
|
||||
@@ -125,30 +126,30 @@
|
||||
"style": "consistent"
|
||||
},
|
||||
|
||||
"comment": "MD036: Do not use emphasis instead of a header",
|
||||
"comment": "MD036: Do not use emphasis instead of a header.",
|
||||
"no-emphasis-as-header": false,
|
||||
|
||||
"comment": "MD037: Disallow spaces inside emphasis markers",
|
||||
"comment": "MD037: Disallow spaces inside emphasis markers.",
|
||||
"no-space-in-emphasis": true,
|
||||
|
||||
"comment": "MD038: Disallow spaces inside code span elements",
|
||||
"comment": "MD038: Disallow spaces inside code span elements.",
|
||||
"no-space-in-code": true,
|
||||
|
||||
"comment": "MD039: Disallow spaces inside link text",
|
||||
"comment": "MD039: Disallow spaces inside link text.",
|
||||
"no-space-in-links": true,
|
||||
|
||||
"comment": "MD040: Fenced code blocks should have a language specified",
|
||||
"comment": "MD040: Fenced code blocks should have a language specified.",
|
||||
"fenced-code-language": true,
|
||||
|
||||
"comment": "MD041: First line in file should be a top level header",
|
||||
"comment": "MD041: First line in file should be a top level header.",
|
||||
"first-line-h1": true,
|
||||
|
||||
"comment": "MD042: No empty links",
|
||||
"no-empty-links": true,
|
||||
|
||||
"comment": "MD043: Required header structure",
|
||||
"comment": "MD043: Required header structure.",
|
||||
"required-headers": false,
|
||||
|
||||
"comment": "MD044: Proper names should have the correct capitalization",
|
||||
"comment": "MD044: Proper names should have the correct capitalization.",
|
||||
"proper-names": false
|
||||
}
|
||||
|
||||
@@ -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.10.0"
|
||||
"markdownlint": "^0.20.4",
|
||||
"markdownlint-cli": "^0.23.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,91 @@
|
||||
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)
|
||||
- [fix] disable `no-var` in legacy entry point
|
||||
- [patch] Ignore property modifications of `staticContext` params (#2029)
|
||||
- [patch] `no-extraneous-dependencies`: Add jest.setup.js to devDeps (#1998)
|
||||
- [meta] add disabled `prefer-named-capture-group` rule
|
||||
- [meta] add disabled `no-useless-catch` config
|
||||
- [deps] Switch to confusing-browser-globals (#1961)
|
||||
- [deps] update `object.entries`, `eslint-plugin-import`, `eslint-plugin-jsx-a11y`, `eslint-plugin-react`, `tape`
|
||||
- [docs] correct JavaScript capitalization (#2046)
|
||||
- [readme] Improve eslint config setup instructions for yarn (#2001)
|
||||
- [docs] fix docs for whitespace config (#1914, #1871)
|
||||
|
||||
13.1.0 / 2018-08-13
|
||||
==================
|
||||
- [new] add eslint v5 support (#1834)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -12,8 +16,6 @@ We export two ESLint configurations for your usage.
|
||||
|
||||
Our default export contains all of our ESLint rules, including ECMAScript 6+. It requires `eslint` and `eslint-plugin-import`.
|
||||
|
||||
If you use yarn, run `npm info "eslint-config-airbnb-base@latest" peerDependencies` to list the peer dependencies and versions, then run `yarn add --dev <dependency>@<version>` for each listed peer dependency. See below for npm instructions.
|
||||
|
||||
1. Install the correct versions of each package, which are listed by the command:
|
||||
|
||||
```sh
|
||||
@@ -26,6 +28,10 @@ If you use yarn, run `npm info "eslint-config-airbnb-base@latest" peerDependenci
|
||||
npx install-peerdeps --dev eslint-config-airbnb-base
|
||||
```
|
||||
|
||||
If using **yarn**, you can also use the shortcut described above if you have npm 5+ installed on your machine, as the command will detect that you are using yarn and will act accordingly.
|
||||
Otherwise, run `npm info "eslint-config-airbnb-base@latest" peerDependencies` to list the peer dependencies and versions, then run `yarn add --dev <dependency>@<version>` for each listed peer dependency.
|
||||
|
||||
|
||||
If using **npm < 5**, Linux/OSX users can run
|
||||
|
||||
```sh
|
||||
@@ -77,16 +83,16 @@ 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
|
||||
|
||||
See [Airbnb's overarching ESLint config](https://npmjs.com/eslint-config-airbnb), [Airbnb's Javascript styleguide](https://github.com/airbnb/javascript), and the [ESlint config docs](https://eslint.org/docs/user-guide/configuring#extending-configuration-files) for more information.
|
||||
See [Airbnb's overarching ESLint config](https://npmjs.com/eslint-config-airbnb), [Airbnb's JavaScript styleguide](https://github.com/airbnb/javascript), and the [ESlint config docs](https://eslint.org/docs/user-guide/configuring#extending-configuration-files) for more information.
|
||||
|
||||
### eslint-config-airbnb-base/whitespace
|
||||
|
||||
This entry point only warns on whitespace rules and sets all other rules to warnings. View the list of whitespace rules [here](https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb-base/whitespace.js).
|
||||
This entry point only errors on whitespace rules and sets all other rules to warnings. View the list of whitespace rules [here](https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb-base/whitespace.js).
|
||||
|
||||
## Improving this config
|
||||
|
||||
@@ -95,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,5 +27,8 @@ module.exports = {
|
||||
property: '__defineSetter__',
|
||||
message: 'Please use Object.defineProperty instead.',
|
||||
}],
|
||||
'no-var': 'off',
|
||||
'prefer-object-spread': 'off',
|
||||
strict: ['error', 'safe'],
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,18 +1,33 @@
|
||||
{
|
||||
"name": "eslint-config-airbnb-base",
|
||||
"version": "13.1.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 * rules/* test/*",
|
||||
"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,27 @@
|
||||
},
|
||||
"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.14.0",
|
||||
"in-publish": "^2.0.0",
|
||||
"safe-publish-latest": "^1.1.2",
|
||||
"tape": "^4.9.1"
|
||||
"@babel/runtime": "^7.16.3",
|
||||
"babel-preset-airbnb": "^4.5.0",
|
||||
"babel-tape-runner": "^3.0.0",
|
||||
"eclint": "^2.8.1",
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-find-rules": "^4.0.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"in-publish": "^2.0.1",
|
||||
"safe-publish-latest": "^2.0.0",
|
||||
"tape": "^5.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^4.19.1 || ^5.3.0",
|
||||
"eslint-plugin-import": "^2.14.0"
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-plugin-import": "^2.25.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
"node": "^10.12.0 || >=12.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-restricted-globals": "^0.1.1",
|
||||
"object.assign": "^4.1.0",
|
||||
"object.entries": "^1.0.4"
|
||||
"confusing-browser-globals": "^1.0.10",
|
||||
"object.assign": "^4.1.2",
|
||||
"object.entries": "^1.1.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,34 @@ 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
|
||||
'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',
|
||||
@@ -80,15 +104,19 @@ module.exports = {
|
||||
'no-empty-pattern': 'error',
|
||||
|
||||
// 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 +124,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 +153,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 +186,38 @@ 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 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,18 +230,22 @@ 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
|
||||
'response', // for Express responses
|
||||
'$scope', // for Angular 1 scopes
|
||||
'staticContext', // for ReactRouter context
|
||||
]
|
||||
}],
|
||||
|
||||
// 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
|
||||
@@ -238,28 +291,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
|
||||
@@ -267,6 +325,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,
|
||||
@@ -278,8 +337,13 @@ 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
|
||||
'no-useless-catch': 'error',
|
||||
|
||||
// disallow useless string concatenation
|
||||
// https://eslint.org/docs/rules/no-useless-concat
|
||||
'no-useless-concat': 'error',
|
||||
@@ -297,16 +361,33 @@ 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
|
||||
// https://eslint.org/docs/rules/prefer-promise-reject-errors
|
||||
'prefer-promise-reject-errors': ['error', { allowEmptyReject: true }],
|
||||
|
||||
// Suggest using named capture group in regular expression
|
||||
// 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)
|
||||
@@ -318,6 +399,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
|
||||
@@ -325,6 +407,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
|
||||
@@ -39,6 +38,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 +77,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 +89,21 @@ 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 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 +111,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 +129,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 +142,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
|
||||
@@ -62,6 +60,15 @@ module.exports = {
|
||||
// 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',
|
||||
|
||||
@@ -158,6 +165,7 @@ module.exports = {
|
||||
// https://eslint.org/docs/rules/sort-imports
|
||||
'sort-imports': ['off', {
|
||||
ignoreCase: false,
|
||||
ignoreDeclarationSort: false,
|
||||
ignoreMemberSort: false,
|
||||
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
|
||||
}],
|
||||
|
||||
@@ -79,6 +79,7 @@ module.exports = {
|
||||
'test-*.{js,jsx}', // repos with multiple top-level test files
|
||||
'**/*{.,_}{test,spec}.{js,jsx}', // tests where the extension or filename suffix denotes that it is a test
|
||||
'**/jest.config.js', // jest config
|
||||
'**/jest.setup.js', // jest setup
|
||||
'**/vue.config.js', // vue-cli config
|
||||
'**/webpack.config.js', // webpack config
|
||||
'**/webpack.config.*.js', // webpack config
|
||||
@@ -89,6 +90,8 @@ 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,
|
||||
}],
|
||||
@@ -221,17 +224,21 @@ module.exports = {
|
||||
// https://github.com/benmosher/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
|
||||
'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
|
||||
'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 }],
|
||||
'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',
|
||||
'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
|
||||
@@ -243,5 +250,24 @@ module.exports = {
|
||||
// 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
|
||||
'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 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/benmosher/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/benmosher/eslint-plugin-import/blob/1012eb951767279ce3b540a4ec4f29236104bb5b/docs/rules/no-relative-packages.md
|
||||
'import/no-relative-packages': 'error',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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
|
||||
}],
|
||||
|
||||
@@ -285,7 +287,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 +295,10 @@ module.exports = {
|
||||
['%', '-'],
|
||||
['%', '*'],
|
||||
['%', '/'],
|
||||
['**', '+'],
|
||||
['**', '-'],
|
||||
['**', '*'],
|
||||
['**', '/'],
|
||||
['&', '|', '^', '~', '<<', '>>', '>>>'],
|
||||
['==', '!=', '===', '!==', '>', '>=', '<', '<='],
|
||||
['/', '*'],
|
||||
['&', '|', '<<', '>>', '>>>'],
|
||||
['==', '!=', '===', '!=='],
|
||||
['&&', '||'],
|
||||
['in', 'instanceof']
|
||||
],
|
||||
allowSamePrecedence: false
|
||||
}],
|
||||
@@ -312,8 +310,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
|
||||
@@ -367,11 +366,12 @@ module.exports = {
|
||||
}],
|
||||
|
||||
// disallow dangling underscores in identifiers
|
||||
// https://eslint.org/docs/rules/no-underscore-dangle
|
||||
'no-underscore-dangle': ['error', {
|
||||
allow: [],
|
||||
allowAfterThis: false,
|
||||
allowAfterSuper: false,
|
||||
enforceInMethodNames: false,
|
||||
enforceInMethodNames: true,
|
||||
}],
|
||||
|
||||
// disallow the use of Boolean literals in conditional expressions
|
||||
@@ -421,16 +421,25 @@ module.exports = {
|
||||
'operator-linebreak': ['error', 'before', { overrides: { '=': 'none' } }],
|
||||
|
||||
// disallow padding within blocks
|
||||
'padded-blocks': ['error', { blocks: 'never', classes: 'never', switches: 'never' }],
|
||||
'padded-blocks': ['error', {
|
||||
blocks: 'never',
|
||||
classes: 'never',
|
||||
switches: 'never',
|
||||
}, {
|
||||
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
|
||||
@@ -490,11 +499,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,
|
||||
}
|
||||
}],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const restrictedGlobals = require('eslint-restricted-globals');
|
||||
const confusingBrowserGlobals = require('confusing-browser-globals');
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
@@ -16,7 +16,19 @@ module.exports = {
|
||||
'no-label-var': 'error',
|
||||
|
||||
// disallow specific globals
|
||||
'no-restricted-globals': ['error', 'isFinite', 'isNaN'].concat(restrictedGlobals),
|
||||
'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),
|
||||
|
||||
// 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';
|
||||
|
||||
|
||||
@@ -26,7 +26,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 assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
const { ESLint } = require('eslint');
|
||||
|
||||
const baseConfig = require('.');
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
|
||||
function getSeverity(ruleConfig) {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
async function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = assign({}, config);
|
||||
const cli = new ESLint({
|
||||
useEslintrc: false,
|
||||
baseConfig: config
|
||||
});
|
||||
const baseRules = (await cli.calculateConfigForFile(require.resolve('./'))).rules;
|
||||
|
||||
entries(baseRules).forEach((rule) => {
|
||||
const ruleName = rule[0];
|
||||
const ruleConfig = rule[1];
|
||||
const severity = getSeverity(ruleConfig);
|
||||
|
||||
if (rulesToError.indexOf(ruleName) === -1 && severity === 'error') {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
errorsOnly.rules[ruleName] = ['warn'].concat(ruleConfig.slice(1));
|
||||
} else if (typeof ruleConfig === 'number') {
|
||||
errorsOnly.rules[ruleName] = 1;
|
||||
} else {
|
||||
errorsOnly.rules[ruleName] = 'warn';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return errorsOnly;
|
||||
}
|
||||
|
||||
onlyErrorOnRules(whitespaceRules, baseConfig).then((config) => console.log(JSON.stringify(config)));
|
||||
@@ -1,78 +1,55 @@
|
||||
const assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
const CLIEngine = require('eslint').CLIEngine;
|
||||
/* eslint global-require: 0 */
|
||||
|
||||
const baseConfig = require('.');
|
||||
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 assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
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 (Array.isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
});
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
return errorsOnly;
|
||||
function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = assign({}, config);
|
||||
const cli = new CLIEngine({ baseConfig: config, useEslintrc: false });
|
||||
const baseRules = cli.getConfigForFile(require.resolve('./')).rules;
|
||||
|
||||
entries(baseRules).forEach((rule) => {
|
||||
const ruleName = rule[0];
|
||||
const ruleConfig = rule[1];
|
||||
const severity = getSeverity(ruleConfig);
|
||||
|
||||
if (rulesToError.indexOf(ruleName) === -1 && severity === 'error') {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
errorsOnly.rules[ruleName] = ['warn'].concat(ruleConfig.slice(1));
|
||||
} else if (typeof ruleConfig === 'number') {
|
||||
errorsOnly.rules[ruleName] = 1;
|
||||
} else {
|
||||
errorsOnly.rules[ruleName] = 'warn';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return errorsOnly;
|
||||
}
|
||||
|
||||
module.exports = onlyErrorOnRules(whitespaceRules, baseConfig);
|
||||
} else {
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
module.exports = JSON.parse(String(execSync(path.join(__dirname, 'whitespace-async.js'))));
|
||||
}
|
||||
|
||||
module.exports = onlyErrorOnRules([
|
||||
'array-bracket-newline',
|
||||
'array-bracket-spacing',
|
||||
'array-element-newline',
|
||||
'arrow-spacing',
|
||||
'block-spacing',
|
||||
'comma-spacing',
|
||||
'computed-property-spacing',
|
||||
'dot-location',
|
||||
'eol-last',
|
||||
'func-call-spacing',
|
||||
'function-paren-newline',
|
||||
'generator-star-spacing',
|
||||
'implicit-arrow-linebreak',
|
||||
'indent',
|
||||
'key-spacing',
|
||||
'keyword-spacing',
|
||||
'line-comment-position',
|
||||
'linebreak-style',
|
||||
'multiline-ternary',
|
||||
'newline-per-chained-call',
|
||||
'no-irregular-whitespace',
|
||||
'no-mixed-spaces-and-tabs',
|
||||
'no-multi-spaces',
|
||||
'no-regex-spaces',
|
||||
'no-spaced-func',
|
||||
'no-trailing-spaces',
|
||||
'no-whitespace-before-property',
|
||||
'nonblock-statement-body-position',
|
||||
'object-curly-newline',
|
||||
'object-curly-spacing',
|
||||
'object-property-newline',
|
||||
'one-var-declaration-per-line',
|
||||
'operator-linebreak',
|
||||
'padded-blocks',
|
||||
'padding-line-between-statements',
|
||||
'rest-spread-spacing',
|
||||
'semi-spacing',
|
||||
'semi-style',
|
||||
'space-before-blocks',
|
||||
'space-before-function-paren',
|
||||
'space-in-parens',
|
||||
'space-infix-ops',
|
||||
'space-unary-ops',
|
||||
'spaced-comment',
|
||||
'switch-colon-spacing',
|
||||
'template-tag-spacing',
|
||||
'import/newline-after-import',
|
||||
], 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,104 @@
|
||||
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)
|
||||
- [patch] extend `no-underscore-dangle` to allow for redux dev tools in the main config instead (#1996)
|
||||
- [meta] add disabled `jsx-fragments` rule
|
||||
- [deps] update `eslint-config-airbnb-base`, `object.entries`, `eslint-plugin-import`, `eslint-plugin-react`, `eslint-plugin-jsx-a11y`, `babel-preset-airbnb`, `tape` (#2005, etc)
|
||||
- [docs] correct JavaScript capitalization (#2046)
|
||||
- [docs] fix docs for whitespace config (#1914, #1871)
|
||||
- [readme] Improve eslint config setup instructions for yarn (#2001)
|
||||
|
||||
17.1.0 / 2018-08-13
|
||||
==================
|
||||
- [new] add eslint v5 support
|
||||
|
||||
@@ -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,9 +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 use yarn, run `npm info "eslint-config-airbnb@latest" peerDependencies` to list the peer dependencies and versions, then run `yarn add --dev <dependency>@<version>` for each listed peer dependency. See below for npm instructions.
|
||||
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:
|
||||
|
||||
@@ -26,6 +26,9 @@ If you use yarn, run `npm info "eslint-config-airbnb@latest" peerDependencies` t
|
||||
npx install-peerdeps --dev eslint-config-airbnb
|
||||
```
|
||||
|
||||
If using **yarn**, you can also use the shortcut described above if you have npm 5+ installed on your machine, as the command will detect that you are using yarn and will act accordingly.
|
||||
Otherwise, run `npm info "eslint-config-airbnb@latest" peerDependencies` to list the peer dependencies and versions, then run `yarn add --dev <dependency>@<version>` for each listed peer dependency.
|
||||
|
||||
If using **npm < 5**, Linux/OSX users can run
|
||||
|
||||
```sh
|
||||
@@ -38,7 +41,7 @@ If you use yarn, run `npm info "eslint-config-airbnb@latest" peerDependencies` t
|
||||
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.
|
||||
@@ -50,14 +53,18 @@ If you use yarn, run `npm info "eslint-config-airbnb@latest" peerDependencies` t
|
||||
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
|
||||
|
||||
This entry point only warns on whitespace rules and sets all other rules to warnings. View the list of whitespace rules [here](https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb/whitespace.js).
|
||||
This entry point only errors on whitespace rules and sets all other rules to warnings. View the list of whitespace rules [here](https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb/whitespace.js).
|
||||
|
||||
### eslint-config-airbnb/base
|
||||
|
||||
@@ -67,7 +74,7 @@ This entry point is deprecated. See [eslint-config-airbnb-base](https://npmjs.co
|
||||
|
||||
This entry point is deprecated. See [eslint-config-airbnb-base](https://npmjs.com/eslint-config-airbnb-base).
|
||||
|
||||
See [Airbnb's Javascript styleguide](https://github.com/airbnb/javascript) and
|
||||
See [Airbnb's JavaScript styleguide](https://github.com/airbnb/javascript) and
|
||||
the [ESlint config docs](https://eslint.org/docs/user-guide/configuring#extending-configuration-files)
|
||||
for more information.
|
||||
|
||||
|
||||
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.0",
|
||||
"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 * rules/* test/*",
|
||||
"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 && 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",
|
||||
"link:eslint": "cd node_modules/eslint && npm link --production && cd -",
|
||||
"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,34 @@
|
||||
},
|
||||
"homepage": "https://github.com/airbnb/javascript",
|
||||
"dependencies": {
|
||||
"eslint-config-airbnb-base": "^13.1.0",
|
||||
"object.assign": "^4.1.0",
|
||||
"object.entries": "^1.0.4"
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"object.assign": "^4.1.2",
|
||||
"object.entries": "^1.1.5"
|
||||
},
|
||||
"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.14.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.1.1",
|
||||
"eslint-plugin-react": "^7.11.0",
|
||||
"in-publish": "^2.0.0",
|
||||
"@babel/runtime": "^7.16.3",
|
||||
"babel-preset-airbnb": "^4.5.0",
|
||||
"babel-tape-runner": "^3.0.0",
|
||||
"eclint": "^2.8.1",
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-find-rules": "^4.0.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"in-publish": "^2.0.1",
|
||||
"react": ">= 0.13.0",
|
||||
"safe-publish-latest": "^1.1.2",
|
||||
"tape": "^4.9.1"
|
||||
"safe-publish-latest": "^2.0.0",
|
||||
"tape": "^5.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^4.19.1 || ^5.3.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.1.1",
|
||||
"eslint-plugin-react": "^7.11.0"
|
||||
"eslint": "^7.32.0 || ^8.2.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
"node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
283
packages/eslint-config-airbnb/rules/react-a11y.js
vendored
283
packages/eslint-config-airbnb/rules/react-a11y.js
vendored
@@ -11,26 +11,10 @@ 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/evcohen/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
|
||||
@@ -42,19 +26,97 @@ module.exports = {
|
||||
'input[type="image"]': [],
|
||||
}],
|
||||
|
||||
// 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: [] }],
|
||||
|
||||
// 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'],
|
||||
}],
|
||||
|
||||
// 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',
|
||||
|
||||
// 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',
|
||||
|
||||
// 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 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 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/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 a control (an interactive element) has a text label.
|
||||
// https://github.com/evcohen/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/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',
|
||||
|
||||
// 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',
|
||||
|
||||
// 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',
|
||||
|
||||
// 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,
|
||||
}],
|
||||
// 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 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
|
||||
@@ -66,6 +128,18 @@ module.exports = {
|
||||
depth: 25
|
||||
}],
|
||||
|
||||
// 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',
|
||||
|
||||
// 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: [],
|
||||
}],
|
||||
|
||||
// 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
|
||||
'jsx-a11y/mouse-events-have-key-events': 'error',
|
||||
@@ -74,39 +148,9 @@ module.exports = {
|
||||
// https://github.com/evcohen/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/evcohen/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
|
||||
@@ -114,25 +158,10 @@ module.exports = {
|
||||
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/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'],
|
||||
}],
|
||||
|
||||
// A non-interactive element does not support event handlers (mouse and key handlers)
|
||||
@@ -148,40 +177,6 @@ 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
|
||||
'jsx-a11y/no-noninteractive-element-to-interactive-role': ['error', {
|
||||
@@ -199,12 +194,58 @@ module.exports = {
|
||||
roles: ['tabpanel'],
|
||||
}],
|
||||
|
||||
// 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/evcohen/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/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-redundant-roles.md
|
||||
'jsx-a11y/no-redundant-roles': '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',
|
||||
]
|
||||
}],
|
||||
|
||||
// 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',
|
||||
|
||||
// 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',
|
||||
|
||||
// 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',
|
||||
|
||||
// ----------------------------------------------------
|
||||
// Rules that no longer exist in eslint-plugin-jsx-a11y
|
||||
// ----------------------------------------------------
|
||||
|
||||
// require that JSX labels use "htmlFor"
|
||||
// https://github.com/evcohen/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,
|
||||
}],
|
||||
},
|
||||
};
|
||||
|
||||
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',
|
||||
},
|
||||
};
|
||||
115
packages/eslint-config-airbnb/rules/react.js
vendored
115
packages/eslint-config-airbnb/rules/react.js
vendored
@@ -1,3 +1,8 @@
|
||||
const assign = require('object.assign');
|
||||
const baseStyleRules = require('eslint-config-airbnb-base/rules/style').rules;
|
||||
|
||||
const dangleRules = baseStyleRules['no-underscore-dangle'];
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
'react',
|
||||
@@ -12,6 +17,10 @@ module.exports = {
|
||||
// View link below for react rules documentation
|
||||
// https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules
|
||||
rules: {
|
||||
'no-underscore-dangle': [dangleRules[0], assign({}, 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
|
||||
'jsx-quotes': ['error', 'prefer-double'],
|
||||
@@ -82,6 +91,7 @@ module.exports = {
|
||||
|
||||
// Validate JSX has key prop when in array or iterator
|
||||
// https://github.com/yannickcr/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
|
||||
@@ -185,7 +195,7 @@ module.exports = {
|
||||
|
||||
// Prevent multiple component definition per file
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md
|
||||
'react/no-multi-comp': ['error', { ignoreStateless: true }],
|
||||
'react/no-multi-comp': 'off',
|
||||
|
||||
// Prevent usage of setState
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-set-state.md
|
||||
@@ -231,9 +241,11 @@ module.exports = {
|
||||
// https://github.com/yannickcr/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',
|
||||
@@ -256,13 +268,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.+$/',
|
||||
@@ -451,6 +469,97 @@ module.exports = {
|
||||
// Prevent usage of UNSAFE_ methods
|
||||
// https://github.com/yannickcr/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
|
||||
'react/jsx-fragments': ['error', 'syntax'],
|
||||
|
||||
// Enforce linebreaks in curly braces in JSX attributes and expressions.
|
||||
// https://github.com/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/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/yannickcr/eslint-plugin-react/blob/8785c169c25b09b33c95655bf508cf46263bc53f/docs/rules/no-namespace.md
|
||||
'react/no-namespace': 'error',
|
||||
|
||||
// Prefer exact proptype definitions
|
||||
// https://github.com/yannickcr/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/yannickcr/eslint-plugin-react/blob/21e01b61af7a38fc86d94f27eb66cda8054582ed/docs/rules/no-arrow-function-lifecycle.md
|
||||
'react/no-arrow-function-lifecycle': 'error',
|
||||
|
||||
// Prevent usage of invalid attributes
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/21e01b61af7a38fc86d94f27eb66cda8054582ed/docs/rules/no-invalid-html-attribute.md
|
||||
'react/no-invalid-html-attribute': 'error',
|
||||
|
||||
// Prevent declaring unused methods of component class
|
||||
// https://github.com/yannickcr/eslint-plugin-react/blob/21e01b61af7a38fc86d94f27eb66cda8054582ed/docs/rules/no-unused-class-component-methods.md
|
||||
'react/no-unused-class-component-methods': 'error',
|
||||
},
|
||||
|
||||
settings: {
|
||||
@@ -461,7 +570,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();
|
||||
});
|
||||
|
||||
@@ -28,7 +28,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 assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
const { ESLint } = require('eslint');
|
||||
|
||||
const baseConfig = require('.');
|
||||
const whitespaceRules = require('./whitespaceRules');
|
||||
|
||||
const severities = ['off', 'warn', 'error'];
|
||||
|
||||
function getSeverity(ruleConfig) {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
async function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = assign({}, config);
|
||||
const cli = new ESLint({
|
||||
useEslintrc: false,
|
||||
baseConfig: config
|
||||
});
|
||||
const baseRules = (await cli.calculateConfigForFile(require.resolve('./'))).rules;
|
||||
|
||||
entries(baseRules).forEach((rule) => {
|
||||
const ruleName = rule[0];
|
||||
const ruleConfig = rule[1];
|
||||
const severity = getSeverity(ruleConfig);
|
||||
|
||||
if (rulesToError.indexOf(ruleName) === -1 && severity === 'error') {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
errorsOnly.rules[ruleName] = ['warn'].concat(ruleConfig.slice(1));
|
||||
} else if (typeof ruleConfig === 'number') {
|
||||
errorsOnly.rules[ruleName] = 1;
|
||||
} else {
|
||||
errorsOnly.rules[ruleName] = 'warn';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return errorsOnly;
|
||||
}
|
||||
|
||||
onlyErrorOnRules(whitespaceRules, baseConfig).then((config) => console.log(JSON.stringify(config)));
|
||||
@@ -1,92 +1,55 @@
|
||||
const assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
const CLIEngine = require('eslint').CLIEngine;
|
||||
/* eslint global-require: 0 */
|
||||
|
||||
const baseConfig = require('.');
|
||||
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 assign = require('object.assign');
|
||||
const entries = require('object.entries');
|
||||
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 (Array.isArray(ruleConfig)) {
|
||||
return getSeverity(ruleConfig[0]);
|
||||
}
|
||||
});
|
||||
if (typeof ruleConfig === 'number') {
|
||||
return severities[ruleConfig];
|
||||
}
|
||||
return ruleConfig;
|
||||
}
|
||||
|
||||
return errorsOnly;
|
||||
function onlyErrorOnRules(rulesToError, config) {
|
||||
const errorsOnly = assign({}, config);
|
||||
const cli = new CLIEngine({ baseConfig: config, useEslintrc: false });
|
||||
const baseRules = cli.getConfigForFile(require.resolve('./')).rules;
|
||||
|
||||
entries(baseRules).forEach((rule) => {
|
||||
const ruleName = rule[0];
|
||||
const ruleConfig = rule[1];
|
||||
const severity = getSeverity(ruleConfig);
|
||||
|
||||
if (rulesToError.indexOf(ruleName) === -1 && severity === 'error') {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
errorsOnly.rules[ruleName] = ['warn'].concat(ruleConfig.slice(1));
|
||||
} else if (typeof ruleConfig === 'number') {
|
||||
errorsOnly.rules[ruleName] = 1;
|
||||
} else {
|
||||
errorsOnly.rules[ruleName] = 'warn';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return errorsOnly;
|
||||
}
|
||||
|
||||
module.exports = onlyErrorOnRules(whitespaceRules, baseConfig);
|
||||
} else {
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
module.exports = JSON.parse(String(execSync(path.join(__dirname, 'whitespace-async.js'))));
|
||||
}
|
||||
|
||||
module.exports = onlyErrorOnRules([
|
||||
'array-bracket-newline',
|
||||
'array-bracket-spacing',
|
||||
'array-element-newline',
|
||||
'arrow-spacing',
|
||||
'block-spacing',
|
||||
'comma-spacing',
|
||||
'computed-property-spacing',
|
||||
'dot-location',
|
||||
'eol-last',
|
||||
'func-call-spacing',
|
||||
'function-paren-newline',
|
||||
'generator-star-spacing',
|
||||
'implicit-arrow-linebreak',
|
||||
'indent',
|
||||
'key-spacing',
|
||||
'keyword-spacing',
|
||||
'line-comment-position',
|
||||
'linebreak-style',
|
||||
'multiline-ternary',
|
||||
'newline-per-chained-call',
|
||||
'no-irregular-whitespace',
|
||||
'no-mixed-spaces-and-tabs',
|
||||
'no-multi-spaces',
|
||||
'no-regex-spaces',
|
||||
'no-spaced-func',
|
||||
'no-trailing-spaces',
|
||||
'no-whitespace-before-property',
|
||||
'nonblock-statement-body-position',
|
||||
'object-curly-newline',
|
||||
'object-curly-spacing',
|
||||
'object-property-newline',
|
||||
'one-var-declaration-per-line',
|
||||
'operator-linebreak',
|
||||
'padded-blocks',
|
||||
'padding-line-between-statements',
|
||||
'rest-spread-spacing',
|
||||
'semi-spacing',
|
||||
'semi-style',
|
||||
'space-before-blocks',
|
||||
'space-before-function-paren',
|
||||
'space-in-parens',
|
||||
'space-infix-ops',
|
||||
'space-unary-ops',
|
||||
'spaced-comment',
|
||||
'switch-colon-spacing',
|
||||
'template-tag-spacing',
|
||||
'import/newline-after-import',
|
||||
// eslint-plugin-react rules
|
||||
'react/jsx-child-element-spacing',
|
||||
'react/jsx-closing-bracket-location',
|
||||
'react/jsx-closing-tag-location',
|
||||
'react/jsx-curly-spacing',
|
||||
'react/jsx-equals-spacing',
|
||||
'react/jsx-first-prop-newline',
|
||||
'react/jsx-indent',
|
||||
'react/jsx-indent-props',
|
||||
'react/jsx-max-props-per-line',
|
||||
'react/jsx-one-expression-per-line',
|
||||
'react/jsx-space-before-closing',
|
||||
'react/jsx-tag-spacing',
|
||||
'react/jsx-wrap-multilines',
|
||||
], baseConfig);
|
||||
|
||||
64
packages/eslint-config-airbnb/whitespaceRules.js
Normal file
64
packages/eslint-config-airbnb/whitespaceRules.js
Normal file
@@ -0,0 +1,64 @@
|
||||
module.exports = [
|
||||
'array-bracket-newline',
|
||||
'array-bracket-spacing',
|
||||
'array-element-newline',
|
||||
'arrow-spacing',
|
||||
'block-spacing',
|
||||
'comma-spacing',
|
||||
'computed-property-spacing',
|
||||
'dot-location',
|
||||
'eol-last',
|
||||
'func-call-spacing',
|
||||
'function-paren-newline',
|
||||
'generator-star-spacing',
|
||||
'implicit-arrow-linebreak',
|
||||
'indent',
|
||||
'key-spacing',
|
||||
'keyword-spacing',
|
||||
'line-comment-position',
|
||||
'linebreak-style',
|
||||
'multiline-ternary',
|
||||
'newline-per-chained-call',
|
||||
'no-irregular-whitespace',
|
||||
'no-mixed-spaces-and-tabs',
|
||||
'no-multi-spaces',
|
||||
'no-regex-spaces',
|
||||
'no-spaced-func',
|
||||
'no-trailing-spaces',
|
||||
'no-whitespace-before-property',
|
||||
'nonblock-statement-body-position',
|
||||
'object-curly-newline',
|
||||
'object-curly-spacing',
|
||||
'object-property-newline',
|
||||
'one-var-declaration-per-line',
|
||||
'operator-linebreak',
|
||||
'padded-blocks',
|
||||
'padding-line-between-statements',
|
||||
'rest-spread-spacing',
|
||||
'semi-spacing',
|
||||
'semi-style',
|
||||
'space-before-blocks',
|
||||
'space-before-function-paren',
|
||||
'space-in-parens',
|
||||
'space-infix-ops',
|
||||
'space-unary-ops',
|
||||
'spaced-comment',
|
||||
'switch-colon-spacing',
|
||||
'template-tag-spacing',
|
||||
'import/newline-after-import',
|
||||
|
||||
// eslint-plugin-react rules
|
||||
'react/jsx-child-element-spacing',
|
||||
'react/jsx-closing-bracket-location',
|
||||
'react/jsx-closing-tag-location',
|
||||
'react/jsx-curly-spacing',
|
||||
'react/jsx-equals-spacing',
|
||||
'react/jsx-first-prop-newline',
|
||||
'react/jsx-indent',
|
||||
'react/jsx-indent-props',
|
||||
'react/jsx-max-props-per-line',
|
||||
'react/jsx-one-expression-per-line',
|
||||
'react/jsx-space-before-closing',
|
||||
'react/jsx-tag-spacing',
|
||||
'react/jsx-wrap-multilines',
|
||||
];
|
||||
@@ -27,7 +27,8 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
- 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).
|
||||
- Always use JSX syntax.
|
||||
- Do not use `React.createElement` unless you're initializing the app from a file that is not JSX.
|
||||
- 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`.
|
||||
|
||||
## Class vs `React.createClass` vs stateless
|
||||
|
||||
@@ -51,7 +52,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
}
|
||||
```
|
||||
|
||||
And if you don't have state or refs, prefer normal functions (not arrow functions) over classes:
|
||||
And if you don’t have state or refs, prefer normal functions (not arrow functions) over classes:
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -80,7 +81,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
|
||||
## Naming
|
||||
|
||||
- **Extensions**: Use `.jsx` extension for React components.
|
||||
- **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)
|
||||
- **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)
|
||||
|
||||
@@ -110,9 +111,10 @@ 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.
|
||||
- **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.
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -212,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
|
||||
@@ -265,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
|
||||
@@ -278,6 +301,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
<Foo
|
||||
userName="hello"
|
||||
phoneNumber={12345678}
|
||||
Component={SomeComponent}
|
||||
/>
|
||||
```
|
||||
|
||||
@@ -351,7 +375,11 @@ 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 unique ID. ([why?](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318))
|
||||
- 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)
|
||||
|
||||
> 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.
|
||||
|
||||
We don’t recommend using indexes for keys if the order of items may change.
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -402,7 +430,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
```
|
||||
|
||||
- Use spread props sparingly.
|
||||
> Why? Otherwise you're more likely to pass unnecessary props down to components. And for React v15.6.1 and older, you could [pass invalid HTML attributes to the DOM](https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html).
|
||||
> Why? Otherwise you’re more likely to pass unnecessary props down to components. And for React v15.6.1 and older, you could [pass invalid HTML attributes to the DOM](https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html).
|
||||
|
||||
Exceptions:
|
||||
|
||||
@@ -423,7 +451,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
}
|
||||
```
|
||||
|
||||
- Spreading objects with known, explicit props. This can be particularly useful when testing React components with Mocha's beforeEach construct.
|
||||
- Spreading objects with known, explicit props. This can be particularly useful when testing React components with Mocha’s beforeEach construct.
|
||||
|
||||
```jsx
|
||||
export default function Foo {
|
||||
@@ -440,17 +468,17 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
Filter out unnecessary props when possible. Also, use [prop-types-exact](https://www.npmjs.com/package/prop-types-exact) to help prevent bugs.
|
||||
|
||||
```jsx
|
||||
// good
|
||||
render() {
|
||||
const { irrelevantProp, ...relevantProps } = this.props;
|
||||
return <WrappedComponent {...relevantProps} />
|
||||
}
|
||||
|
||||
// bad
|
||||
render() {
|
||||
const { irrelevantProp, ...relevantProps } = this.props;
|
||||
const { irrelevantProp, ...relevantProps } = this.props;
|
||||
return <WrappedComponent {...this.props} />
|
||||
}
|
||||
|
||||
// good
|
||||
render() {
|
||||
const { irrelevantProp, ...relevantProps } = this.props;
|
||||
return <WrappedComponent {...relevantProps} />
|
||||
}
|
||||
```
|
||||
|
||||
## Refs
|
||||
@@ -509,7 +537,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
<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/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md)
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -526,7 +554,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
|
||||
## Methods
|
||||
|
||||
- Use arrow functions to close over local variables.
|
||||
- Use arrow functions to close over local variables. It is handy when you need to pass additional data to an event handler. Although, make sure they [do not massively hurt performance](https://www.bignerdranch.com/blog/choosing-the-best-approach-for-react-event-handlers/), in particular when passed to custom components that might be PureComponents, because they will trigger a possibly needless rerender every time.
|
||||
|
||||
```jsx
|
||||
function ItemList(props) {
|
||||
@@ -535,7 +563,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
{props.items.map((item, index) => (
|
||||
<Item
|
||||
key={item.key}
|
||||
onClick={() => doSomethingWith(item.name, index)}
|
||||
onClick={(event) => { doSomethingWith(event, item.name, index); }}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
@@ -545,7 +573,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
|
||||
- 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)
|
||||
|
||||
> Why? A bind call in the render path creates a brand new function on every single render.
|
||||
> 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.
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
@@ -559,6 +587,17 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
}
|
||||
}
|
||||
|
||||
// very bad
|
||||
class extends React.Component {
|
||||
onClickDiv = () => {
|
||||
// do stuff
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div onClick={this.onClickDiv} />
|
||||
}
|
||||
}
|
||||
|
||||
// good
|
||||
class extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -628,7 +667,8 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
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`
|
||||
@@ -701,7 +741,7 @@ This style guide is mostly based on the standards that are currently prevalent i
|
||||
|
||||
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