@shun-shobon/style-guide 1.2.0 → 1.2.2
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/dist/eslint/index.d.mts +4448 -0
- package/dist/eslint/index.mjs +519 -0
- package/dist/eslint/index.mjs.map +1 -0
- package/dist/prettier/index.d.mts +61 -0
- package/dist/prettier/index.mjs +103 -0
- package/dist/prettier/index.mjs.map +1 -0
- package/package.json +17 -16
- package/dist/eslint/index.d.ts +0 -4995
- package/dist/eslint/index.js +0 -831
- package/dist/eslint/index.js.map +0 -1
- package/dist/prettier/index.d.ts +0 -53
- package/dist/prettier/index.js +0 -127
- package/dist/prettier/index.js.map +0 -1
package/dist/eslint/index.js
DELETED
|
@@ -1,831 +0,0 @@
|
|
|
1
|
-
// src/eslint/globs.ts
|
|
2
|
-
var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
|
|
3
|
-
var GLOB_SRC = `**/*.${GLOB_SRC_EXT}`;
|
|
4
|
-
var GLOB_JS_EXT = "?([cm])js";
|
|
5
|
-
var GLOB_JS = `**/*.${GLOB_JS_EXT}`;
|
|
6
|
-
var GLOB_JSX_EXT = "?([cm])jsx";
|
|
7
|
-
var GLOB_JSX = `**/*.${GLOB_JSX_EXT}`;
|
|
8
|
-
var GLOB_TS_EXT = "?([cm])ts";
|
|
9
|
-
var GLOB_TS = `**/*.${GLOB_TS_EXT}`;
|
|
10
|
-
var GLOB_TSX_EXT = "?([cm])tsx";
|
|
11
|
-
var GLOB_TSX = `**/*.${GLOB_TSX_EXT}`;
|
|
12
|
-
var GLOB_DTS_EXT = "?([cm])d.ts";
|
|
13
|
-
var GLOB_DTS = `**/*.${GLOB_DTS_EXT}`;
|
|
14
|
-
var GLOB_STORYBOOK_EXT = `@(stories|story).${GLOB_TSX_EXT}`;
|
|
15
|
-
var GLOB_STORYBOOK = `**/*.${GLOB_STORYBOOK_EXT}`;
|
|
16
|
-
var GLOB_STORYBOOK_CONFIG = `**/.storybook/main.${GLOB_SRC_EXT}`;
|
|
17
|
-
var GLOB_ASTRO_EXT = "astro";
|
|
18
|
-
var GLOB_ASTRO = `**/*.${GLOB_ASTRO_EXT}`;
|
|
19
|
-
|
|
20
|
-
// src/eslint/utils.ts
|
|
21
|
-
async function interopDefault(module) {
|
|
22
|
-
const resolved = await module;
|
|
23
|
-
return resolved.default ?? resolved;
|
|
24
|
-
}
|
|
25
|
-
function renameRules(rules, from, to) {
|
|
26
|
-
return Object.fromEntries(
|
|
27
|
-
Object.entries(rules).map(([key, value]) => [
|
|
28
|
-
key.startsWith(from) ? `${to}${key.slice(from.length)}` : key,
|
|
29
|
-
value
|
|
30
|
-
])
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// src/eslint/configs/astro.ts
|
|
35
|
-
async function astro(options = {}) {
|
|
36
|
-
const { typescript: typescript2 = true } = options;
|
|
37
|
-
const [pluginAstro, parserAstro] = await Promise.all([
|
|
38
|
-
interopDefault(import("eslint-plugin-astro")),
|
|
39
|
-
interopDefault(import("astro-eslint-parser"))
|
|
40
|
-
]);
|
|
41
|
-
return [
|
|
42
|
-
{
|
|
43
|
-
name: "shun-shobon/astro/plugins",
|
|
44
|
-
plugins: {
|
|
45
|
-
astro: pluginAstro
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
name: "shun-shobon/astro/rules",
|
|
50
|
-
files: [GLOB_ASTRO],
|
|
51
|
-
languageOptions: {
|
|
52
|
-
parser: parserAstro,
|
|
53
|
-
parserOptions: {
|
|
54
|
-
parser: typescript2 ? await interopDefault(import("@typescript-eslint/parser")) : void 0,
|
|
55
|
-
extraFileExtensions: [".astro"]
|
|
56
|
-
},
|
|
57
|
-
globals: {
|
|
58
|
-
Astro: "readonly",
|
|
59
|
-
Fragment: "readonly"
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
processor: pluginAstro.processors[typescript2 ? "client-side-ts" : "astro"],
|
|
63
|
-
rules: {
|
|
64
|
-
// Astroの推奨ルールを有効化
|
|
65
|
-
...pluginAstro.configs.recommended.at(-1).rules,
|
|
66
|
-
// Astroのjsx-a11yの拡張ルール(strict)を有効化
|
|
67
|
-
...pluginAstro.configs["jsx-a11y-strict"].at(-1).rules,
|
|
68
|
-
// 曖昧なリンクのテキストを許可しない
|
|
69
|
-
"astro/jsx-a11y/anchor-ambiguous-text": "error",
|
|
70
|
-
// インタラクティブな要素にラベルが付いていないことを許可しない
|
|
71
|
-
"astro/jsx-a11y/control-has-associated-label": "error",
|
|
72
|
-
// html要素にlang属性が付与されていないことを許可しない
|
|
73
|
-
"astro/jsx-a11y/lang": "error",
|
|
74
|
-
// フォーカス可能な要素に `aria-hidden` 属性を付与することを許可しない
|
|
75
|
-
"astro/jsx-a11y/no-aria-hidden-on-focusable": "error"
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// src/eslint/configs/base.ts
|
|
82
|
-
function base() {
|
|
83
|
-
return [
|
|
84
|
-
{
|
|
85
|
-
name: "shun-shobon/base/setup",
|
|
86
|
-
linterOptions: {
|
|
87
|
-
reportUnusedDisableDirectives: true
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
];
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// src/eslint/configs/disable-type-checked.ts
|
|
94
|
-
async function disableTypeChecked(options = {}) {
|
|
95
|
-
const { disableTypeCheckedFiles = [] } = options;
|
|
96
|
-
const { configs: configsTypeScript } = await interopDefault(
|
|
97
|
-
import("typescript-eslint")
|
|
98
|
-
);
|
|
99
|
-
return [
|
|
100
|
-
{
|
|
101
|
-
name: "shun-shobon/disableTypeChecked/rules",
|
|
102
|
-
files: disableTypeCheckedFiles,
|
|
103
|
-
languageOptions: {
|
|
104
|
-
parserOptions: {
|
|
105
|
-
projectService: false
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
rules: {
|
|
109
|
-
...renameRules(
|
|
110
|
-
configsTypeScript.disableTypeChecked.rules,
|
|
111
|
-
"@typescript-eslint/",
|
|
112
|
-
"typescript/"
|
|
113
|
-
)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// src/eslint/plugins.ts
|
|
120
|
-
import { default as default2 } from "@eslint/js";
|
|
121
|
-
import { default as default3 } from "eslint-plugin-import-x";
|
|
122
|
-
import { default as default4 } from "eslint-plugin-jsx-a11y";
|
|
123
|
-
import { default as default5 } from "eslint-plugin-n";
|
|
124
|
-
import { default as default6 } from "eslint-plugin-regexp";
|
|
125
|
-
import { default as default7 } from "eslint-plugin-simple-import-sort";
|
|
126
|
-
import { default as default8 } from "eslint-plugin-unicorn";
|
|
127
|
-
|
|
128
|
-
// src/eslint/configs/import-sort.ts
|
|
129
|
-
function importSort() {
|
|
130
|
-
return [
|
|
131
|
-
{
|
|
132
|
-
name: "shun-shobon/importSort/setup",
|
|
133
|
-
plugins: {
|
|
134
|
-
"import-sort": default7
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
name: "shun-shobon/importSort/rules",
|
|
139
|
-
rules: {
|
|
140
|
-
// importをソートする
|
|
141
|
-
"import-sort/imports": "warn",
|
|
142
|
-
// exportをソートする
|
|
143
|
-
"import-sort/exports": "warn"
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
];
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// src/eslint/configs/imports.ts
|
|
150
|
-
function imports(options) {
|
|
151
|
-
const { typescript: typescript2 = false } = options;
|
|
152
|
-
return [
|
|
153
|
-
{
|
|
154
|
-
name: "shun-shobon/imports/setup",
|
|
155
|
-
plugins: {
|
|
156
|
-
import: default3
|
|
157
|
-
},
|
|
158
|
-
settings: {
|
|
159
|
-
"import-x/parsers": {
|
|
160
|
-
espree: [".js", ".cjs", ".mjs", ".jsx"],
|
|
161
|
-
...typescript2 ? { "@typescript-eslint/parser": [".ts", ".mts", ".cts", ".tsx"] } : {}
|
|
162
|
-
},
|
|
163
|
-
"import-x/extensions": [
|
|
164
|
-
".js",
|
|
165
|
-
".jsx",
|
|
166
|
-
...typescript2 ? [".ts", ".tsx", ".d.ts"] : []
|
|
167
|
-
]
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
name: "shun-shobon/imports/rules",
|
|
172
|
-
rules: {
|
|
173
|
-
...renameRules(
|
|
174
|
-
default3.configs.recommended.rules,
|
|
175
|
-
"import-x/",
|
|
176
|
-
"import/"
|
|
177
|
-
),
|
|
178
|
-
// import先のモジュールが存在するかチェックしない
|
|
179
|
-
// TSの型チェックで十分なため
|
|
180
|
-
"import/namespace": "off",
|
|
181
|
-
"import/no-unresolved": "off",
|
|
182
|
-
"import/named": "off",
|
|
183
|
-
// type import時に`import type { foo } from "foo"`を強制
|
|
184
|
-
"import/consistent-type-specifier-style": ["warn", "prefer-top-level"],
|
|
185
|
-
// import文を一番上に書くのを強制
|
|
186
|
-
"import/first": "error",
|
|
187
|
-
// 同じパスからのimportをまとめる
|
|
188
|
-
"import/no-duplicates": "warn",
|
|
189
|
-
// default import時に`{ default as foo } from "foo"`と書くのを警告
|
|
190
|
-
"import/no-named-default": "warn",
|
|
191
|
-
// import文のパスを簡略化する
|
|
192
|
-
"import/no-useless-path-segments": ["warn", { noUselessIndex: true }],
|
|
193
|
-
// 自分自身をimportするのを禁止
|
|
194
|
-
"import/no-self-import": "error"
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
];
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// src/eslint/configs/javascript.ts
|
|
201
|
-
import globals from "globals";
|
|
202
|
-
function javascript() {
|
|
203
|
-
return [
|
|
204
|
-
{
|
|
205
|
-
name: "shun-shobon/javascript/rules",
|
|
206
|
-
languageOptions: {
|
|
207
|
-
ecmaVersion: "latest",
|
|
208
|
-
sourceType: "module",
|
|
209
|
-
globals: {
|
|
210
|
-
...globals.es2021,
|
|
211
|
-
...globals.browser,
|
|
212
|
-
...globals.node
|
|
213
|
-
},
|
|
214
|
-
parserOptions: {
|
|
215
|
-
ecmaFeatures: {
|
|
216
|
-
jax: true
|
|
217
|
-
},
|
|
218
|
-
ecmaVersion: "latest",
|
|
219
|
-
sourceType: "module"
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
rules: {
|
|
223
|
-
...default2.configs.recommended.rules,
|
|
224
|
-
// Arrayの関数に`return`を忘れないようにする
|
|
225
|
-
"array-callback-return": "error",
|
|
226
|
-
// 常にtrue/falseになる式や短絡評価されない式を警告
|
|
227
|
-
"no-constant-binary-expression": "warn",
|
|
228
|
-
// コンストラクタの戻り値を許可しない
|
|
229
|
-
"no-constructor-return": "error",
|
|
230
|
-
// Symbol/BigIntでnewしない
|
|
231
|
-
"no-new-native-nonconstructor": "error",
|
|
232
|
-
// `Promise`のコンストラクタの戻り値を許可しない
|
|
233
|
-
"no-promise-executor-return": "error",
|
|
234
|
-
// 自分自身を比較する式を許可しない
|
|
235
|
-
// NaNチェックは`Number.isNaN()`を使う
|
|
236
|
-
"no-self-compare": "error",
|
|
237
|
-
// ループの条件式の変数をループ内で変更していない場合に警告
|
|
238
|
-
"no-unmodified-loop-condition": "warn",
|
|
239
|
-
// 条件式が常にtrue/falseになる場合を警告
|
|
240
|
-
// ただし、ループ内の条件式は除外
|
|
241
|
-
"no-constant-condition": ["error", { checkLoops: false }],
|
|
242
|
-
// 1回しかループしないループを警告
|
|
243
|
-
"no-unreachable-loop": "warn",
|
|
244
|
-
// 未使用のプライベートクラスメンバーを警告
|
|
245
|
-
"no-unused-private-class-members": "warn",
|
|
246
|
-
// `_`から始まる変数名以外の未使用変数を警告
|
|
247
|
-
"no-unused-vars": [
|
|
248
|
-
"warn",
|
|
249
|
-
{
|
|
250
|
-
varsIgnorePattern: "^_",
|
|
251
|
-
argsIgnorePattern: "^_"
|
|
252
|
-
}
|
|
253
|
-
],
|
|
254
|
-
// 競合が発生する可能性のある値の代入を許可しない
|
|
255
|
-
"require-atomic-updates": "error",
|
|
256
|
-
// 循環的複雑度を15以上を警告
|
|
257
|
-
"complexity": ["warn", 15],
|
|
258
|
-
// switch文のデフォルトケースを最後にする
|
|
259
|
-
"default-case-last": "error",
|
|
260
|
-
// デフォルト引数を最後にする
|
|
261
|
-
"default-param-last": "error",
|
|
262
|
-
// nullチェックを除いて厳密でない等価演算子を許可しない
|
|
263
|
-
"eqeqeq": ["error", "always", { null: "ignore" }],
|
|
264
|
-
// getter/setterをグループ化
|
|
265
|
-
"grouped-accessor-pairs": ["error", "setBeforeGet"],
|
|
266
|
-
// `console.log()`/`alert`を警告
|
|
267
|
-
"no-alert": "warn",
|
|
268
|
-
"no-console": ["warn", { allow: ["warn", "error"] }],
|
|
269
|
-
// `else { return }`を警告
|
|
270
|
-
"no-else-return": "warn",
|
|
271
|
-
// `!!`や`~`を使った短縮型変換を許可しない
|
|
272
|
-
"no-implicit-coercion": "error",
|
|
273
|
-
// 不要なifのネストを許可しない
|
|
274
|
-
"no-lonely-if": "error",
|
|
275
|
-
// 複数の代入を許可しない
|
|
276
|
-
"no-multi-assign": "error",
|
|
277
|
-
// 複数行文字列を警告
|
|
278
|
-
"no-multi-str": "warn",
|
|
279
|
-
// `Function`/`Object`/`String`/`Number`/`Boolean`のコンストラクタを許可しない
|
|
280
|
-
"no-new-func": "error",
|
|
281
|
-
"no-new-wrappers": "error",
|
|
282
|
-
// 関数の引数を再代入することを許可しない
|
|
283
|
-
"no-param-reassign": "error",
|
|
284
|
-
// インクリメント/デクリメント演算子を許可しない
|
|
285
|
-
"no-plusplus": "error",
|
|
286
|
-
// `throw` に文字列を渡さない
|
|
287
|
-
"no-throw-literal": "error",
|
|
288
|
-
// 不要な三項演算子を警告
|
|
289
|
-
"no-unneeded-ternary": "warn",
|
|
290
|
-
// 未使用の式を警告
|
|
291
|
-
"no-unused-expressions": "warn",
|
|
292
|
-
// 意味の無いコンストラクタを警告
|
|
293
|
-
"no-useless-constructor": "warn",
|
|
294
|
-
// 意味の無い`return`を警告
|
|
295
|
-
"no-useless-return": "warn",
|
|
296
|
-
// `var`を許可しない
|
|
297
|
-
"no-var": "error",
|
|
298
|
-
// オブジェクトのショートハンド記法を使用していない場合は警告
|
|
299
|
-
"object-shorthand": "warn",
|
|
300
|
-
// 演算子のショートハンド記法を使用していない場合は警告
|
|
301
|
-
"operator-assignment": "warn",
|
|
302
|
-
// コールバック関数をアロー関数にする
|
|
303
|
-
"prefer-arrow-callback": "warn",
|
|
304
|
-
// `const`を使用する
|
|
305
|
-
"prefer-const": "warn",
|
|
306
|
-
// 名前付きキャプチャグループを使用する
|
|
307
|
-
"prefer-named-capture-group": "warn",
|
|
308
|
-
// `Number.parseInt()`を使用する
|
|
309
|
-
"prefer-numeric-literals": "error",
|
|
310
|
-
// `hasOwnProperty`の使用を許可しない
|
|
311
|
-
"prefer-object-has-own": "error",
|
|
312
|
-
// スプレッド構文を使用する
|
|
313
|
-
"prefer-object-spread": "warn",
|
|
314
|
-
// `Promise`の`reject`には`Error`オブジェクトを渡す
|
|
315
|
-
"prefer-promise-reject-errors": "error",
|
|
316
|
-
// なるべく正規表現リテラルを使用する
|
|
317
|
-
"prefer-regex-literals": "warn",
|
|
318
|
-
// `arguments`/`.apply()`の代わりに`...args`を使用する
|
|
319
|
-
"prefer-rest-params": "warn",
|
|
320
|
-
"prefer-spread": "warn",
|
|
321
|
-
// `parseInt`には基数を渡す
|
|
322
|
-
"radix": "error",
|
|
323
|
-
// 正規表現のユニコードフラグを使用する
|
|
324
|
-
"require-unicode-regexp": "warn",
|
|
325
|
-
// シンボルに名前を付ける
|
|
326
|
-
"symbol-description": "warn"
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
];
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// src/eslint/configs/jsx-a11y.ts
|
|
333
|
-
function jsxA11y() {
|
|
334
|
-
return [
|
|
335
|
-
{
|
|
336
|
-
name: "shun-shobon/jsxA11y/setup",
|
|
337
|
-
plugins: {
|
|
338
|
-
// eslint-disable-next-line typescript/no-unsafe-assignment
|
|
339
|
-
"jsx-a11y": default4
|
|
340
|
-
},
|
|
341
|
-
settings: {
|
|
342
|
-
"jsx-a11y": {
|
|
343
|
-
polymorphicPropName: "as"
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
];
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// src/eslint/configs/next.ts
|
|
351
|
-
async function next() {
|
|
352
|
-
const pluginNext = await interopDefault(import("@next/eslint-plugin-next"));
|
|
353
|
-
return [
|
|
354
|
-
{
|
|
355
|
-
name: "shun-shobon/next/setup",
|
|
356
|
-
plugins: {
|
|
357
|
-
next: pluginNext
|
|
358
|
-
}
|
|
359
|
-
},
|
|
360
|
-
{
|
|
361
|
-
name: "shun-shobon/next/rules",
|
|
362
|
-
files: [GLOB_SRC],
|
|
363
|
-
rules: {
|
|
364
|
-
// Next.jsの推奨ルールを有効化
|
|
365
|
-
...renameRules(
|
|
366
|
-
pluginNext.configs.recommended.rules,
|
|
367
|
-
"@next/next/",
|
|
368
|
-
"next/"
|
|
369
|
-
),
|
|
370
|
-
// Next.jsの更に厳格なルールを有効化
|
|
371
|
-
...renameRules(
|
|
372
|
-
pluginNext.configs["core-web-vitals"].rules,
|
|
373
|
-
"@next/next/",
|
|
374
|
-
"next/"
|
|
375
|
-
),
|
|
376
|
-
// `img`要素を使う場合もあるので無効化
|
|
377
|
-
"next/no-img-element": "off"
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
];
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// src/eslint/configs/node.ts
|
|
384
|
-
function node() {
|
|
385
|
-
return [
|
|
386
|
-
{
|
|
387
|
-
name: "shun-shobon/node/setup",
|
|
388
|
-
plugins: {
|
|
389
|
-
node: default5
|
|
390
|
-
}
|
|
391
|
-
},
|
|
392
|
-
{
|
|
393
|
-
name: "shun-shobon/node/rules",
|
|
394
|
-
rules: {
|
|
395
|
-
"node/no-deprecated-api": "error",
|
|
396
|
-
"node/no-exports-assign": "error",
|
|
397
|
-
"node/no-path-concat": "error",
|
|
398
|
-
"node/no-process-exit": "error",
|
|
399
|
-
"node/no-unpublished-bin": "error",
|
|
400
|
-
"node/no-sync": "error",
|
|
401
|
-
"node/process-exit-as-throw": "error",
|
|
402
|
-
"node/prefer-global/console": "error",
|
|
403
|
-
"node/prefer-global/text-decoder": "error",
|
|
404
|
-
"node/prefer-global/text-encoder": "error",
|
|
405
|
-
"node/prefer-global/url": "error",
|
|
406
|
-
"node/prefer-global/url-search-params": "error",
|
|
407
|
-
"node/prefer-promises/dns": "error",
|
|
408
|
-
"node/prefer-promises/fs": "error"
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
];
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// src/eslint/configs/qwik.ts
|
|
415
|
-
async function qwik() {
|
|
416
|
-
const pluginQwik = await interopDefault(import("eslint-plugin-qwik"));
|
|
417
|
-
return [
|
|
418
|
-
{
|
|
419
|
-
name: "shun-shobon/qwik/setup",
|
|
420
|
-
plugins: {
|
|
421
|
-
// eslint-disable-next-line typescript/no-unsafe-assignment
|
|
422
|
-
qwik: pluginQwik
|
|
423
|
-
}
|
|
424
|
-
},
|
|
425
|
-
{
|
|
426
|
-
name: "shun-shobon/qwik/rules",
|
|
427
|
-
files: [GLOB_JSX, GLOB_TSX],
|
|
428
|
-
rules: {
|
|
429
|
-
// qwikの推奨ルールを有効化
|
|
430
|
-
// eslint-disable-next-line typescript/no-unsafe-member-access
|
|
431
|
-
...pluginQwik.configs.recommended.rules,
|
|
432
|
-
// qwikの厳格ルールを有効化
|
|
433
|
-
// eslint-disable-next-line typescript/no-unsafe-member-access
|
|
434
|
-
...pluginQwik.configs.strict.rules
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
];
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// src/eslint/configs/react.ts
|
|
441
|
-
async function react(options = {}) {
|
|
442
|
-
const { typescript: typescript2 = false } = options;
|
|
443
|
-
const [pluginReact, pluginReactHooks] = await Promise.all([
|
|
444
|
-
interopDefault(import("eslint-plugin-react")),
|
|
445
|
-
interopDefault(import("eslint-plugin-react-hooks"))
|
|
446
|
-
]);
|
|
447
|
-
return [
|
|
448
|
-
{
|
|
449
|
-
name: "shun-shobon/react/setup",
|
|
450
|
-
plugins: {
|
|
451
|
-
"react": pluginReact,
|
|
452
|
-
"react-hooks": pluginReactHooks
|
|
453
|
-
},
|
|
454
|
-
settings: {
|
|
455
|
-
react: {
|
|
456
|
-
version: "detect"
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
name: "shun-shobon/react/rules",
|
|
462
|
-
files: [GLOB_JSX, GLOB_TSX],
|
|
463
|
-
rules: {
|
|
464
|
-
// reactの推奨ルールを有効化
|
|
465
|
-
...pluginReact.configs.recommended.rules,
|
|
466
|
-
// React v17以降のJSX Runtimeを使う場合の不要なルールを無効化
|
|
467
|
-
...pluginReact.configs["jsx-runtime"].rules,
|
|
468
|
-
// React Hooksの推奨ルールを有効化
|
|
469
|
-
...pluginReactHooks.configs.recommended.rules,
|
|
470
|
-
// JSX A11yの厳格なルールを有効化
|
|
471
|
-
// eslint-disable-next-line typescript/no-unsafe-member-access
|
|
472
|
-
...default4.configs.strict.rules,
|
|
473
|
-
// その他必要なものを有効化
|
|
474
|
-
// `onClick`などのイベントハンドラーの命名規則をチェック
|
|
475
|
-
"react/jsx-handler-names": "warn",
|
|
476
|
-
// ContextのProviderに即値を渡さないようにする
|
|
477
|
-
// 即値で渡すと、Providerが含まれるコンポーネントの再描画時に新しい値が渡されてしまい、再描画が発生する
|
|
478
|
-
"react/jsx-no-constructed-context-values": "warn",
|
|
479
|
-
// `React.Fragment`を省略可能な場合は省略する
|
|
480
|
-
// ただし、フラグメントのみの場合は許可する
|
|
481
|
-
"react/jsx-no-useless-fragment": ["warn", { allowExpressions: true }],
|
|
482
|
-
// rel 属性の値をチェック
|
|
483
|
-
"react/no-invalid-html-attribute": "warn",
|
|
484
|
-
// propsのデフォルト値としてobjectやarrayのリテラルを使用しないようにする
|
|
485
|
-
// 使用してしまうと、再描画が発生する可能性がある
|
|
486
|
-
"react/no-object-type-as-default-prop": "warn",
|
|
487
|
-
// コンポーネント内でコンポーネントを定義するのを許可しない
|
|
488
|
-
"react/no-unstable-nested-components": "error",
|
|
489
|
-
...typescript2 ? {
|
|
490
|
-
// TypeScriptの型チェックで検出できるものは無効化
|
|
491
|
-
// propTypesはTSで代替できるので無効化
|
|
492
|
-
"react/prop-types": "off",
|
|
493
|
-
// HTMLの属性名として認識されていない属性名を許可
|
|
494
|
-
// TSで型チェックしているので不要
|
|
495
|
-
"react/no-unknown-property": "off"
|
|
496
|
-
} : {},
|
|
497
|
-
// 曖昧なリンクのテキストを許可しない
|
|
498
|
-
"jsx-a11y/anchor-ambiguous-text": "error",
|
|
499
|
-
// インタラクティブな要素にラベルが付いていないことを許可しない
|
|
500
|
-
"jsx-a11y/control-has-associated-label": "error",
|
|
501
|
-
// html要素にlang属性が付与されていないことを許可しない
|
|
502
|
-
"jsx-a11y/lang": "error",
|
|
503
|
-
// フォーカス可能な要素に `aria-hidden` 属性を付与することを許可しない
|
|
504
|
-
"jsx-a11y/no-aria-hidden-on-focusable": "error"
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
];
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// src/eslint/configs/regexp.ts
|
|
511
|
-
function regexp() {
|
|
512
|
-
return [
|
|
513
|
-
{
|
|
514
|
-
name: "shun-shobon/regexp/setup",
|
|
515
|
-
plugins: {
|
|
516
|
-
regexp: default6
|
|
517
|
-
}
|
|
518
|
-
},
|
|
519
|
-
{
|
|
520
|
-
name: "shun-shobon/regexp/rules",
|
|
521
|
-
rules: {
|
|
522
|
-
// 推奨ルールを使用
|
|
523
|
-
...default6.configs["flat/recommended"].rules
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
];
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// src/eslint/configs/storybook.ts
|
|
530
|
-
async function storybook() {
|
|
531
|
-
const pluginStorybook = await interopDefault(
|
|
532
|
-
import("eslint-plugin-storybook")
|
|
533
|
-
);
|
|
534
|
-
return [
|
|
535
|
-
{
|
|
536
|
-
name: "shun-shobon/storybook/setup",
|
|
537
|
-
plugins: {
|
|
538
|
-
storybook: pluginStorybook
|
|
539
|
-
}
|
|
540
|
-
},
|
|
541
|
-
{
|
|
542
|
-
name: "shun-shobon/storybook/rules",
|
|
543
|
-
files: [GLOB_STORYBOOK],
|
|
544
|
-
rules: {
|
|
545
|
-
// Storybookの推奨ルールから拝借
|
|
546
|
-
"import/no-anonymous-default-export": "off",
|
|
547
|
-
"storybook/await-interactions": "error",
|
|
548
|
-
"storybook/context-in-play-function": "error",
|
|
549
|
-
"storybook/default-exports": "error",
|
|
550
|
-
"storybook/hierarchy-separator": "warn",
|
|
551
|
-
"storybook/no-redundant-story-name": "warn",
|
|
552
|
-
"storybook/prefer-pascal-case": "warn",
|
|
553
|
-
"storybook/story-exports": "error",
|
|
554
|
-
"storybook/use-storybook-expect": "error",
|
|
555
|
-
"storybook/use-storybook-testing-library": "error"
|
|
556
|
-
}
|
|
557
|
-
},
|
|
558
|
-
// Storybookの設定ファイルへのルール
|
|
559
|
-
{
|
|
560
|
-
name: "shun-shobon/storybook/config-rules",
|
|
561
|
-
files: [GLOB_STORYBOOK_CONFIG],
|
|
562
|
-
rules: {
|
|
563
|
-
"storybook/no-uninstalled-addons": "error"
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
];
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// src/eslint/configs/typescript.ts
|
|
570
|
-
async function typescript(options = {}) {
|
|
571
|
-
const { componentExts = [] } = options;
|
|
572
|
-
const {
|
|
573
|
-
plugin: pluginTypeScript,
|
|
574
|
-
parser: parserTypeScript,
|
|
575
|
-
configs: configsTypeScript
|
|
576
|
-
} = await import("typescript-eslint");
|
|
577
|
-
return [
|
|
578
|
-
{
|
|
579
|
-
name: "shun-shobon/typescript/setup",
|
|
580
|
-
plugins: {
|
|
581
|
-
typescript: pluginTypeScript
|
|
582
|
-
}
|
|
583
|
-
},
|
|
584
|
-
{
|
|
585
|
-
name: "shun-shobon/typescript/rules",
|
|
586
|
-
files: [GLOB_SRC, ...componentExts.map((ext) => `**/*.${ext}`)],
|
|
587
|
-
languageOptions: {
|
|
588
|
-
parser: parserTypeScript,
|
|
589
|
-
parserOptions: {
|
|
590
|
-
projectService: {
|
|
591
|
-
allowDefaultProject: ["./*.js"]
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
},
|
|
595
|
-
rules: {
|
|
596
|
-
// 厳密なルール + 型チェックのルールを有効化
|
|
597
|
-
...renameRules(
|
|
598
|
-
configsTypeScript.strictTypeChecked.at(-1).rules,
|
|
599
|
-
"@typescript-eslint/",
|
|
600
|
-
"typescript/"
|
|
601
|
-
),
|
|
602
|
-
// コーディング規約 + 型チェックのルールを有効化
|
|
603
|
-
...renameRules(
|
|
604
|
-
configsTypeScript.stylisticTypeChecked.at(-1).rules,
|
|
605
|
-
"@typescript-eslint/",
|
|
606
|
-
"typescript/"
|
|
607
|
-
),
|
|
608
|
-
// exportされている関数は型の明示を必須にする
|
|
609
|
-
"typescript/explicit-module-boundary-types": "warn",
|
|
610
|
-
// 型をexportする際に`type`の付与を必須にする
|
|
611
|
-
"typescript/consistent-type-exports": [
|
|
612
|
-
"error",
|
|
613
|
-
{
|
|
614
|
-
fixMixedExportsWithInlineTypeSpecifier: true
|
|
615
|
-
}
|
|
616
|
-
],
|
|
617
|
-
// 型をimportする際に`type`の付与を必須にする
|
|
618
|
-
"typescript/consistent-type-imports": "error",
|
|
619
|
-
// `_`から始まる変数名以外の未使用変数を警告
|
|
620
|
-
"typescript/no-unused-vars": [
|
|
621
|
-
"warn",
|
|
622
|
-
{
|
|
623
|
-
varsIgnorePattern: "^_",
|
|
624
|
-
argsIgnorePattern: "^_"
|
|
625
|
-
}
|
|
626
|
-
],
|
|
627
|
-
// 副作用の可能性のあるtype importを警告
|
|
628
|
-
"typescript/no-import-type-side-effects": "warn",
|
|
629
|
-
// なるべくreadonlyを付与する
|
|
630
|
-
"typescript/prefer-readonly": "warn",
|
|
631
|
-
// `Promise`を返す関数は`async`を付与する
|
|
632
|
-
"typescript/promise-function-async": "error",
|
|
633
|
-
// ソートでは必ず比較関数を渡す
|
|
634
|
-
"typescript/require-array-sort-compare": "error",
|
|
635
|
-
// `return await`を使う
|
|
636
|
-
// 一貫性のためと、awaitが無くなったときにasyncを外すのは面倒なため
|
|
637
|
-
// また、スタックトレースが読みやすくなる
|
|
638
|
-
"typescript/return-await": ["warn", "always"],
|
|
639
|
-
"typescript/no-unnecessary-condition": [
|
|
640
|
-
"warn",
|
|
641
|
-
{ allowConstantLoopConditions: true }
|
|
642
|
-
],
|
|
643
|
-
// null assertion `!` を許可
|
|
644
|
-
"typescript/no-non-null-assertion": "off",
|
|
645
|
-
// template stringへの変数埋め込みの制限をstrictよりも緩和
|
|
646
|
-
"typescript/restrict-template-expressions": [
|
|
647
|
-
"error",
|
|
648
|
-
{
|
|
649
|
-
allowAny: true,
|
|
650
|
-
allowBoolean: false,
|
|
651
|
-
allowNullish: false,
|
|
652
|
-
allowNumber: true,
|
|
653
|
-
allowRegExp: false,
|
|
654
|
-
allowNever: false
|
|
655
|
-
}
|
|
656
|
-
]
|
|
657
|
-
}
|
|
658
|
-
},
|
|
659
|
-
{
|
|
660
|
-
name: "shun-shobon/typescript/disables/eslint-recommended",
|
|
661
|
-
files: [GLOB_TS, GLOB_TSX, ...componentExts.map((ext) => `**/*.${ext}`)],
|
|
662
|
-
rules: {
|
|
663
|
-
// ESLintの推奨ルールからTypeScriptで検証可能なものを無効化
|
|
664
|
-
...configsTypeScript.eslintRecommended.rules
|
|
665
|
-
}
|
|
666
|
-
},
|
|
667
|
-
{
|
|
668
|
-
name: "shun-shobon/typescript/disables/dts",
|
|
669
|
-
files: [GLOB_DTS],
|
|
670
|
-
rules: {
|
|
671
|
-
// `import`の重複を許可
|
|
672
|
-
"import/no-duplicates": "off",
|
|
673
|
-
// `///`での参照を許可
|
|
674
|
-
"typescript/triple-slash-reference": "off"
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
];
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
// src/eslint/configs/unicorn.ts
|
|
681
|
-
function unicorn() {
|
|
682
|
-
return [
|
|
683
|
-
{
|
|
684
|
-
name: "shun-shobon/unicorn/setup",
|
|
685
|
-
plugins: {
|
|
686
|
-
unicorn: default8
|
|
687
|
-
}
|
|
688
|
-
},
|
|
689
|
-
{
|
|
690
|
-
name: "shun-shobon/unicorn/rules",
|
|
691
|
-
rules: {
|
|
692
|
-
...default8.configs.recommended.rules,
|
|
693
|
-
// Prettierで整形できるルールは無効化
|
|
694
|
-
"unicorn/empty-brace-spaces": "off",
|
|
695
|
-
"unicorn/no-nested-ternary": "off",
|
|
696
|
-
"unicorn/number-literal-case": "off",
|
|
697
|
-
// unicornの推奨ルールから不要なものを無効化
|
|
698
|
-
// コンポーネント内の関数など、スコープを小さくしておきたい場合があるので無効化
|
|
699
|
-
"unicorn/consistent-function-scoping": "off",
|
|
700
|
-
// ファイルの名前はコンポーネントなどで形式が変化するため無効化
|
|
701
|
-
"unicorn/filename-case": "off",
|
|
702
|
-
// 直接関数を渡したほうが簡潔に書ける場合があるので無効化
|
|
703
|
-
"unicorn/no-array-callback-reference": "off",
|
|
704
|
-
// `.forEach()`のほうが簡潔に書ける場合があるので無効化
|
|
705
|
-
"unicorn/no-array-for-each": "off",
|
|
706
|
-
// `.reduce()`/`.reduceRight()`は使ったほうが簡潔に書ける場合があるので無効化
|
|
707
|
-
"unicorn/no-array-reduce": "off",
|
|
708
|
-
// 否定形の方が簡潔に書ける場合があるので無効化
|
|
709
|
-
"unicorn/no-negated-condition": "off",
|
|
710
|
-
// nullも使う場合があるので無効化
|
|
711
|
-
"unicorn/no-null": "off",
|
|
712
|
-
// undefinedを使いたい場合があるので無効化
|
|
713
|
-
"unicorn/no-useless-undefined": "off",
|
|
714
|
-
// CommonJSを使う場合もあるため無効化
|
|
715
|
-
"unicorn/prefer-module": "off",
|
|
716
|
-
// `[...array].map()`は~~ダサい~~ので無効化
|
|
717
|
-
"unicorn/prefer-spread": "off",
|
|
718
|
-
// 略語の方が簡潔に書ける場合があるので無効化
|
|
719
|
-
"unicorn/prevent-abbreviations": "off",
|
|
720
|
-
// switch文のcase節を常にブロックにするのは冗長なので必要なときのみブロックにする
|
|
721
|
-
"unicorn/switch-case-braces": ["warn", "avoid"]
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
];
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
// src/eslint/factory.ts
|
|
728
|
-
import { isPackageExists } from "local-pkg";
|
|
729
|
-
async function shun_shobon(options = {}, ...userConfigs) {
|
|
730
|
-
const {
|
|
731
|
-
gitignore: enableGitignore = true,
|
|
732
|
-
ignores: userIgnores = [],
|
|
733
|
-
typescript: enableTypescript = isPackageExists("typescript"),
|
|
734
|
-
react: enableReact = isPackageExists("react"),
|
|
735
|
-
next: enableNext = isPackageExists("next"),
|
|
736
|
-
qwik: enableQwik = isPackageExists("@builder.io/qwik"),
|
|
737
|
-
astro: enableAstro = isPackageExists("astro"),
|
|
738
|
-
storybook: enableStorybook = isPackageExists("storybook"),
|
|
739
|
-
componentExts = [],
|
|
740
|
-
disableTypeCheckedFiles = []
|
|
741
|
-
} = options;
|
|
742
|
-
const configQueue = [];
|
|
743
|
-
if (enableGitignore) {
|
|
744
|
-
configQueue.push(
|
|
745
|
-
interopDefault(import("eslint-config-flat-gitignore")).then(
|
|
746
|
-
(gitignore) => [
|
|
747
|
-
gitignore(
|
|
748
|
-
typeof enableGitignore !== "boolean" ? { name: "shun-shobon/gitignore/setup", ...enableGitignore } : { name: "shun-shobon/gitignore/setup" }
|
|
749
|
-
)
|
|
750
|
-
]
|
|
751
|
-
)
|
|
752
|
-
);
|
|
753
|
-
}
|
|
754
|
-
if (enableAstro) {
|
|
755
|
-
componentExts.push(GLOB_ASTRO_EXT);
|
|
756
|
-
disableTypeCheckedFiles.push(GLOB_ASTRO);
|
|
757
|
-
}
|
|
758
|
-
configQueue.push(
|
|
759
|
-
base(),
|
|
760
|
-
javascript(),
|
|
761
|
-
imports({ typescript: enableTypescript }),
|
|
762
|
-
importSort(),
|
|
763
|
-
unicorn(),
|
|
764
|
-
regexp(),
|
|
765
|
-
node(),
|
|
766
|
-
jsxA11y()
|
|
767
|
-
);
|
|
768
|
-
if (enableTypescript) {
|
|
769
|
-
configQueue.push(
|
|
770
|
-
typescript({
|
|
771
|
-
componentExts
|
|
772
|
-
})
|
|
773
|
-
);
|
|
774
|
-
disableTypeCheckedFiles.push(GLOB_JS, GLOB_JSX);
|
|
775
|
-
}
|
|
776
|
-
if (enableReact) {
|
|
777
|
-
configQueue.push(
|
|
778
|
-
react({
|
|
779
|
-
typescript: enableTypescript
|
|
780
|
-
})
|
|
781
|
-
);
|
|
782
|
-
}
|
|
783
|
-
if (enableNext) {
|
|
784
|
-
configQueue.push(next());
|
|
785
|
-
}
|
|
786
|
-
if (enableQwik) {
|
|
787
|
-
configQueue.push(qwik());
|
|
788
|
-
}
|
|
789
|
-
if (enableAstro) {
|
|
790
|
-
configQueue.push(
|
|
791
|
-
astro({
|
|
792
|
-
typescript: enableTypescript
|
|
793
|
-
})
|
|
794
|
-
);
|
|
795
|
-
}
|
|
796
|
-
if (enableStorybook) {
|
|
797
|
-
configQueue.push(storybook());
|
|
798
|
-
}
|
|
799
|
-
if (enableTypescript) {
|
|
800
|
-
configQueue.push(disableTypeChecked({ disableTypeCheckedFiles }));
|
|
801
|
-
}
|
|
802
|
-
const ignores = [...userIgnores, "**/.yarn/**"];
|
|
803
|
-
configQueue.push([
|
|
804
|
-
{
|
|
805
|
-
ignores
|
|
806
|
-
}
|
|
807
|
-
]);
|
|
808
|
-
const configs = await Promise.all(configQueue).then(
|
|
809
|
-
(configs2) => configs2.flat()
|
|
810
|
-
);
|
|
811
|
-
return [...configs, ...userConfigs];
|
|
812
|
-
}
|
|
813
|
-
export {
|
|
814
|
-
astro,
|
|
815
|
-
base,
|
|
816
|
-
disableTypeChecked,
|
|
817
|
-
importSort,
|
|
818
|
-
imports,
|
|
819
|
-
javascript,
|
|
820
|
-
jsxA11y,
|
|
821
|
-
next,
|
|
822
|
-
node,
|
|
823
|
-
qwik,
|
|
824
|
-
react,
|
|
825
|
-
regexp,
|
|
826
|
-
shun_shobon,
|
|
827
|
-
storybook,
|
|
828
|
-
typescript,
|
|
829
|
-
unicorn
|
|
830
|
-
};
|
|
831
|
-
//# sourceMappingURL=index.js.map
|