@agilebot/eslint-config 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Agilebot, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @agilebot/eslint-config
2
+
3
+ ### Usage
4
+
5
+ ```bash
6
+ npm install --save-dev eslint \
7
+ @agilebot/eslint-config \
8
+ @agilebot/eslint-plugin \
9
+ @agilebot/eslint-utils
10
+ ```
11
+
12
+ ```js
13
+ // .eslintrc.js
14
+ const { agilebot } = require('@agilebot/eslint-utils');
15
+
16
+ module.exports = agilebot(__dirname);
17
+ ```
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ extends: ['plugin:@agilebot/recommended'],
3
+ rules: {
4
+ // 禁止使用inline style,应该使用mui的sx属性或tss或styled-component
5
+ '@agilebot/react/no-inline-styles': [
6
+ 'error',
7
+ {
8
+ allowedFor: ['Grow']
9
+ }
10
+ ]
11
+ }
12
+ };
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ plugins: ['@cspell'],
3
+ rules: {
4
+ '@cspell/spellchecker': [
5
+ 'warn',
6
+ {
7
+ checkComments: false,
8
+ autoFix: false
9
+ }
10
+ ]
11
+ }
12
+ };
@@ -0,0 +1,7 @@
1
+ module.exports = {
2
+ plugins: ['deprecation'],
3
+ rules: {
4
+ // 禁止使用带有deprecation标记的方法或属性
5
+ 'deprecation/deprecation': 'error'
6
+ }
7
+ };
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ env: {
3
+ browser: true,
4
+ node: true,
5
+ es6: true,
6
+ mocha: true,
7
+ jest: true,
8
+ jasmine: true
9
+ }
10
+ };
@@ -0,0 +1,23 @@
1
+ const { isCI } = require('@agilebot/eslint-utils');
2
+
3
+ module.exports = {
4
+ plugins: ['eslint-comments', 'file-progress'],
5
+ rules: {
6
+ // 禁止未使用的eslint-disable注释
7
+ 'eslint-comments/no-unused-disable': 'error',
8
+ // 禁止无限制的eslint-disable注释
9
+ 'eslint-comments/no-unlimited-disable': 'error',
10
+ // 禁止重复的eslint-disable注释
11
+ 'eslint-comments/no-duplicate-disable': 'error',
12
+ // 禁止聚合的eslint-enable注释
13
+ 'eslint-comments/no-aggregating-enable': 'error',
14
+ // eslint-disable须说明原因
15
+ 'eslint-comments/require-description': [
16
+ 'error',
17
+ {
18
+ ignore: ['eslint-env', 'exported', 'global', 'globals']
19
+ }
20
+ ],
21
+ 'file-progress/activate': isCI() ? 'off' : 'warn'
22
+ }
23
+ };
@@ -0,0 +1,19 @@
1
+ // config for eslint plugins, DO NOT use for ts
2
+ module.exports = {
3
+ extends: ['godaddy'],
4
+ rules: {
5
+ 'quote-props': 'off',
6
+ 'linebreak-style': 'off',
7
+ complexity: 'off',
8
+ 'max-statements': 'off',
9
+ 'id-length': 'off',
10
+ 'default-case': 'off',
11
+ 'valid-jsdoc': 'off',
12
+ 'generator-star-spacing': 'off',
13
+ 'max-params': 'off',
14
+ 'max-depth': 'off',
15
+ 'no-undefined': 'off',
16
+ 'no-process-env': 'off',
17
+ 'no-sync': 'off'
18
+ }
19
+ };
@@ -0,0 +1,40 @@
1
+ module.exports = {
2
+ plugins: ['import', 'no-relative-import-paths'],
3
+ extends: ['plugin:import/recommended', 'plugin:import/typescript'],
4
+ rules: {
5
+ 'import/no-unresolved': 'error',
6
+ 'import/no-named-as-default-member': 'off',
7
+ 'import/no-named-as-default': 'off',
8
+ 'import/no-useless-path-segments': [
9
+ 'error',
10
+ {
11
+ noUselessIndex: true
12
+ }
13
+ ],
14
+ 'import/no-cycle': 'error',
15
+ 'import/newline-after-import': 'error',
16
+ 'import/first': 'error',
17
+ 'import/no-import-module-exports': 'error',
18
+ 'import/no-anonymous-default-export': [
19
+ 'error',
20
+ {
21
+ allowArray: true,
22
+ allowObject: true
23
+ }
24
+ ],
25
+ 'no-relative-import-paths/no-relative-import-paths': [
26
+ 'warn',
27
+ { allowSameFolder: true }
28
+ ]
29
+ },
30
+ settings: {
31
+ 'import/parsers': {
32
+ '@typescript-eslint/parser': ['.ts', '.tsx']
33
+ },
34
+ 'import/resolver': {
35
+ typescript: {
36
+ alwaysTryTypes: true
37
+ }
38
+ }
39
+ }
40
+ };
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ plugins: ['jsdoc'],
3
+ extends: ['plugin:jsdoc/recommended-typescript-error'],
4
+ rules: {
5
+ // 禁止有空行
6
+ 'jsdoc/no-blank-block-descriptions': 'error',
7
+ 'jsdoc/no-blank-blocks': 'error',
8
+ 'jsdoc/require-returns': 'off',
9
+ // @return注释不是很有必要
10
+ 'jsdoc/require-returns-type': 'off',
11
+ // 每行注释都有星号
12
+ 'jsdoc/require-asterisk-prefix': 'error'
13
+ }
14
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ // lodash一些方法可能影响性能,如forEach等,优先使用js的原生方法
3
+ extends: ['plugin:you-dont-need-lodash-underscore/compatible']
4
+ };
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ plugins: ['prettier'],
3
+ extends: ['plugin:prettier/recommended'],
4
+ rules: {
5
+ 'prettier/prettier': [
6
+ 'error',
7
+ {
8
+ endOfLine: 'auto'
9
+ }
10
+ ]
11
+ }
12
+ };
@@ -0,0 +1,10 @@
1
+ module.exports = {
2
+ plugins: ['promise'],
3
+ rules: {
4
+ 'promise/no-nesting': 'error',
5
+ 'promise/no-promise-in-callback': 'error',
6
+ 'promise/param-names': 'error',
7
+ 'promise/no-multiple-resolved': 'error',
8
+ 'promise/no-return-in-finally': 'error'
9
+ }
10
+ };
@@ -0,0 +1,60 @@
1
+ module.exports = {
2
+ plugins: ['react', 'react-hooks', 'jsx-a11y'],
3
+ extends: [
4
+ 'plugin:react/recommended',
5
+ 'plugin:react-hooks/recommended',
6
+ 'plugin:react-prefer-function-component/recommended',
7
+ 'plugin:jsx-a11y/recommended'
8
+ ],
9
+ rules: {
10
+ // 禁止没必要的Fragment,除了<>{foo}</>
11
+ 'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
12
+ // 优先使用<>而不是<Fragment>
13
+ 'react/jsx-fragments': 'error',
14
+ 'react/jsx-handler-names': [
15
+ 'error',
16
+ {
17
+ eventHandlerPrefix: 'handle',
18
+ eventHandlerPropPrefix: 'on',
19
+ checkLocalVariables: true
20
+ }
21
+ ],
22
+ // useState必须以[example, setExample]命名
23
+ 'react/hook-use-state': 'error',
24
+ // 避免使用数组的 index 来作为 key 属性的值
25
+ 'react/no-array-index-key': 'error',
26
+ 'react/self-closing-comp': 'error',
27
+ // 组件命名符合帕斯卡
28
+ 'react/jsx-pascal-case': [
29
+ 'error',
30
+ {
31
+ allowNamespace: true
32
+ }
33
+ ],
34
+ // 布尔属性如果为true,省略值
35
+ 'react/jsx-boolean-value': 'error',
36
+ // 已经有ts校验,此规则没有必要,会与带静态属性的Functional Component冲突
37
+ 'react/prop-types': 'off',
38
+ // <App prop={'Hello'} />没必要,使用<App prop="Hello" />
39
+ 'react/jsx-curly-brace-presence': [
40
+ 'error',
41
+ {
42
+ props: 'never',
43
+ children: 'never',
44
+ propElementValues: 'always'
45
+ }
46
+ ],
47
+ // 禁止声明未使用的props
48
+ 'react/no-unused-prop-types': 'error',
49
+ // img之类的void元素不应该有children
50
+ 'react/void-dom-elements-no-children': 'error',
51
+ 'jsx-a11y/click-events-have-key-events': 'off',
52
+ 'jsx-a11y/no-static-element-interactions': 'off',
53
+ 'jsx-a11y/alt-text': 'off'
54
+ },
55
+ settings: {
56
+ react: {
57
+ version: 'detect'
58
+ }
59
+ }
60
+ };
@@ -0,0 +1,21 @@
1
+ module.exports = {
2
+ extends: ['love'],
3
+ rules: {
4
+ 'no-alert': 'error',
5
+ // 避免使用同步方法
6
+ 'n/no-sync': 'error',
7
+ // 尽量使用fs.promises而不是fs
8
+ 'n/prefer-promises/fs': 'error',
9
+ 'arrow-body-style': 'error',
10
+ curly: 'error',
11
+ // 找出TODO注释,以便后期修复
12
+ 'no-warning-comments': [
13
+ 'warn',
14
+ {
15
+ terms: ['todo', 'fixme']
16
+ }
17
+ ],
18
+ // 路径拼接使用path.join,而不是直接使用加号
19
+ 'n/no-path-concat': 'error'
20
+ }
21
+ };
@@ -0,0 +1,76 @@
1
+ module.exports = {
2
+ plugins: ['@typescript-eslint', '@stylistic'],
3
+ rules: {
4
+ // 如果没用模板字符串,避免使用反引号
5
+ '@stylistic/quotes': ['error', 'single', { avoidEscape: true }],
6
+ // 优先使用interface而不是type
7
+ '@typescript-eslint/consistent-type-definitions': 'error',
8
+ // The `@typescript-eslint/naming-convention` rule allows `leadingUnderscore` and `trailingUnderscore` settings.
9
+ // However, the existing `no-underscore-dangle` rule already takes care of this.
10
+ '@typescript-eslint/naming-convention': [
11
+ 'error',
12
+ // Allow camelCase variables (23.2), PascalCase variables (23.8), and UPPER_CASE variables (23.10)
13
+ {
14
+ selector: 'variable',
15
+ format: ['camelCase', 'PascalCase', 'UPPER_CASE']
16
+ },
17
+ // Allow camelCase functions (23.2), and PascalCase functions (23.8)
18
+ {
19
+ selector: 'function',
20
+ format: ['camelCase', 'PascalCase']
21
+ },
22
+ // Airbnb recommends PascalCase for classes (23.3),
23
+ // and although Airbnb does not make TypeScript recommendations,
24
+ // we are assuming this rule would similarly apply to anything "type like",
25
+ // including interfaces, type aliases, and enums
26
+ {
27
+ selector: 'typeLike',
28
+ format: ['PascalCase']
29
+ },
30
+ {
31
+ selector: 'parameter',
32
+ format: ['camelCase'],
33
+ leadingUnderscore: 'allow'
34
+ },
35
+ {
36
+ selector: 'method',
37
+ format: ['camelCase', 'PascalCase']
38
+ },
39
+ {
40
+ selector: 'typeProperty',
41
+ format: ['camelCase']
42
+ },
43
+ {
44
+ selector: 'enumMember',
45
+ format: ['PascalCase', 'UPPER_CASE']
46
+ }
47
+ ],
48
+ // 禁止没有必要的初始化
49
+ '@typescript-eslint/no-inferrable-types': 'error',
50
+ // 函数中未使用await,函数签名不要加async
51
+ '@typescript-eslint/require-await': 'error',
52
+ // 没有必要的类型as
53
+ '@typescript-eslint/no-unnecessary-type-assertion': 'error',
54
+ // 数组用T[]而不是Array<T>
55
+ '@typescript-eslint/array-type': ['error', { default: 'array' }],
56
+ // Promise必须加await或void
57
+ '@typescript-eslint/no-misused-promises': [
58
+ 'error',
59
+ {
60
+ checksVoidReturn: false
61
+ }
62
+ ],
63
+ // 以下是关闭的规则
64
+ '@typescript-eslint/strict-boolean-expressions': 'off',
65
+ '@typescript-eslint/explicit-function-return-type': 'off',
66
+ '@typescript-eslint/restrict-template-expressions': 'off',
67
+ '@typescript-eslint/no-non-null-assertion': 'off',
68
+ '@typescript-eslint/method-signature-style': 'off',
69
+ '@typescript-eslint/consistent-type-assertions': 'off',
70
+ '@typescript-eslint/no-extraneous-class': 'off',
71
+ '@typescript-eslint/no-confusing-void-expression': 'off',
72
+ '@typescript-eslint/explicit-member-accessibility': 'off',
73
+ '@typescript-eslint/unbound-method': 'off',
74
+ '@typescript-eslint/no-unsafe-argument': 'off'
75
+ }
76
+ };
@@ -0,0 +1,35 @@
1
+ module.exports = {
2
+ plugins: ['unicorn'],
3
+ extends: ['plugin:unicorn/recommended'],
4
+ rules: {
5
+ // unicorn默认规则太严格,屏蔽以下
6
+ 'unicorn/filename-case': 'off',
7
+ 'unicorn/import-style': 'off',
8
+ 'unicorn/prefer-at': 'off',
9
+ 'unicorn/prevent-abbreviations': 'off',
10
+ 'unicorn/prefer-date-now': 'off',
11
+ 'unicorn/no-process-exit': 'off',
12
+ 'unicorn/prefer-module': 'off',
13
+ 'unicorn/no-null': 'off',
14
+ 'unicorn/prefer-top-level-await': 'off',
15
+ 'unicorn/consistent-function-scoping': 'off',
16
+ 'unicorn/numeric-separators-style': 'off',
17
+ 'unicorn/prefer-optional-catch-binding': 'off',
18
+ 'unicorn/no-negated-condition': 'off',
19
+ 'unicorn/switch-case-braces': 'off',
20
+ 'unicorn/no-array-for-each': 'off',
21
+ 'unicorn/prefer-ternary': 'off',
22
+ 'unicorn/better-regex': 'off',
23
+ 'unicorn/error-message': 'off',
24
+ 'unicorn/no-object-as-default-parameter': 'off',
25
+ 'unicorn/no-array-push-push': 'off',
26
+ 'unicorn/no-useless-undefined': 'off',
27
+ 'unicorn/prefer-blob-reading-methods': 'off',
28
+ 'unicorn/catch-error-name': [
29
+ 'error',
30
+ {
31
+ name: 'err'
32
+ }
33
+ ]
34
+ }
35
+ };
package/lib/index.js ADDED
@@ -0,0 +1,51 @@
1
+ module.exports = {
2
+ overrides: [
3
+ {
4
+ files: [
5
+ '*.ts',
6
+ '*.tsx',
7
+ '*.cts',
8
+ '*.mts',
9
+ '*.js',
10
+ '*.jsx',
11
+ '*.cjs',
12
+ '*.mjs'
13
+ ],
14
+ parser: '@typescript-eslint/parser',
15
+ extends: [
16
+ './configs/env',
17
+ './configs/standard',
18
+ './configs/ts',
19
+ './configs/promise',
20
+ './configs/import',
21
+ './configs/unicorn',
22
+ './configs/react',
23
+ './configs/jsdoc',
24
+ './configs/lodash',
25
+ './configs/eslint',
26
+ './configs/deprecation',
27
+ './configs/cspell',
28
+ './configs/agilebot',
29
+ // prettier始终放在最后
30
+ './configs/prettier'
31
+ ]
32
+ },
33
+ {
34
+ files: ['*.ts', '*.tsx'],
35
+ rules: {
36
+ '@typescript-eslint/explicit-member-accessibility': 'error'
37
+ }
38
+ },
39
+ {
40
+ files: ['*.d.ts'],
41
+ rules: {
42
+ // .d.ts中支持导入ts文件中的类型
43
+ '@typescript-eslint/consistent-type-imports': 'off',
44
+ // .d.ts中忽略属性命名规则
45
+ '@typescript-eslint/naming-convention': 'off',
46
+ // .d.ts中忽略三斜线引用
47
+ '@typescript-eslint/triple-slash-reference': 'off'
48
+ }
49
+ }
50
+ ]
51
+ };
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@agilebot/eslint-config",
3
+ "version": "0.1.1",
4
+ "description": "Agilebot's ESLint config",
5
+ "main": "lib",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "url": "sh-agilebot/frontend-toolkit",
9
+ "directory": "packages/eslint-config"
10
+ },
11
+ "homepage": "https://github.com/sh-agilebot/frontend-toolkit/tree/master/packages/eslint-config#readme",
12
+ "dependencies": {
13
+ "@cspell/eslint-plugin": "^8.6.0",
14
+ "@stylistic/eslint-plugin": "^1.7.0",
15
+ "@typescript-eslint/eslint-plugin": "^7.1.1",
16
+ "@typescript-eslint/parser": "^7.1.1",
17
+ "eslint-config-godaddy": "^6.0.0",
18
+ "eslint-config-love": "^43.1.0",
19
+ "eslint-config-prettier": "^9.1.0",
20
+ "eslint-import-resolver-typescript": "^3.6.1",
21
+ "eslint-plugin-deprecation": "^2.0.0",
22
+ "eslint-plugin-eslint-comments": "^3.2.0",
23
+ "eslint-plugin-file-progress": "^1.3.0",
24
+ "eslint-plugin-import": "npm:eslint-plugin-i@^2.29.1",
25
+ "eslint-plugin-jsdoc": "^48.2.1",
26
+ "eslint-plugin-jsx-a11y": "^6.8.0",
27
+ "eslint-plugin-n": "^16.6.2",
28
+ "eslint-plugin-no-relative-import-paths": "^1.5.2",
29
+ "eslint-plugin-prettier": "^5.1.3",
30
+ "eslint-plugin-promise": "^6.0.0",
31
+ "eslint-plugin-react": "^7.34.1",
32
+ "eslint-plugin-react-hooks": "^4.6.0",
33
+ "eslint-plugin-react-prefer-function-component": "^3.3.0",
34
+ "eslint-plugin-unicorn": "^51.0.1",
35
+ "eslint-plugin-you-dont-need-lodash-underscore": "^6.13.0"
36
+ },
37
+ "devDependencies": {
38
+ "@agilebot/eslint-utils": "0.1.1"
39
+ },
40
+ "peerDependencies": {
41
+ "@agilebot/eslint-plugin": "*",
42
+ "@agilebot/eslint-utils": "*",
43
+ "eslint": "^8.0.0"
44
+ },
45
+ "files": [
46
+ "lib"
47
+ ],
48
+ "scripts": {
49
+ "lint": "eslint lib --fix"
50
+ }
51
+ }