@tuomashatakka/eslint-config 0.2.2 → 2.0.0

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/README.md CHANGED
@@ -1 +1,13 @@
1
- # ES Lintin' configuratin' :v
1
+ # Rules for my linter
2
+
3
+ Heavily opionated yet heavily clean and effective linter configuration for ESLint.
4
+
5
+ For Next, React and TS
6
+
7
+
8
+ ### Todo
9
+
10
+ - Style imports aren't yet enforced to have an empty line between them and other imports.
11
+ - I really love Python's enforced linting style for having two rows between major blocks
12
+ and 1 row between minor. I should finish my block padding plugin some day for the ESLinter.
13
+ My linting rules would really appreciate that.
@@ -0,0 +1 @@
1
+ declare module 'eslint-plugin-import';
@@ -0,0 +1,45 @@
1
+ import eslint from '@eslint/js'
2
+ import stylistic from '@stylistic/eslint-plugin';
3
+ import tsplugin from '@typescript-eslint/eslint-plugin';
4
+ import eslintPluginBlockPadding from 'eslint-plugin-block-padding';
5
+ import importPlugin from 'eslint-plugin-import';
6
+ import react from 'eslint-plugin-react';
7
+ import tseslint from 'typescript-eslint'
8
+
9
+ import { rules } from './rules.js'
10
+
11
+
12
+
13
+ const ignores = [
14
+ '**/*.js',
15
+ ];
16
+
17
+ export default tseslint.config(
18
+ {
19
+ ...eslint.configs.recommended,
20
+ ignores,
21
+ },
22
+ { plugins: {
23
+ '@stylistic': stylistic,
24
+ 'react': react,
25
+ 'import': importPlugin,
26
+ '@typescript-eslint': tsplugin,
27
+ 'block-padding': eslintPluginBlockPadding,
28
+ },
29
+ },
30
+ ...tseslint.configs.recommended.map((config) => ({
31
+ ...config,
32
+
33
+ settings: {
34
+ react: {
35
+ version: 'detect',
36
+ },
37
+ },
38
+ ignores,
39
+
40
+ rules: {
41
+ ...config.rules,
42
+ ...rules
43
+ },
44
+ })),
45
+ );
package/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ import config from './eslint.config.js'
2
+
3
+
4
+ export default config
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@tuomashatakka/eslint-config",
3
- "version": "0.2.2",
3
+ "version": "2.0.0",
4
4
  "description": "Default eslint configuration",
5
- "main": "index.js",
5
+ "type": "module",
6
+ "main": "index.mjs",
6
7
  "scripts": {
7
- "test": "exit 0"
8
+ "lint": "eslint . -c eslint.config.mjs"
8
9
  },
9
10
  "repository": {
10
11
  "type": "git",
@@ -17,12 +18,26 @@
17
18
  },
18
19
  "homepage": "https://github.com/tuomashatakka/eslint-config#readme",
19
20
  "peerDependencies": {
20
- "eslint": ">=4.0.0 || >= 5.0.0",
21
- "babel-eslint": ">=8.0.0 || >= 9.0.0",
22
- "eslint-plugin-flow": "latest",
23
- "eslint-plugin-react": "latest",
24
- "eslint-plugin-import": "latest",
25
- "eslint-import-resolver-webpack": "latest",
26
- "eslint-plugin-block-padding": "latest"
21
+ "react": "*"
22
+ },
23
+ "devDependencies": {
24
+ "@eslint/compat": "^1.2.1",
25
+ "@eslint/eslintrc": "^3.1.0",
26
+ "@eslint/js": "^9.13.0",
27
+ "@next/eslint-plugin-next": "^15.0.1",
28
+ "@stylistic/eslint-plugin": "^2.9.0",
29
+ "@stylistic/eslint-plugin-ts": "^2.9.0",
30
+ "@types/eslint__eslintrc": "^2.1.2",
31
+ "@types/eslint__js": "^8.42.3",
32
+ "@typescript-eslint/eslint-plugin": "^8.11.0",
33
+ "@typescript-eslint/parser": "^8.11.0",
34
+ "eslint": "^9.13.0",
35
+ "eslint-config-next": "^15.0.1",
36
+ "eslint-plugin-block-padding": "^0.0.3",
37
+ "eslint-plugin-import": "^2.31.0",
38
+ "eslint-plugin-react": "^7.37.2",
39
+ "globals": "^15.11.0",
40
+ "typescript": "^5.6.3",
41
+ "typescript-eslint": "^8.11.0"
27
42
  }
