@slashnephy/eslint-config 2.0.0 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +2 -1
- package/package.json +4 -3
- package/src/base/javascript.js +1 -2
- package/src/base/javascript.ts +189 -0
- package/src/base/json.ts +5 -0
- package/src/base/typescript.js +2 -1
- package/src/base/typescript.ts +200 -0
- package/src/base/yaml.ts +19 -0
- package/src/framework/emotion.ts +20 -0
- package/src/framework/jest.ts +17 -0
- package/src/framework/next.js.ts +12 -0
- package/src/framework/react.ts +92 -0
- package/src/framework/relay.ts +10 -0
- package/src/framework/vite.ts +8 -0
- package/src/framework/vitest.ts +9 -0
- package/src/index.ts +134 -0
- package/src/presets/a11y.ts +27 -0
- package/src/presets/allow-default-export.ts +7 -0
- package/src/presets/build-configuration.ts +13 -0
- package/src/presets/node.ts +8 -0
- package/src/presets/package.json.ts +37 -0
- package/src/presets/style.ts +39 -0
- package/src/presets/userscript.ts +25 -0
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023 SlashNephy
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 SlashNephy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# eslint-config
|
|
2
2
|
|
|
3
3
|
[](https://github.com/SlashNephy/eslint-config/actions/workflows/check.yml?query=branch%3Amaster)
|
|
4
|
-

|
|
4
|
+
[](https://www.npmjs.com/package/@slashnephy/eslint-config)
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
@@ -12,6 +12,7 @@ $ yarn add @slashnephy/eslint-config
|
|
|
12
12
|
## Usage
|
|
13
13
|
|
|
14
14
|
`.eslintrc.json`
|
|
15
|
+
|
|
15
16
|
```json
|
|
16
17
|
{
|
|
17
18
|
"extends": ["@slashnephy/eslint-config"]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slashnephy/eslint-config",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"author": "SlashNephy <spica@starry.blue> (https://spica.starry.blue/)",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"files": [
|
|
13
13
|
"./package.json",
|
|
14
14
|
"./src/**/*.js",
|
|
15
|
+
"./src/**/*.ts",
|
|
15
16
|
"./README.md"
|
|
16
17
|
],
|
|
17
18
|
"publishConfig": {
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
"lint": "concurrently -n lint: 'yarn:lint:*'",
|
|
28
29
|
"lint:eslint": "yarn build && eslint .",
|
|
29
30
|
"lint:prettier": "prettier --check .",
|
|
30
|
-
"publish": "yarn
|
|
31
|
+
"publish": "yarn build && yarn npm publish"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@emotion/eslint-plugin": "11.11.0",
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
"eslint": "^8"
|
|
76
77
|
},
|
|
77
78
|
"devDependencies": {
|
|
78
|
-
"@slashnephy/prettier-config": "0.
|
|
79
|
+
"@slashnephy/prettier-config": "1.0.3",
|
|
79
80
|
"@types/eslint": "8.44.1",
|
|
80
81
|
"@types/node": "20.4.5",
|
|
81
82
|
"concurrently": "8.2.0",
|
package/src/base/javascript.js
CHANGED
|
@@ -11,7 +11,7 @@ module.exports = {
|
|
|
11
11
|
'plugin:import/recommended',
|
|
12
12
|
'plugin:xss/recommended',
|
|
13
13
|
],
|
|
14
|
-
plugins: ['import', 'promise', 'n', 'unused-imports'
|
|
14
|
+
plugins: ['import', 'promise', 'n', 'unused-imports'],
|
|
15
15
|
env: {
|
|
16
16
|
node: true,
|
|
17
17
|
es2022: true,
|
|
@@ -116,7 +116,6 @@ module.exports = {
|
|
|
116
116
|
exceptRange: true,
|
|
117
117
|
},
|
|
118
118
|
],
|
|
119
|
-
'deprecation/deprecation': 'error',
|
|
120
119
|
'unused-imports/no-unused-vars': [
|
|
121
120
|
'warn',
|
|
122
121
|
{
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import standard from 'eslint-config-standard'
|
|
2
|
+
|
|
3
|
+
import type { Linter } from 'eslint'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* JavaScript 関連の eslint プリセット
|
|
7
|
+
*/
|
|
8
|
+
module.exports = {
|
|
9
|
+
extends: [
|
|
10
|
+
'plugin:eslint-comments/recommended',
|
|
11
|
+
'plugin:node/recommended',
|
|
12
|
+
'plugin:import/recommended',
|
|
13
|
+
'plugin:xss/recommended',
|
|
14
|
+
],
|
|
15
|
+
plugins: ['import', 'promise', 'n', 'unused-imports'],
|
|
16
|
+
env: {
|
|
17
|
+
node: true,
|
|
18
|
+
es2022: true,
|
|
19
|
+
},
|
|
20
|
+
parserOptions: {
|
|
21
|
+
ecmaVersion: 'latest',
|
|
22
|
+
},
|
|
23
|
+
globals: {
|
|
24
|
+
document: 'readonly',
|
|
25
|
+
navigator: 'readonly',
|
|
26
|
+
window: 'readonly',
|
|
27
|
+
},
|
|
28
|
+
rules: {
|
|
29
|
+
...standard.rules,
|
|
30
|
+
// 不要なルール無効化コメントを報告
|
|
31
|
+
'eslint-comments/no-unused-disable': 'error',
|
|
32
|
+
// default export を禁止
|
|
33
|
+
'import/no-default-export': 'error',
|
|
34
|
+
// アロー関数を優先
|
|
35
|
+
'prefer-arrow-callback': 'error',
|
|
36
|
+
// const a = function () { ... } を禁止
|
|
37
|
+
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
|
|
38
|
+
// 中括弧の省略を禁止
|
|
39
|
+
curly: 'error',
|
|
40
|
+
// テンプレート文字列を優先
|
|
41
|
+
'prefer-template': 'error',
|
|
42
|
+
// == 比較 👉 === 比較
|
|
43
|
+
eqeqeq: 'error',
|
|
44
|
+
// *.js で 'use strict'; を強制
|
|
45
|
+
strict: ['error', 'global'],
|
|
46
|
+
// import 順を並び替える
|
|
47
|
+
'import/order': [
|
|
48
|
+
'warn',
|
|
49
|
+
{
|
|
50
|
+
// 組み込み → 外部依存 → 内部依存 → object → type の順にする
|
|
51
|
+
groups: [
|
|
52
|
+
'builtin',
|
|
53
|
+
'external',
|
|
54
|
+
['parent', 'sibling', 'index'],
|
|
55
|
+
'object',
|
|
56
|
+
'type',
|
|
57
|
+
'unknown',
|
|
58
|
+
],
|
|
59
|
+
// カテゴリー間に改行を入れる
|
|
60
|
+
'newlines-between': 'always',
|
|
61
|
+
// 大文字小文字区別なしで ABC 順にする
|
|
62
|
+
alphabetize: {
|
|
63
|
+
order: 'asc',
|
|
64
|
+
caseInsensitive: true,
|
|
65
|
+
},
|
|
66
|
+
pathGroups: [
|
|
67
|
+
// **.css は最後に配置する
|
|
68
|
+
{
|
|
69
|
+
pattern: '**.css',
|
|
70
|
+
group: 'type',
|
|
71
|
+
position: 'after',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
// **.css が import 順最後ではないときに警告
|
|
75
|
+
warnOnUnassignedImports: true,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
// 不要 import 文を禁止
|
|
79
|
+
'unused-imports/no-unused-imports': 'error',
|
|
80
|
+
// 特定の構文を禁止
|
|
81
|
+
'no-restricted-syntax': [
|
|
82
|
+
'error',
|
|
83
|
+
// 数値リテラル以外での Array#at() の使用を禁止
|
|
84
|
+
// https://qiita.com/printf_moriken/items/da03f55cb626617c1958
|
|
85
|
+
{
|
|
86
|
+
selector:
|
|
87
|
+
// eslint-disable-next-line quotes
|
|
88
|
+
"CallExpression[callee.property.name='at']:not([arguments.0.type='Literal'],[arguments.0.type='UnaryExpression'][arguments.0.argument.type='Literal'])",
|
|
89
|
+
message: 'at method accepts only a literal argument',
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
// 非同期メソッドを優先
|
|
93
|
+
'node/prefer-promises/dns': 'error',
|
|
94
|
+
'node/prefer-promises/fs': 'error',
|
|
95
|
+
// 構文のバージョンチェックを無効化
|
|
96
|
+
'node/no-unsupported-features/es-syntax': 'off',
|
|
97
|
+
// 不正確な import チェックを無効化
|
|
98
|
+
'node/no-missing-import': 'off',
|
|
99
|
+
'node/no-extraneous-import': 'off',
|
|
100
|
+
'node/no-unpublished-import': 'off',
|
|
101
|
+
'import/no-import-module-exports': 'off',
|
|
102
|
+
'import/no-extraneous-dependencies': 'off',
|
|
103
|
+
// foo["bar"] 👉 foo.bar
|
|
104
|
+
'dot-notation': 'error',
|
|
105
|
+
// {foo: foo} 👉 {foo}
|
|
106
|
+
'object-shorthand': ['error', 'always'],
|
|
107
|
+
// Array 系メソッドで return を強制
|
|
108
|
+
'array-callback-return': ['error'],
|
|
109
|
+
// ループ内では await を禁止
|
|
110
|
+
'no-await-in-loop': 'error',
|
|
111
|
+
// 操作が値に影響しない式を禁止
|
|
112
|
+
'no-constant-binary-expression': 'error',
|
|
113
|
+
// コンストラクター内で return を禁止
|
|
114
|
+
'no-constructor-return': 'error',
|
|
115
|
+
// 関数の返り値としての Promise executor を禁止
|
|
116
|
+
'no-promise-executor-return': 'error',
|
|
117
|
+
// 自身との比較 (e.g. foo === foo) を禁止
|
|
118
|
+
'no-self-compare': 'error',
|
|
119
|
+
// 非テンプレート文字列で ${foo} を禁止
|
|
120
|
+
// "Hello, ${name}" 👉 `Hello, ${name}`
|
|
121
|
+
'no-template-curly-in-string': 'error',
|
|
122
|
+
// 更新されないループ条件を禁止
|
|
123
|
+
'no-unmodified-loop-condition': 'error',
|
|
124
|
+
// 到達できないループを禁止
|
|
125
|
+
'no-unreachable-loop': 'error',
|
|
126
|
+
// 未使用の private メンバーを禁止
|
|
127
|
+
'no-unused-private-class-members': 'error',
|
|
128
|
+
// スレッドセーフで安全に更新されないコードを禁止
|
|
129
|
+
'require-atomic-updates': 'error',
|
|
130
|
+
// func () 👉 func()
|
|
131
|
+
'func-call-spacing': ['error', 'never'],
|
|
132
|
+
// ペアになっていない setter を禁止
|
|
133
|
+
'accessor-pairs': 'error',
|
|
134
|
+
// キャメルケースに強制しない
|
|
135
|
+
camelcase: 'off',
|
|
136
|
+
// switch 文で default を強制しない
|
|
137
|
+
'default-case': 'off',
|
|
138
|
+
// default export を優先しない
|
|
139
|
+
'import/prefer-default-export': 'off',
|
|
140
|
+
// 循環 import を禁止
|
|
141
|
+
'import/no-cycle': 'error',
|
|
142
|
+
// continue 文を許可
|
|
143
|
+
'no-continue': 'off',
|
|
144
|
+
// _ で始まるメンバー名を許可
|
|
145
|
+
'no-underscore-dangle': 'off',
|
|
146
|
+
// 自身より後に宣言されたメンバーの使用を許可
|
|
147
|
+
'no-use-before-define': 'off',
|
|
148
|
+
// console.* の使用を許可
|
|
149
|
+
'no-console': 'off',
|
|
150
|
+
// 深い三項演算子を許可
|
|
151
|
+
'no-nested-ternary': 'off',
|
|
152
|
+
// i++ インクリメントを許可
|
|
153
|
+
'no-plusplus': 'off',
|
|
154
|
+
// return の省略などを許可
|
|
155
|
+
'consistent-return': 'off',
|
|
156
|
+
// 空行を挟む
|
|
157
|
+
'padding-line-between-statements': [
|
|
158
|
+
'warn',
|
|
159
|
+
// return 前に空行
|
|
160
|
+
{ blankLine: 'always', prev: '*', next: 'return' },
|
|
161
|
+
// ディレクティブ後に空行
|
|
162
|
+
{ blankLine: 'always', prev: 'directive', next: '*' },
|
|
163
|
+
{ blankLine: 'any', prev: 'directive', next: 'directive' },
|
|
164
|
+
],
|
|
165
|
+
// void Promise を許可
|
|
166
|
+
'no-void': 'off',
|
|
167
|
+
// 1 <= x < 10 を許可
|
|
168
|
+
yoda: [
|
|
169
|
+
'error',
|
|
170
|
+
'never',
|
|
171
|
+
{
|
|
172
|
+
exceptRange: true,
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
// 不要な変数を禁止
|
|
176
|
+
'unused-imports/no-unused-vars': [
|
|
177
|
+
'warn',
|
|
178
|
+
// '_' で始まる変数を許可
|
|
179
|
+
{
|
|
180
|
+
vars: 'all',
|
|
181
|
+
varsIgnorePattern: '^_',
|
|
182
|
+
args: 'after-used',
|
|
183
|
+
argsIgnorePattern: '^_',
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
// anonymous な export default を許可
|
|
187
|
+
'import/no-anonymous-default-export': 'off',
|
|
188
|
+
},
|
|
189
|
+
} satisfies Linter.Config
|
package/src/base/json.ts
ADDED
package/src/base/typescript.js
CHANGED
|
@@ -8,7 +8,7 @@ module.exports = {
|
|
|
8
8
|
'plugin:no-void-return-type/recommended',
|
|
9
9
|
'plugin:storybook/recommended',
|
|
10
10
|
],
|
|
11
|
-
plugins: ['@typescript-eslint', 'tsdoc'],
|
|
11
|
+
plugins: ['@typescript-eslint', 'tsdoc', 'deprecation'],
|
|
12
12
|
parser: '@typescript-eslint/parser',
|
|
13
13
|
parserOptions: {
|
|
14
14
|
sourceType: 'module',
|
|
@@ -162,5 +162,6 @@ module.exports = {
|
|
|
162
162
|
allowBitwiseExpressions: true,
|
|
163
163
|
},
|
|
164
164
|
],
|
|
165
|
+
'deprecation/deprecation': 'error',
|
|
165
166
|
},
|
|
166
167
|
};
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import type { Linter } from 'eslint'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TypeScript 関連の eslint プリセット
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
extends: [
|
|
8
|
+
'plugin:@typescript-eslint/strict-type-checked',
|
|
9
|
+
'plugin:@typescript-eslint/stylistic-type-checked',
|
|
10
|
+
'plugin:import/typescript',
|
|
11
|
+
'plugin:no-void-return-type/recommended',
|
|
12
|
+
'plugin:storybook/recommended',
|
|
13
|
+
],
|
|
14
|
+
plugins: ['@typescript-eslint', 'tsdoc', 'deprecation'],
|
|
15
|
+
parser: '@typescript-eslint/parser',
|
|
16
|
+
parserOptions: {
|
|
17
|
+
sourceType: 'module',
|
|
18
|
+
ecmaVersion: 'latest',
|
|
19
|
+
lib: ['esnext'],
|
|
20
|
+
project: './tsconfig.json',
|
|
21
|
+
warnOnUnsupportedTypeScriptVersion: true,
|
|
22
|
+
},
|
|
23
|
+
settings: {
|
|
24
|
+
'import/parsers': {
|
|
25
|
+
'@typescript-eslint/parser': ['.ts', '.mts', '.cts', '.tsx', '.d.ts'],
|
|
26
|
+
},
|
|
27
|
+
'import/resolver': {
|
|
28
|
+
node: {
|
|
29
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
|
30
|
+
},
|
|
31
|
+
typescript: {
|
|
32
|
+
alwaysTryTypes: true,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
rules: {
|
|
37
|
+
/**
|
|
38
|
+
* Automatically fixable は error にする
|
|
39
|
+
*/
|
|
40
|
+
// interface 👉 type
|
|
41
|
+
'@typescript-eslint/consistent-type-definitions': ['error', 'type'],
|
|
42
|
+
// export type を優先
|
|
43
|
+
'@typescript-eslint/consistent-type-exports': [
|
|
44
|
+
'error',
|
|
45
|
+
{
|
|
46
|
+
fixMixedExportsWithInlineTypeSpecifier: true,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
// import type を優先
|
|
50
|
+
'@typescript-eslint/consistent-type-imports': 'error',
|
|
51
|
+
// クラスのアクセス修飾子を強制
|
|
52
|
+
'@typescript-eslint/explicit-member-accessibility': 'error',
|
|
53
|
+
// export されているメンバーや public メンバーは型を明示させる
|
|
54
|
+
'@typescript-eslint/explicit-module-boundary-types': 'warn',
|
|
55
|
+
'@typescript-eslint/member-delimiter-style': 'error',
|
|
56
|
+
'@typescript-eslint/member-ordering': 'warn',
|
|
57
|
+
'@typescript-eslint/method-signature-style': ['warn', 'method'],
|
|
58
|
+
// 命名規則を強制
|
|
59
|
+
'@typescript-eslint/naming-convention': [
|
|
60
|
+
'warn',
|
|
61
|
+
// デフォルトは camelCase
|
|
62
|
+
{
|
|
63
|
+
selector: ['default'],
|
|
64
|
+
format: ['strictCamelCase'],
|
|
65
|
+
},
|
|
66
|
+
// 型名 / 列挙型のメンバーは PascalCase
|
|
67
|
+
{
|
|
68
|
+
selector: ['typeLike', 'enumMember'],
|
|
69
|
+
format: ['StrictPascalCase'],
|
|
70
|
+
},
|
|
71
|
+
// 変数名は camelCase
|
|
72
|
+
{
|
|
73
|
+
selector: ['variableLike'],
|
|
74
|
+
format: ['strictCamelCase', 'StrictPascalCase'],
|
|
75
|
+
leadingUnderscore: 'allow',
|
|
76
|
+
},
|
|
77
|
+
// export された定数は UPPER_CASE を許容
|
|
78
|
+
{
|
|
79
|
+
selector: ['variable'],
|
|
80
|
+
modifiers: ['const', 'global', 'exported'],
|
|
81
|
+
format: ['strictCamelCase', 'StrictPascalCase', 'UPPER_CASE'],
|
|
82
|
+
},
|
|
83
|
+
// プロパティーに snake_case / UPPER_CASE を許容
|
|
84
|
+
{
|
|
85
|
+
selector: ['property'],
|
|
86
|
+
format: [
|
|
87
|
+
'strictCamelCase',
|
|
88
|
+
'snake_case',
|
|
89
|
+
'UPPER_CASE',
|
|
90
|
+
'StrictPascalCase',
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
// Boolean は特定のプレフィックスを強制
|
|
94
|
+
{
|
|
95
|
+
selector: ['variable'],
|
|
96
|
+
types: ['boolean'],
|
|
97
|
+
format: ['StrictPascalCase'],
|
|
98
|
+
prefix: [
|
|
99
|
+
'is',
|
|
100
|
+
'are',
|
|
101
|
+
'was',
|
|
102
|
+
'were',
|
|
103
|
+
'should',
|
|
104
|
+
'has',
|
|
105
|
+
'can',
|
|
106
|
+
'did',
|
|
107
|
+
'will',
|
|
108
|
+
'contains',
|
|
109
|
+
'enable',
|
|
110
|
+
'disable',
|
|
111
|
+
'show',
|
|
112
|
+
'hide',
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
// プライベートメンバーは _ で始める
|
|
116
|
+
{
|
|
117
|
+
selector: ['memberLike'],
|
|
118
|
+
modifiers: ['private'],
|
|
119
|
+
format: ['strictCamelCase'],
|
|
120
|
+
leadingUnderscore: 'require',
|
|
121
|
+
},
|
|
122
|
+
// deconstruct で宣言された変数は許容
|
|
123
|
+
{
|
|
124
|
+
selector: ['variableLike'],
|
|
125
|
+
modifiers: ['destructured'],
|
|
126
|
+
format: null,
|
|
127
|
+
},
|
|
128
|
+
// オブジェクトのキーなど '' 付きの宣言は許容
|
|
129
|
+
{
|
|
130
|
+
selector: ['memberLike', 'property'],
|
|
131
|
+
modifiers: ['requiresQuotes'],
|
|
132
|
+
format: null,
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
// void を式の値として禁止
|
|
136
|
+
'@typescript-eslint/no-confusing-void-expression': 'error',
|
|
137
|
+
// 重複した型定義を禁止
|
|
138
|
+
// boolean | false 👉 boolean
|
|
139
|
+
'@typescript-eslint/no-redundant-type-constituents': 'warn',
|
|
140
|
+
// require() を禁止
|
|
141
|
+
'@typescript-eslint/no-require-imports': 'warn',
|
|
142
|
+
'@typescript-eslint/no-unnecessary-qualifier': 'error',
|
|
143
|
+
'@typescript-eslint/no-useless-empty-export': 'error',
|
|
144
|
+
// パラメーターでのプロパティ宣言を強制
|
|
145
|
+
'@typescript-eslint/parameter-properties': [
|
|
146
|
+
'warn',
|
|
147
|
+
{
|
|
148
|
+
allow: [
|
|
149
|
+
'readonly',
|
|
150
|
+
'private',
|
|
151
|
+
'protected',
|
|
152
|
+
'public',
|
|
153
|
+
'private readonly',
|
|
154
|
+
'protected readonly',
|
|
155
|
+
'public readonly',
|
|
156
|
+
],
|
|
157
|
+
prefer: 'parameter-property',
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
'@typescript-eslint/prefer-enum-initializers': 'warn',
|
|
161
|
+
'@typescript-eslint/prefer-readonly': 'error',
|
|
162
|
+
'@typescript-eslint/prefer-regexp-exec': 'error',
|
|
163
|
+
// Promise<T> を返す関数では async のマークを強制
|
|
164
|
+
'@typescript-eslint/promise-function-async': 'error',
|
|
165
|
+
'@typescript-eslint/require-array-sort-compare': 'off',
|
|
166
|
+
'@typescript-eslint/switch-exhaustiveness-check': 'error',
|
|
167
|
+
'@typescript-eslint/type-annotation-spacing': 'error',
|
|
168
|
+
'@typescript-eslint/unbound-method': 'off',
|
|
169
|
+
// JavaScript 側で定義
|
|
170
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
171
|
+
// 過激なルールを無効化
|
|
172
|
+
'@typescript-eslint/no-unsafe-assignment': 'off',
|
|
173
|
+
'@typescript-eslint/no-unsafe-call': 'off',
|
|
174
|
+
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
175
|
+
'@typescript-eslint/no-unsafe-return': 'off',
|
|
176
|
+
'@typescript-eslint/no-unsafe-argument': 'off',
|
|
177
|
+
'@typescript-eslint/no-unsafe-enum-comparison': 'off',
|
|
178
|
+
'@typescript-eslint/restrict-template-expressions': 'off',
|
|
179
|
+
'@typescript-eslint/strict-boolean-expressions': 'off',
|
|
180
|
+
// import に拡張子を推奨
|
|
181
|
+
'import/extensions': [
|
|
182
|
+
'warn',
|
|
183
|
+
'always',
|
|
184
|
+
{
|
|
185
|
+
ignorePackages: true,
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
// TSDoc
|
|
189
|
+
'tsdoc/syntax': 'warn',
|
|
190
|
+
// enum のメンバーでビット演算を許可する
|
|
191
|
+
'@typescript-eslint/prefer-literal-enum-member': [
|
|
192
|
+
'error',
|
|
193
|
+
{
|
|
194
|
+
allowBitwiseExpressions: true,
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
// Deprecated されたコードの使用を禁止
|
|
198
|
+
'deprecation/deprecation': 'error',
|
|
199
|
+
},
|
|
200
|
+
} satisfies Linter.Config
|
package/src/base/yaml.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Linter } from 'eslint'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
extends: ['plugin:yml/standard', 'plugin:yml/prettier'],
|
|
5
|
+
parser: 'yaml-eslint-parser',
|
|
6
|
+
rules: {
|
|
7
|
+
'yml/quotes': ['error', { prefer: 'double' }],
|
|
8
|
+
},
|
|
9
|
+
overrides: [
|
|
10
|
+
// GitHub Workflow でダブルクォートが使えない場合があるのでシングルに統一
|
|
11
|
+
// https://github.com/actions/runner/issues/866
|
|
12
|
+
{
|
|
13
|
+
files: '.github/workflows/*.{yml,yaml}',
|
|
14
|
+
rules: {
|
|
15
|
+
'yml/quotes': ['error', { prefer: 'single' }],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
} satisfies Linter.Config
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Linter } from 'eslint'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Emotion 関連の eslint プリセット
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
plugins: ['@emotion', 'css-reorder'],
|
|
8
|
+
rules: {
|
|
9
|
+
'@emotion/pkg-renaming': 'error',
|
|
10
|
+
'@emotion/styled-import': 'error',
|
|
11
|
+
'@emotion/syntax-preference': 'error',
|
|
12
|
+
'css-reorder/property-reorder': 'error',
|
|
13
|
+
'react/no-unknown-property': [
|
|
14
|
+
'error',
|
|
15
|
+
{
|
|
16
|
+
ignore: ['css'],
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
} satisfies Linter.Config
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Linter } from 'eslint'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* jest 関連の eslint プリセット
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
plugins: ['jest'],
|
|
8
|
+
extends: [
|
|
9
|
+
'plugin:jest/recommended',
|
|
10
|
+
'plugin:jest/style',
|
|
11
|
+
'plugin:jest-formatting/recommended',
|
|
12
|
+
],
|
|
13
|
+
env: {
|
|
14
|
+
'jest/globals': true,
|
|
15
|
+
},
|
|
16
|
+
rules: {},
|
|
17
|
+
} satisfies Linter.Config
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import next from 'eslint-config-next'
|
|
2
|
+
|
|
3
|
+
import type { Linter } from 'eslint'
|
|
4
|
+
|
|
5
|
+
// https://github.com/vercel/next.js/blob/canary/packages/eslint-config-next/index.js
|
|
6
|
+
module.exports = {
|
|
7
|
+
extends: ['plugin:@next/next/recommended'],
|
|
8
|
+
rules: {
|
|
9
|
+
...next.rules,
|
|
10
|
+
'import/no-default-export': 'off',
|
|
11
|
+
},
|
|
12
|
+
} satisfies Linter.Config
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Linter } from 'eslint'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* React 関連の eslint プリセット
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
extends: [
|
|
8
|
+
'plugin:react/recommended',
|
|
9
|
+
'plugin:react/jsx-runtime',
|
|
10
|
+
'plugin:css-import-order/recommended',
|
|
11
|
+
],
|
|
12
|
+
plugins: ['react-hooks', 'css-import-order'],
|
|
13
|
+
parserOptions: {
|
|
14
|
+
ecmaFeatures: {
|
|
15
|
+
jsx: true,
|
|
16
|
+
},
|
|
17
|
+
jsxPragma: 'React',
|
|
18
|
+
lib: ['dom'],
|
|
19
|
+
},
|
|
20
|
+
env: {
|
|
21
|
+
browser: true,
|
|
22
|
+
node: true,
|
|
23
|
+
},
|
|
24
|
+
settings: {
|
|
25
|
+
react: {
|
|
26
|
+
version: 'detect',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
rules: {
|
|
30
|
+
// <div flag={true} /> 👉 <div flag />
|
|
31
|
+
'react/jsx-boolean-value': 'error',
|
|
32
|
+
// <div value={'test'} /> 👉 <div value='test' />
|
|
33
|
+
'react/jsx-curly-brace-presence': 'error',
|
|
34
|
+
// <div></div> 👉 <div />
|
|
35
|
+
'react/self-closing-comp': [
|
|
36
|
+
'error',
|
|
37
|
+
{
|
|
38
|
+
component: true,
|
|
39
|
+
html: true,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
// コンポーネント名を PascalCase に強制
|
|
43
|
+
'react/jsx-pascal-case': 'error',
|
|
44
|
+
// https://recoiljs.org/docs/introduction/installation/#eslint
|
|
45
|
+
'react-hooks/rules-of-hooks': 'error',
|
|
46
|
+
'react-hooks/exhaustive-deps': [
|
|
47
|
+
'warn',
|
|
48
|
+
{
|
|
49
|
+
additionalHooks: '(useRecoilCallback|useRecoilTransaction_UNSTABLE)',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
// ハンドラーの名前規則
|
|
53
|
+
'react/jsx-handler-names': 'error',
|
|
54
|
+
// useState の分解宣言 & setXXX という名前を強制
|
|
55
|
+
'react/hook-use-state': 'error',
|
|
56
|
+
// <React.Fragment /> 👉 </>
|
|
57
|
+
'react/jsx-fragments': 'error',
|
|
58
|
+
// ステートレス関数を優先
|
|
59
|
+
'react/prefer-stateless-function': 'error',
|
|
60
|
+
// props を並び替える
|
|
61
|
+
'react/jsx-sort-props': [
|
|
62
|
+
'error',
|
|
63
|
+
{
|
|
64
|
+
callbacksLast: true,
|
|
65
|
+
shorthandFirst: true,
|
|
66
|
+
multiline: 'last',
|
|
67
|
+
reservedFirst: true,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
// JSX を .tsx でも使えるように
|
|
71
|
+
'react/jsx-filename-extension': [
|
|
72
|
+
'error',
|
|
73
|
+
{
|
|
74
|
+
extensions: ['.jsx', '.tsx'],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
// props に対してスプレッド演算子を使えるように
|
|
78
|
+
'react/jsx-props-no-spreading': 'off',
|
|
79
|
+
// <></> を使えるように
|
|
80
|
+
'react/jsx-no-useless-fragment': 'off',
|
|
81
|
+
// defaultProps を使わない
|
|
82
|
+
'react/require-default-props': 'off',
|
|
83
|
+
},
|
|
84
|
+
overrides: [
|
|
85
|
+
{
|
|
86
|
+
files: '**/*.jsx',
|
|
87
|
+
rules: {
|
|
88
|
+
'react/prop-types': 'error',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
} satisfies Linter.Config
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { resolve } from 'path'
|
|
2
|
+
|
|
3
|
+
// https://github.com/microsoft/rushstack/tree/main/eslint/eslint-patch
|
|
4
|
+
import '@rushstack/eslint-patch/modern-module-resolution.js'
|
|
5
|
+
import { readGitignoreFiles } from 'eslint-gitignore'
|
|
6
|
+
|
|
7
|
+
import type { Linter } from 'eslint'
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
root: true,
|
|
11
|
+
extends: ['eslint:recommended'],
|
|
12
|
+
ignorePatterns: [
|
|
13
|
+
'**/node_modules/**',
|
|
14
|
+
'**/.yarn/**',
|
|
15
|
+
'**/dist/**',
|
|
16
|
+
...readGitignoreFiles(),
|
|
17
|
+
],
|
|
18
|
+
overrides: [
|
|
19
|
+
/*
|
|
20
|
+
* 言語固有ルール
|
|
21
|
+
*/
|
|
22
|
+
// JavaScript / TypeScript
|
|
23
|
+
{
|
|
24
|
+
files: '**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',
|
|
25
|
+
extends: resolve(__dirname, 'base/javascript.js'),
|
|
26
|
+
},
|
|
27
|
+
// TypeScript
|
|
28
|
+
{
|
|
29
|
+
files: '**/*.{ts,mts,cts,tsx}',
|
|
30
|
+
extends: [resolve(__dirname, 'base/typescript.js')],
|
|
31
|
+
},
|
|
32
|
+
// JSON
|
|
33
|
+
{
|
|
34
|
+
files: '**/*.json',
|
|
35
|
+
extends: resolve(__dirname, 'base/json.js'),
|
|
36
|
+
},
|
|
37
|
+
// YAML
|
|
38
|
+
{
|
|
39
|
+
files: '**/*.{yml,yaml}',
|
|
40
|
+
extends: resolve(__dirname, 'base/yaml.js'),
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
/*
|
|
44
|
+
* フレームワーク固有ルール
|
|
45
|
+
*/
|
|
46
|
+
// React
|
|
47
|
+
{
|
|
48
|
+
files: '**/*.{jsx,tsx}',
|
|
49
|
+
extends: resolve(__dirname, 'framework/react.js'),
|
|
50
|
+
},
|
|
51
|
+
// Relay
|
|
52
|
+
{
|
|
53
|
+
files: '**/*.{js,jsx,ts,tsx}',
|
|
54
|
+
extends: resolve(__dirname, 'framework/relay.js'),
|
|
55
|
+
},
|
|
56
|
+
// Next.js
|
|
57
|
+
{
|
|
58
|
+
files: [
|
|
59
|
+
// <= 12
|
|
60
|
+
'**/pages/**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',
|
|
61
|
+
// >= 13
|
|
62
|
+
'**/src/app/**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',
|
|
63
|
+
],
|
|
64
|
+
extends: resolve(__dirname, 'framework/next.js.js'),
|
|
65
|
+
},
|
|
66
|
+
// Vite
|
|
67
|
+
{
|
|
68
|
+
files: '**/src/**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',
|
|
69
|
+
extends: resolve(__dirname, 'framework/vite.js'),
|
|
70
|
+
},
|
|
71
|
+
// Emotion
|
|
72
|
+
{
|
|
73
|
+
files: '**/*.{jsx,tsx}',
|
|
74
|
+
extends: resolve(__dirname, 'framework/emotion.js'),
|
|
75
|
+
},
|
|
76
|
+
// jest / vitest
|
|
77
|
+
{
|
|
78
|
+
files: [
|
|
79
|
+
'**/*.test.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',
|
|
80
|
+
'**/test/**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}',
|
|
81
|
+
],
|
|
82
|
+
extends: [
|
|
83
|
+
resolve(__dirname, 'framework/jest.js'),
|
|
84
|
+
resolve(__dirname, 'framework/vitest.js'),
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
* 個別のプリセットルール
|
|
90
|
+
*/
|
|
91
|
+
// React向け a11y
|
|
92
|
+
{
|
|
93
|
+
files: '**/*.{jsx,tsx}',
|
|
94
|
+
extends: resolve(__dirname, 'presets/a11y.js'),
|
|
95
|
+
},
|
|
96
|
+
// Node.js
|
|
97
|
+
{
|
|
98
|
+
files: '**/bin/**/*.{js,mjs,cjs,ts,mts,cts}',
|
|
99
|
+
extends: resolve(__dirname, 'presets/node.js'),
|
|
100
|
+
},
|
|
101
|
+
// Cloudflare Worker
|
|
102
|
+
{
|
|
103
|
+
files: ['**/src/worker.{js,ts}', '**/functions/**/*.{js,ts}'],
|
|
104
|
+
extends: resolve(__dirname, 'presets/allow-default-export.js'),
|
|
105
|
+
},
|
|
106
|
+
// ビルドツールの構成ファイル
|
|
107
|
+
{
|
|
108
|
+
files: [
|
|
109
|
+
'**/{webpack,rollup,vite}.config.{js,mjs,cjs,ts,mts,cts}',
|
|
110
|
+
'**/codegen.{js,mjs,cjs,ts,mts,cts}',
|
|
111
|
+
],
|
|
112
|
+
extends: [
|
|
113
|
+
resolve(__dirname, 'presets/allow-default-export.js'),
|
|
114
|
+
resolve(__dirname, 'presets/build-configuration.js'),
|
|
115
|
+
resolve(__dirname, 'presets/node.js'),
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
// package.json
|
|
119
|
+
{
|
|
120
|
+
files: '**/package.json',
|
|
121
|
+
extends: resolve(__dirname, 'presets/package.json.js'),
|
|
122
|
+
},
|
|
123
|
+
// UserScript
|
|
124
|
+
{
|
|
125
|
+
files: '**/*.user.js',
|
|
126
|
+
extends: resolve(__dirname, 'presets/userscript.js'),
|
|
127
|
+
},
|
|
128
|
+
// コーディングスタイル
|
|
129
|
+
{
|
|
130
|
+
files: '**/*',
|
|
131
|
+
extends: resolve(__dirname, 'presets/style.js'),
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
} satisfies Linter.Config
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// @ts-expect-error Linter.Config
|
|
2
|
+
import airbnb from 'eslint-config-airbnb/rules/react-a11y'
|
|
3
|
+
|
|
4
|
+
import type { Linter } from 'eslint'
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
extends: ['plugin:jsx-a11y/recommended'],
|
|
8
|
+
plugins: ['jsx-a11y'],
|
|
9
|
+
parserOptions: {
|
|
10
|
+
ecmaFeatures: {
|
|
11
|
+
jsx: true,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
rules: {
|
|
15
|
+
...airbnb.rules,
|
|
16
|
+
'jsx-a11y/alt-text': [
|
|
17
|
+
'warn',
|
|
18
|
+
{
|
|
19
|
+
elements: ['img', 'object', 'area', 'input[type="image"]'],
|
|
20
|
+
img: ['Image'],
|
|
21
|
+
object: [],
|
|
22
|
+
area: [],
|
|
23
|
+
'input[type="image"]': [],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
} satisfies Linter.Config
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Linter } from 'eslint'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
extends: ['plugin:package-json/recommended'],
|
|
5
|
+
plugins: ['package-json'],
|
|
6
|
+
env: {
|
|
7
|
+
node: true,
|
|
8
|
+
},
|
|
9
|
+
rules: {
|
|
10
|
+
'package-json/order-properties': [
|
|
11
|
+
'error',
|
|
12
|
+
[
|
|
13
|
+
'name',
|
|
14
|
+
'version',
|
|
15
|
+
'type',
|
|
16
|
+
'main',
|
|
17
|
+
'private',
|
|
18
|
+
'author',
|
|
19
|
+
'description',
|
|
20
|
+
'repository',
|
|
21
|
+
'license',
|
|
22
|
+
'files',
|
|
23
|
+
'exports',
|
|
24
|
+
'publishConfig',
|
|
25
|
+
'scripts',
|
|
26
|
+
'dependencies',
|
|
27
|
+
'peerDependencies',
|
|
28
|
+
'optionalDependencies',
|
|
29
|
+
'bundledDependencies',
|
|
30
|
+
'devDependencies',
|
|
31
|
+
'packageManager',
|
|
32
|
+
'engines',
|
|
33
|
+
'eslintConfig',
|
|
34
|
+
],
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
} satisfies Linter.Config
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Linter } from 'eslint'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* スタイル関連の eslint プリセット
|
|
5
|
+
* - 特に eslint と競合しそうなルールを記述する
|
|
6
|
+
*/
|
|
7
|
+
module.exports = {
|
|
8
|
+
extends: ['plugin:editorconfig/noconflict', 'prettier'],
|
|
9
|
+
plugins: ['editorconfig'],
|
|
10
|
+
rules: {
|
|
11
|
+
// インデント
|
|
12
|
+
// - 基本インデントを 2 にする
|
|
13
|
+
// - switch-case でインデントを許可
|
|
14
|
+
// indent: ['error', 2, { SwitchCase: 1 }],
|
|
15
|
+
// 詳細なインデントは競合するので無効にして prettier に任せる
|
|
16
|
+
|
|
17
|
+
// ダブルクォーテーションを禁止
|
|
18
|
+
quotes: ['error', 'single'],
|
|
19
|
+
// セミコロンを禁止
|
|
20
|
+
semi: ['error', 'never'],
|
|
21
|
+
// UTF-8 BOM を禁止
|
|
22
|
+
'unicode-bom': ['error', 'never'],
|
|
23
|
+
// 最終行に改行を挿入
|
|
24
|
+
'eol-last': ['error', 'always'],
|
|
25
|
+
// 行末のスペースを禁止
|
|
26
|
+
'no-trailing-spaces': ['error'],
|
|
27
|
+
},
|
|
28
|
+
overrides: [
|
|
29
|
+
// JSON ではダブルクォーテーションを使う
|
|
30
|
+
{
|
|
31
|
+
files: '**/*.json',
|
|
32
|
+
rules: {
|
|
33
|
+
quotes: ['error', 'double'],
|
|
34
|
+
semi: 'off',
|
|
35
|
+
'eol-last': 'off',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
} satisfies Linter.Config
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Linter } from 'eslint'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* UserScript 開発用の eslint プリセット
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
extends: ['plugin:userscripts/recommended'],
|
|
8
|
+
rules: {
|
|
9
|
+
'no-undef': 'off',
|
|
10
|
+
'xss/no-mixed-html': 'off',
|
|
11
|
+
'xss/no-location-href-assign': 'off',
|
|
12
|
+
'userscripts/compat-grant': [
|
|
13
|
+
'error',
|
|
14
|
+
{
|
|
15
|
+
requireAllCompatible: true,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
'userscripts/compat-headers': [
|
|
19
|
+
'error',
|
|
20
|
+
{
|
|
21
|
+
requireAllCompatible: true,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
} satisfies Linter.Config
|