28
43
  }
package/rules.js ADDED
@@ -0,0 +1,81 @@
1
+ export const rules = {
2
+
3
+ 'block-padding/after-block': [ 'warn', 2 ],
4
+
5
+ // @stylistic
6
+ '@stylistic/jsx-quotes': [ 'warn', 'prefer-single' ],
7
+ '@stylistic/jsx-newline': [ 'warn', { prevent: true, allowMultilines: true }],
8
+ '@stylistic/jsx-props-no-multi-spaces': [ 'warn' ],
9
+ 'react/no-unescaped-entities': [ 'error', { forbid: [ '>', '}' ]}],
10
+ 'react/jsx-uses-vars': [ 'error' ],
11
+ 'react/jsx-uses-react': [ 'error' ],
12
+ 'react/style-prop-object': [ 'error', { allow: []}],
13
+ 'react/prefer-stateless-function': [ 'error', { ignorePureComponents: false }],
14
+ 'react/no-invalid-html-attribute': [ 'error', []],
15
+ 'react/hook-use-state': [ 'warn', { allowDestructuredState: false }],
16
+ 'react/jsx-one-expression-per-line': [ 'warn', { allow: 'single-child' }],
17
+ 'react/jsx-no-useless-fragment': [ 'warn', { allowExpressions: true }],
18
+ 'react/jsx-no-target-blank': [ 'warn', { enforceDynamicLinks: 'always' }],
19
+ 'react/jsx-closing-bracket-location': [ 'warn', 'line-aligned' ],
20
+ 'react/jsx-closing-tag-location': [ 'warn', 'line-aligned' ],
21
+ 'react/jsx-equals-spacing': [ 'warn', 'never' ],
22
+ 'react/jsx-first-prop-new-line': [ 'warn', 'multiline' ],
23
+ 'react/jsx-indent': [ 'warn', 2, { checkAttributes: true, indentLogicalExpressions: true }],
24
+ 'react/jsx-indent-props': [ 'warn', 2 ],
25
+ 'react/jsx-max-props-per-line': [ 'warn', { maximum: 1, when: 'multiline' }],
26
+ '@stylistic/arrow-parens': [ 'warn', 'always' ],
27
+ '@stylistic/dot-location': [ 'warn', 'property' ],
28
+ '@stylistic/eol-last': [ 'warn', 'always' ],
29
+ '@stylistic/multiline-ternary': [ 'warn', 'always-multiline' ],
30
+ '@stylistic/no-extra-semi': [ 'warn' ],
31
+ '@stylistic/no-floating-decimal': [ 'warn' ],
32
+ '@stylistic/no-mixed-operators': [ 'warn' ],
33
+ '@stylistic/semi-spacing': [ 'warn', { before: false, after: true }],
34
+ '@stylistic/semi-style': [ 'warn', 'last' ],
35
+ '@stylistic/space-before-blocks': [ 'warn', 'always' ],
36
+ '@stylistic/space-before-function-paren': [ 'warn', { anonymous: 'always', named: 'never', asyncArrow: 'always' }],
37
+ '@stylistic/template-tag-spacing': [ 'warn', 'never' ],
38
+ '@stylistic/yield-star-spacing': [ 'warn', 'after' ],
39
+ 'react/jsx-no-constructed-context-values': [ 'warn' ],
40
+ 'react/jsx-no-script-url': [ 'warn' ],
41
+ 'react/jsx-no-comment-textnodes': [ 'warn' ],
42
+ 'react/jsx-no-duplicate-props': [ 'warn' ],
43
+ 'react/jsx-no-undef': [ 'warn' ],
44
+ 'react/jsx-pascal-case': [ 'warn' ],
45
+ 'react/jsx-curly-brace-presence': [ 'warn', { props: 'never', children: 'never' }],
46
+ 'react/jsx-curly-spacing': [ 'warn', { when: 'never', children: true }],
47
+ '@stylistic/jsx-equals-spacing': [ 'warn', 'never' ],
48
+ '@stylistic/quotes': [ 'warn', 'single', { avoidEscape: true, allowTemplateLiterals: true }],
49
+ '@stylistic/jsx-indent-props': [ 'warn', 2 ],
50
+ '@stylistic/jsx-max-props-per-line': [ 'warn', { maximum: 1, when: 'multiline' }],
51
+ '@stylistic/jsx-self-closing-comp': [ 'warn', { component: true, html: true }],
52
+ '@stylistic/jsx-one-expression-per-line': [ 'warn', { allow: 'single-child' }],
53
+ '@stylistic/jsx-tag-spacing': [ 'warn', { closingSlash: 'never', beforeSelfClosing: 'never', beforeClosing: 'never', afterOpening: 'never' }],
54
+ 'react/display-name': [ 'warn', { checkContextObjects: true }],
55
+
56
+ // Comments
57
+ 'multiline-comment-style': [ 'warn', 'separate-lines', { checkJSDoc: false }],
58
+ '@stylistic/lines-around-comment': [ 'warn', { beforeBlockComment: true, beforeLineComment: true, afterLineComment: false, allowClassEnd: false, allowBlockEnd: false
59
+ }],
60
+
61
+ // TODO
62
+ 'import/no-extraneous-dependencies': [ 'warn' ],
63
+ 'import/consistent-type-specifier-style': [ 'warn', 'prefer-top-level' ],
64
+ 'import/newline-after-import': [ 'warn', { count: 2 }],
65
+ 'import/no-unassigned-import': [ 'error', { allow: [ '**/*.{le,c,sc,sa}ss' ]}],
66
+ 'import/prefer-default-export': [ 'error' ],
67
+ 'import/no-mutable-exports': [ 'error' ],
68
+
69
+ 'import/order': [ 'warn', {
70
+ 'groups': [ 'builtin', 'type', 'external', [ 'parent', 'sibling', 'index' ], 'internal', 'object' ],
71
+ 'alphabetize': { order: 'asc', caseInsensitive: true },
72
+ 'distinctGroup': true,
73
+ 'warnOnUnassignedImports': true,
74
+ 'newlines-between': 'always',
75
+ 'pathGroups': [
76
+ { group: 'internal', pattern: '**/*.css', position: 'after' },
77
+ { group: 'object', pattern: '**/*.scss' },
78
+ { group: 'parent', pattern: '@/**' },
79
+ { group: 'parent', pattern: '../**' },
80
+ { group: 'sibling', pattern: './**' }]}],
81
+ }
package/constants.js DELETED
@@ -1,74 +0,0 @@
1
- module.exports.exceptMethods = [
2
- 'shouldComponentUpdate',
3
- 'render',
4
- 'componentDidMount',
5
- 'componentDidCatch',
6
- 'componentDidUpdate',
7
- 'componentWillMount',
8
- 'componentWillUpdate',
9
- 'componentWillUnmount',
10
- 'componentWillReceiveProps',
11
- ]
12
-
13
- module.exports.plugins = [
14
- 'react',
15
- 'import',
16
- 'block-padding',
17
- ]
18
-
19
- module.exports.env = [
20
- 'node',
21
- 'jasmine',
22
- 'browser',
23
- 'commonjs',
24
- ]
25
-
26
- module.exports.globals = [
27
- 'Set',
28
- 'Map',
29
- 'Proxy',
30
- 'Symbol',
31
- 'Promise',
32
- 'WeakSet',
33
- 'WeakMap',
34
- 'Uint8Array',
35
- '__DEV__',
36
- ]
37
-
38
- module.exports.allowedImports = [
39
- '**/*.{le,c,sc}ss',
40
- 'babel-*',
41
- '@babel/*',
42
- 'reactotron',
43
- ]
44
-
45
- const fn = {
46
- parameters: 'first'
47
- }
48
-
49
- const cl = {
50
- arguments: 'first'
51
- }
52
-
53
- const vr = {
54
- 'var': 2,
55
- 'let': 2,
56
- 'const': 3,
57
- }
58
-
59
- module.exports.indentation = {
60
- depth: 2,
61
- options: {
62
- SwitchCase: 1,
63
- CallExpression: cl,
64
- }
65
- }
66
-
67
- module.exports.comments = {
68
- beforeBlockComment: true,
69
- // afterBlockComment: true,
70
- beforeLineComment: true,
71
- afterLineComment: false,
72
- allowClassEnd: false,
73
- allowBlockEnd: false,
74
- }
package/dependencies.sh DELETED
@@ -1,21 +0,0 @@
1
- #!/bin/bash
2
-
3
- npm install \
4
- \
5
- --save-dev \
6
- eslint@latest \
7
- babel-eslint@latest \
8
- babel-plugin-module-resolver@latest \
9
- eslint-plugin-react@latest \
10
- eslint-plugin-block-padding@latest \
11
- eslint-plugin-import@latest \
12
- eslint-import-resolver-webpack@latest \
13
- eslint-import-resolver-babel-module@latest \
14
- eslint-plugin-flowtype@latest \
15
- eslint-plugin-flowtype-errors@latest \
16
- eslint-plugin-block-padding@latest \
17
- flow-bin@latest
18
-
19
-
20
- # 2> /dev/null
21
- exit 0
package/index.js DELETED
@@ -1,138 +0,0 @@
1
- const { parserOptions,
2
- settings,
3
- parser } = require('./settings')
4
- const { reduce } = require('./utils')
5
- const constants = require('./constants')
6
-
7
- // Shortcuts
8
- const N = 0,
9
- W = 'warn',
10
- E = 'error',
11
- vars = [ 'const', 'let', 'var' ],
12
- any = 'any',
13
- never = 'never',
14
- always = 'always',
15
- dir = 'directive',
16
- after = true,
17
- before = true
18
-
19
- // Constants
20
- const env = reduce(constants.env)
21
- const globals = reduce(constants.globals)
22
- const plugins = constants.plugins
23
- const comments = constants.comments
24
- const indentation = constants.indentation
25
- const exceptMethods = constants.exceptMethods
26
- const allowedImports = constants.allowedImports
27
-
28
-
29
- const statements = [
30
- // [ always, '*', vars ],
31
- [ any, vars, '*' ],
32
- [ any, vars, vars ],
33
- [ always, 'import', '*' ],
34
- [ any, 'import', 'import' ],
35
- // [ always, 'empty', 'block-like' ],
36
- // [ always, 'block-like', vars ],
37
- // [ always, '*', 'block-like' ],
38
- ]
39
-
40
- module.exports = {
41
- env,
42
- parser,
43
- globals,
44
- plugins,
45
- settings,
46
- parserOptions,
47
-
48
- rules: {
49
-
50
- // Ignored
51
- strict: N,
52
-
53
- // Warnings
54
- semi: [ W, never ],
55
- complexity: [ W, 6 ],
56
- 'max-depth': [ W, 3 ],
57
- 'max-lines': [ W, 480 ],
58
- 'max-len': [ W, 140 ],
59
- 'max-statements': [ W, 12 ],
60
-
61
- 'no-tabs': W,
62
- 'no-console': W,
63
- 'no-debugger': W,
64
- 'dot-notation': W,
65
- 'no-extra-parens': W,
66
- 'comma-spacing': [ W, { before: false, after }],
67
- 'class-methods-use-this': [ W, { exceptMethods }],
68
- 'array-bracket-spacing': [ W, always, { arraysInArrays: false, objectsInArrays: false }],
69
- 'object-curly-spacing': [ W, always, { objectsInObjects: false, arraysInObjects: false }],
70
-
71
- // Errors
72
- 'eqeqeq': [ E, 'smart' ],
73
- 'use-isnan': E,
74
-
75
- 'no-undef': E,
76
- 'no-obj-calls': E,
77
- 'no-new-symbol': E,
78
- 'no-unused-vars': E,
79
- 'no-func-assign': E,
80
- 'no-class-assign': E,
81
- 'no-array-constructor': E,
82
-
83
- // Import
84
- 'import/no-mutable-exports': E,
85
- 'import/prefer-default-export': E,
86
- 'import/no-unassigned-import': [ E, { allow: allowedImports }],
87
- 'import/no-extraneous-dependencies': 0,
88
-
89
- // React
90
- 'jsx-quotes': [ W, 'prefer-single' ],
91
- 'react/jsx-uses-vars': E,
92
- 'react/jsx-uses-react': E,
93
- 'react/react-in-jsx-scope': E,
94
-
95
- 'indent': [ 'warn', indentation.depth, indentation.options ],
96
-
97
- 'space-before-function-paren': [ 1, {
98
- asyncArrow: always,
99
- anonymous: always,
100
- named: always,
101
- }],
102
-
103
- // Whitespace
104
- 'arrow-spacing': W,
105
- 'keyword-spacing': [ W, { before, after }],
106
- 'func-call-spacing': [ W, 'never' ],
107
-
108
- // Padding
109
- 'implicit-arrow-linebreak': N,
110
- 'function-paren-newline': N,
111
- 'brace-style': N,
112
- 'arrow-body-style': [ W, 'as-needed' ],
113
- 'newline-per-chained-call': [ W, { ignoreChainWithDepth: 2 }],
114
- 'lines-between-class-members': [ W, 'always', { exceptAfterSingleLine: true }],
115
- 'one-var-declaration-per-line': [ W, 'always' ],
116
- 'padding-line-between-statements': [ W, ...statements.map(([ blankLine, prev, next ]) => ({ blankLine, prev, next })) ],
117
-
118
- // Comments
119
- 'multiline-comment-style': [ W, 'separate-lines' ],
120
- 'line-comment-position': [ W, { position: 'above', applyDefaultIgnorePatterns: true }],
121
- 'lines-around-comment': [ W, comments ],
122
-
123
- // Padding between entities
124
- "block-padding/functions": [ 1, 1, { strategy: 'at-least' }],
125
- "block-padding/classes": [ 1, 2 ],
126
-
127
- },
128
-
129
- }
130
-
131
- // 'import/no-extraneous-dependencies': [ E, {
132
- // 'devDependencies': [
133
- // '**/*.{test,spec}.js',
134
- // '**/{test,spec}/*.js',
135
- // '**/*.{dev,develop,development}.js{x,}',
136
- // '**/{dev,develop,development}/*.js{x,}',
137
- // ]
138
- // }],
package/settings.js DELETED
@@ -1,27 +0,0 @@
1
-
2
- module.exports = {
3
-
4
- parser: 'babel-eslint',
5
-
6
- parserOptions: {
7
- ecmaVersion: 7,
8
- sourceType: 'module',
9
- ecmaFeatures: {
10
- jsx: true,
11
- }
12
- },
13
-
14
- settings: {
15
-
16
- react: {
17
- pragma: 'React',
18
- version: '16.3.0'
19
- },
20
-
21
- 'import/ignore': [
22
- /\.(sc|le|c)ss$/
23
- ],
24
-
25
- }
26
-
27
- }
package/utils.js DELETED
@@ -1,7 +0,0 @@
1
-
2
- const reduce = (arr) =>
3
- arr.reduce((obj, key) => Object.assign(obj, { [key]: true }), {})
4
-
5
- module.exports = {
6
- reduce
7
- }