@cedarjs/eslint-config 2.0.4-next.0 → 2.0.4-next.16
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 +120 -22
- package/index.mjs +180 -0
- package/package.json +20 -6
- package/shared.mjs +265 -0
package/README.md
CHANGED
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
- [Package Leads](#package-leads)
|
|
8
8
|
- [Roadmap](#roadmap)
|
|
9
9
|
- [Contributing](#contributing)
|
|
10
|
-
- [
|
|
10
|
+
- [Usage (Flat Config - Recommended)](#usage-flat-config---recommended)
|
|
11
|
+
- [Overriding Default Configuration (Flat Config)](#overriding-default-configuration-flat-config)
|
|
12
|
+
- [Migration Guide (Optional)](#migration-guide-optional)
|
|
13
|
+
- [Legacy Configuration (Still Supported)](#legacy-configuration-still-supported)
|
|
11
14
|
|
|
12
15
|
## Purpose and Vision
|
|
13
16
|
|
|
14
|
-
This package contains a shareable set of ESLint rules and configuration that can be re-used on all
|
|
17
|
+
This package contains a shareable set of ESLint rules and configuration that can be re-used on all CedarJS projects. The framework [`eslint-config`](https://github.com/cedarjs/cedar/tree/main/packages/eslint-config) package is used both for framework configuration and CedarJS app (created with the [create-cedar-app](https://github.com/cedarjs/cedar/tree/main/packages/create-cedar-app) package) configuration.
|
|
15
18
|
|
|
16
19
|
Our configuration uses recommended rule presets, including those from [ESLint](https://eslint.org/docs/rules/), [React](https://www.npmjs.com/package/eslint-plugin-react#list-of-supported-rules), the [Rules of Hooks](https://reactjs.org/docs/hooks-rules.html), and [Jest](https://github.com/testing-library/eslint-plugin-jest-dom#supported-rules). We also override the presets with some stylistic preferences. Some of them are:
|
|
17
20
|
|
|
@@ -34,25 +37,120 @@ Peter Pistorius (@peterp), David Price (@thedavidprice), Dominic Saadi (@jtoar),
|
|
|
34
37
|
|
|
35
38
|
This package doesn't depend on other Redwood Framework packages. To contribute, you should be familiar with the ESLint package. Keep in mind that any rules added should not conflict with code formatting tools (e.g. [Prettier](https://prettier.io/docs/en/integrating-with-linters.html)).
|
|
36
39
|
|
|
37
|
-
##
|
|
40
|
+
## Usage (Flat Config - Recommended)
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
CedarJS uses ESLint's flat config format by default. Create an `eslint.config.js` file in your project root:
|
|
40
43
|
|
|
41
44
|
```javascript
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"jsx-a11y/no-onchange": "off",
|
|
47
|
-
},
|
|
45
|
+
// cedar-app/eslint.config.js
|
|
46
|
+
import cedarConfig from '@cedarjs/eslint-config'
|
|
47
|
+
|
|
48
|
+
export default await cedarConfig()
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
Note: The config is async because it needs to load your Cedar project configuration.
|
|
52
|
+
|
|
53
|
+
## Overriding Default Configuration (Flat Config)
|
|
54
|
+
|
|
55
|
+
To override rules in your CedarJS app, add additional config objects after the Cedar config:
|
|
51
56
|
|
|
52
57
|
```javascript
|
|
53
|
-
//
|
|
58
|
+
// cedar-app/eslint.config.js
|
|
59
|
+
import cedarConfig from '@cedarjs/eslint-config'
|
|
60
|
+
|
|
61
|
+
export default [
|
|
62
|
+
...(await cedarConfig()),
|
|
63
|
+
{
|
|
64
|
+
rules: {
|
|
65
|
+
'jsx-a11y/no-onchange': 'off',
|
|
66
|
+
'no-console': 'warn',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
You can also add file-specific overrides:
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
// cedar-app/eslint.config.js
|
|
76
|
+
import cedarConfig from '@cedarjs/eslint-config'
|
|
77
|
+
|
|
78
|
+
export default [
|
|
79
|
+
...(await cedarConfig()),
|
|
80
|
+
{
|
|
81
|
+
files: ['web/src/**/*.tsx'],
|
|
82
|
+
rules: {
|
|
83
|
+
'react/prop-types': 'off',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
To ignore specific files or directories:
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
// cedar-app/eslint.config.js
|
|
93
|
+
import cedarConfig from '@cedarjs/eslint-config'
|
|
94
|
+
|
|
95
|
+
export default [
|
|
96
|
+
{
|
|
97
|
+
ignores: ['scripts/**', 'generated/**'],
|
|
98
|
+
},
|
|
99
|
+
...(await cedarConfig()),
|
|
100
|
+
]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Migration Guide (Optional)
|
|
104
|
+
|
|
105
|
+
**The legacy `.eslintrc.js` format still works** - you don't have to migrate. However, if you want to use the new flat config format, follow these steps:
|
|
106
|
+
|
|
107
|
+
1. **Create a new flat config file** in your project root:
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
// eslint.config.mjs (for CommonJS projects)
|
|
111
|
+
// or eslint.config.js (for ESM projects with "type": "module")
|
|
112
|
+
import cedarConfig from '@cedarjs/eslint-config'
|
|
113
|
+
|
|
114
|
+
export default await cedarConfig()
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
2. **Remove old config**:
|
|
118
|
+
- Delete `.eslintrc.js` if it exists
|
|
119
|
+
- Remove `eslintConfig` field from `package.json` if it exists
|
|
120
|
+
|
|
121
|
+
3. **Update your package.json scripts** (if needed):
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"scripts": {
|
|
126
|
+
"lint": "eslint .",
|
|
127
|
+
"lint:fix": "eslint . --fix"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
4. **Migrate custom rules**: If you had custom rules in your old config, add them to your new flat config:
|
|
133
|
+
```javascript
|
|
134
|
+
export default [
|
|
135
|
+
...(await cedarConfig()),
|
|
136
|
+
{
|
|
137
|
+
rules: {
|
|
138
|
+
// Your custom rules here
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
]
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
That's it! Your linting should work the same as before.
|
|
145
|
+
|
|
146
|
+
## Legacy Configuration (Still Supported)
|
|
147
|
+
|
|
148
|
+
The legacy `.eslintrc.js` format is still fully supported. You can continue using it:
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
// cedar-app/.eslintrc.js
|
|
54
152
|
module.exports = {
|
|
55
|
-
extends: ['@
|
|
153
|
+
extends: ['@cedarjs/eslint-config'],
|
|
56
154
|
root: true,
|
|
57
155
|
rules: {
|
|
58
156
|
'jsx-a11y/no-onchange': 'off',
|
|
@@ -60,15 +158,15 @@ module.exports = {
|
|
|
60
158
|
}
|
|
61
159
|
```
|
|
62
160
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
In a different Redwood Framework package or in a Redwood App, you can provide configuration that applies only to that package or side by omitting the `root` directive. For example, to apply a directive only to the client code of an app:
|
|
161
|
+
Or in `package.json`:
|
|
66
162
|
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
"eslintConfig": {
|
|
70
|
-
|
|
71
|
-
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"eslintConfig": {
|
|
166
|
+
"extends": "@cedarjs/eslint-config",
|
|
167
|
+
"root": true
|
|
168
|
+
}
|
|
169
|
+
}
|
|
72
170
|
```
|
|
73
171
|
|
|
74
|
-
|
|
172
|
+
**Note:** While both formats are supported, we recommend migrating to flat config when convenient. See the [Migration Guide](#migration-guide-optional) above.
|
package/index.mjs
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// This is the ESLint configuration used by Cedar projects.
|
|
2
|
+
// Shared eslint config (projects and framework) is located in ./shared.mjs
|
|
3
|
+
// Framework main config is in monorepo root ./eslint.config.js
|
|
4
|
+
|
|
5
|
+
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y'
|
|
6
|
+
import reactCompilerPlugin from 'eslint-plugin-react-compiler'
|
|
7
|
+
import globals from 'globals'
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
getCommonPlugins,
|
|
11
|
+
getApiSideDefaultBabelConfig,
|
|
12
|
+
getWebSideDefaultBabelConfig,
|
|
13
|
+
} from '@cedarjs/babel-config'
|
|
14
|
+
import { getConfig, isTypeScriptProject } from '@cedarjs/project-config'
|
|
15
|
+
|
|
16
|
+
import sharedConfigs from './shared.mjs'
|
|
17
|
+
|
|
18
|
+
// Note: This config is async to support getConfig()
|
|
19
|
+
export default async function createConfig() {
|
|
20
|
+
const config = await getConfig()
|
|
21
|
+
|
|
22
|
+
const getProjectBabelOptions = () => {
|
|
23
|
+
// We can't nest the web overrides inside the overrides block
|
|
24
|
+
// So we just take it out and put it as a separate item
|
|
25
|
+
// Ignoring overrides, as I don't think it has any impact on linting
|
|
26
|
+
const { overrides: _webOverrides, ...otherWebConfig } =
|
|
27
|
+
getWebSideDefaultBabelConfig({
|
|
28
|
+
// We have to enable certain presets like `@babel/preset-react` for JavaScript projects
|
|
29
|
+
forJavaScriptLinting: !isTypeScriptProject(),
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const { overrides: _apiOverrides, ...otherApiConfig } =
|
|
33
|
+
getApiSideDefaultBabelConfig()
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
plugins: getCommonPlugins(),
|
|
37
|
+
overrides: [
|
|
38
|
+
{
|
|
39
|
+
test: ['./api/', './scripts/'],
|
|
40
|
+
...otherApiConfig,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
test: ['./web/'],
|
|
44
|
+
...otherWebConfig,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const plugins = {}
|
|
51
|
+
const rules = {}
|
|
52
|
+
|
|
53
|
+
// Add react compiler plugin & rules if enabled
|
|
54
|
+
const reactCompilerEnabled =
|
|
55
|
+
config.experimental?.reactCompiler?.enabled ?? false
|
|
56
|
+
if (reactCompilerEnabled) {
|
|
57
|
+
plugins['react-compiler'] = reactCompilerPlugin
|
|
58
|
+
rules['react-compiler/react-compiler'] = 2
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const configs = [
|
|
62
|
+
...sharedConfigs,
|
|
63
|
+
{
|
|
64
|
+
ignores: ['!.storybook/'],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
files: ['**/*.js', '**/*.jsx'],
|
|
68
|
+
languageOptions: {
|
|
69
|
+
parserOptions: {
|
|
70
|
+
requireConfigFile: false,
|
|
71
|
+
babelOptions: getProjectBabelOptions(),
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
plugins,
|
|
75
|
+
rules,
|
|
76
|
+
},
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
// Add jsx-a11y if enabled
|
|
80
|
+
if (config.web.a11y) {
|
|
81
|
+
configs.push({
|
|
82
|
+
plugins: {
|
|
83
|
+
'jsx-a11y': jsxA11yPlugin,
|
|
84
|
+
},
|
|
85
|
+
rules: {
|
|
86
|
+
...jsxA11yPlugin.configs.recommended.rules,
|
|
87
|
+
},
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Routes.js/jsx/tsx specific config
|
|
92
|
+
configs.push({
|
|
93
|
+
files: ['web/src/Routes.js', 'web/src/Routes.jsx', 'web/src/Routes.tsx'],
|
|
94
|
+
rules: {
|
|
95
|
+
'no-undef': 'off',
|
|
96
|
+
'jsx-a11y/aria-role': [
|
|
97
|
+
2,
|
|
98
|
+
{
|
|
99
|
+
ignoreNonDOM: true,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
'@cedarjs/unsupported-route-components': 'error',
|
|
103
|
+
},
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
// API side configuration
|
|
107
|
+
configs.push({
|
|
108
|
+
files: ['api/src/**'],
|
|
109
|
+
languageOptions: {
|
|
110
|
+
globals: {
|
|
111
|
+
...globals.node,
|
|
112
|
+
gql: 'readonly',
|
|
113
|
+
context: 'readonly',
|
|
114
|
+
},
|
|
115
|
+
sourceType: 'module',
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
// API services type annotations
|
|
120
|
+
configs.push({
|
|
121
|
+
files: ['api/src/services/**/*.ts'],
|
|
122
|
+
plugins: {
|
|
123
|
+
'@cedarjs': sharedConfigs[1].plugins['@cedarjs'],
|
|
124
|
+
},
|
|
125
|
+
rules: {
|
|
126
|
+
'@cedarjs/service-type-annotations': 'off',
|
|
127
|
+
},
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
// Seed and scripts
|
|
131
|
+
configs.push({
|
|
132
|
+
files: ['api/db/seed.js', 'scripts/**'],
|
|
133
|
+
languageOptions: {
|
|
134
|
+
globals: {
|
|
135
|
+
...globals.node,
|
|
136
|
+
...globals.commonjs,
|
|
137
|
+
},
|
|
138
|
+
sourceType: 'commonjs',
|
|
139
|
+
},
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
// Web side configuration
|
|
143
|
+
configs.push({
|
|
144
|
+
files: ['web/src/**'],
|
|
145
|
+
languageOptions: {
|
|
146
|
+
globals: {
|
|
147
|
+
...globals.browser,
|
|
148
|
+
React: 'readonly',
|
|
149
|
+
gql: 'readonly',
|
|
150
|
+
process: 'readonly',
|
|
151
|
+
require: 'readonly',
|
|
152
|
+
// Developers should use `global` instead of window
|
|
153
|
+
window: 'off',
|
|
154
|
+
},
|
|
155
|
+
sourceType: 'module',
|
|
156
|
+
},
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
// Test, stories, scenarios, and mock files
|
|
160
|
+
configs.push({
|
|
161
|
+
files: [
|
|
162
|
+
'*.test.*',
|
|
163
|
+
'**/__mocks__/**',
|
|
164
|
+
'*.scenarios.*',
|
|
165
|
+
'*.stories.*',
|
|
166
|
+
'*.mock.*',
|
|
167
|
+
],
|
|
168
|
+
languageOptions: {
|
|
169
|
+
globals: {
|
|
170
|
+
mockGraphQLQuery: 'readonly',
|
|
171
|
+
mockGraphQLMutation: 'readonly',
|
|
172
|
+
mockCurrentUser: 'readonly',
|
|
173
|
+
scenario: 'readonly',
|
|
174
|
+
defineScenario: 'readonly',
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
return configs
|
|
180
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/eslint-config",
|
|
3
|
-
"version": "2.0.4-next.
|
|
3
|
+
"version": "2.0.4-next.16+45e20cca7",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
7
7
|
"directory": "packages/eslint-config"
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./index.mjs",
|
|
13
|
+
"require": "./index.js"
|
|
14
|
+
},
|
|
15
|
+
"./shared": {
|
|
16
|
+
"import": "./shared.mjs",
|
|
17
|
+
"require": "./shared.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
10
20
|
"main": "index.js",
|
|
11
21
|
"scripts": {
|
|
12
22
|
"build": "echo 'Nothing to build..'",
|
|
@@ -16,9 +26,11 @@
|
|
|
16
26
|
"@babel/core": "^7.26.10",
|
|
17
27
|
"@babel/eslint-parser": "7.27.5",
|
|
18
28
|
"@babel/eslint-plugin": "7.27.1",
|
|
19
|
-
"@cedarjs/
|
|
20
|
-
"@cedarjs/
|
|
21
|
-
"@cedarjs/
|
|
29
|
+
"@cedarjs/babel-config": "2.0.4-next.16+45e20cca7",
|
|
30
|
+
"@cedarjs/eslint-plugin": "2.0.4-next.16+45e20cca7",
|
|
31
|
+
"@cedarjs/internal": "2.0.4-next.16+45e20cca7",
|
|
32
|
+
"@cedarjs/project-config": "2.0.4-next.16+45e20cca7",
|
|
33
|
+
"@eslint/js": "8.57.1",
|
|
22
34
|
"@typescript-eslint/eslint-plugin": "8.44.0",
|
|
23
35
|
"@typescript-eslint/parser": "8.44.0",
|
|
24
36
|
"eslint": "8.57.1",
|
|
@@ -30,8 +42,10 @@
|
|
|
30
42
|
"eslint-plugin-jsx-a11y": "6.10.2",
|
|
31
43
|
"eslint-plugin-prettier": "5.2.1",
|
|
32
44
|
"eslint-plugin-react": "7.36.1",
|
|
45
|
+
"eslint-plugin-react-compiler": "19.1.0-rc.1",
|
|
33
46
|
"eslint-plugin-react-hooks": "4.6.2",
|
|
34
|
-
"prettier": "3.6.2"
|
|
47
|
+
"prettier": "3.6.2",
|
|
48
|
+
"typescript-eslint": "8.44.0"
|
|
35
49
|
},
|
|
36
50
|
"devDependencies": {
|
|
37
51
|
"@babel/cli": "7.27.2",
|
|
@@ -40,5 +54,5 @@
|
|
|
40
54
|
"publishConfig": {
|
|
41
55
|
"access": "public"
|
|
42
56
|
},
|
|
43
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "45e20cca7a9b55ac486af5503f118df99311c309"
|
|
44
58
|
}
|
package/shared.mjs
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
// This ESLint configuration is shared between the Redwood framework,
|
|
2
|
+
// and Redwood projects.
|
|
3
|
+
//
|
|
4
|
+
// Our ESLint configuration is a mixture between ESLint's recommended
|
|
5
|
+
// rules [^1], React's recommended rules [^2], and a bit of our own stylistic
|
|
6
|
+
// flair:
|
|
7
|
+
// - no semicolons
|
|
8
|
+
// - comma dangle when multiline
|
|
9
|
+
// - single quotes
|
|
10
|
+
// - always use parenthesis around arrow functions
|
|
11
|
+
// - enforced import sorting
|
|
12
|
+
//
|
|
13
|
+
// [^1] https://eslint.org/docs/rules/
|
|
14
|
+
// [^2] https://www.npmjs.com/package/eslint-plugin-react#list-of-supported-rules
|
|
15
|
+
|
|
16
|
+
import babelParser from '@babel/eslint-parser'
|
|
17
|
+
import babelPlugin from '@babel/eslint-plugin'
|
|
18
|
+
import js from '@eslint/js'
|
|
19
|
+
import importPlugin from 'eslint-plugin-import'
|
|
20
|
+
import jestDomPlugin from 'eslint-plugin-jest-dom'
|
|
21
|
+
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y'
|
|
22
|
+
import prettierPlugin from 'eslint-plugin-prettier'
|
|
23
|
+
import reactPlugin from 'eslint-plugin-react'
|
|
24
|
+
import reactHooksPlugin from 'eslint-plugin-react-hooks'
|
|
25
|
+
import globals from 'globals'
|
|
26
|
+
import tseslint from 'typescript-eslint'
|
|
27
|
+
|
|
28
|
+
import cedarjsPlugin from '@cedarjs/eslint-plugin'
|
|
29
|
+
|
|
30
|
+
export default [
|
|
31
|
+
// Base recommended config
|
|
32
|
+
js.configs.recommended,
|
|
33
|
+
|
|
34
|
+
// Base configuration
|
|
35
|
+
{
|
|
36
|
+
plugins: {
|
|
37
|
+
'@babel': babelPlugin,
|
|
38
|
+
prettier: prettierPlugin,
|
|
39
|
+
import: importPlugin,
|
|
40
|
+
'jsx-a11y': jsxA11yPlugin,
|
|
41
|
+
react: reactPlugin,
|
|
42
|
+
'react-hooks': reactHooksPlugin,
|
|
43
|
+
'jest-dom': jestDomPlugin,
|
|
44
|
+
'@cedarjs': cedarjsPlugin,
|
|
45
|
+
},
|
|
46
|
+
languageOptions: {
|
|
47
|
+
parser: babelParser,
|
|
48
|
+
parserOptions: {
|
|
49
|
+
ecmaVersion: 'latest',
|
|
50
|
+
sourceType: 'module',
|
|
51
|
+
ecmaFeatures: {
|
|
52
|
+
jsx: true,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
settings: {
|
|
57
|
+
react: {
|
|
58
|
+
version: 'detect',
|
|
59
|
+
},
|
|
60
|
+
// For the import/order rule. Configures how it tells if an import is "internal" or not.
|
|
61
|
+
// An "internal" import is basically just one that's aliased.
|
|
62
|
+
//
|
|
63
|
+
// See...
|
|
64
|
+
// - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md#groups-array
|
|
65
|
+
// - https://github.com/import-js/eslint-plugin-import/blob/main/README.md#importinternal-regex
|
|
66
|
+
'import/internal-regex': '^src/',
|
|
67
|
+
},
|
|
68
|
+
rules: {
|
|
69
|
+
// React recommended rules
|
|
70
|
+
...reactPlugin.configs.recommended.rules,
|
|
71
|
+
// Jest DOM recommended rules
|
|
72
|
+
...jestDomPlugin.configs.recommended.rules,
|
|
73
|
+
|
|
74
|
+
'@cedarjs/process-env-computed': 'error',
|
|
75
|
+
'prettier/prettier': 'warn',
|
|
76
|
+
'no-console': 'off',
|
|
77
|
+
'prefer-object-spread': 'warn',
|
|
78
|
+
'prefer-spread': 'warn',
|
|
79
|
+
'no-unused-expressions': [
|
|
80
|
+
'error',
|
|
81
|
+
{ allowShortCircuit: true, allowTernary: true },
|
|
82
|
+
],
|
|
83
|
+
'no-useless-escape': 'off',
|
|
84
|
+
camelcase: ['warn', { properties: 'never' }],
|
|
85
|
+
'no-new': 'warn',
|
|
86
|
+
'new-cap': ['error', { newIsCap: true, capIsNew: false }],
|
|
87
|
+
'no-unused-vars': [
|
|
88
|
+
'error',
|
|
89
|
+
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
|
|
90
|
+
],
|
|
91
|
+
// React rules
|
|
92
|
+
'react/prop-types': 'off',
|
|
93
|
+
'react/display-name': 'off',
|
|
94
|
+
'react-hooks/exhaustive-deps': 'warn',
|
|
95
|
+
'import/order': [
|
|
96
|
+
'error',
|
|
97
|
+
{
|
|
98
|
+
'newlines-between': 'always',
|
|
99
|
+
// We set this to an empty array to override the default value, which is `['builtin', 'external', 'object']`.
|
|
100
|
+
// Judging by the number of issues on the repo, this option seems to be notoriously tricky to understand.
|
|
101
|
+
// From what I can tell, if the value of this is `['builtin']` that means it won't sort builtins.
|
|
102
|
+
// But we have a rule for builtins below (react), so that's not what we want.
|
|
103
|
+
//
|
|
104
|
+
// See...
|
|
105
|
+
// - https://github.com/import-js/eslint-plugin-import/pull/1570
|
|
106
|
+
// - https://github.com/import-js/eslint-plugin-import/issues/1565
|
|
107
|
+
pathGroupsExcludedImportTypes: [],
|
|
108
|
+
// Only doing this to add internal. The order here maters.
|
|
109
|
+
// See https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md#groups-array
|
|
110
|
+
groups: [
|
|
111
|
+
'builtin',
|
|
112
|
+
'external',
|
|
113
|
+
'internal',
|
|
114
|
+
'parent',
|
|
115
|
+
'sibling',
|
|
116
|
+
'index',
|
|
117
|
+
],
|
|
118
|
+
pathGroups: [
|
|
119
|
+
{
|
|
120
|
+
pattern: 'react',
|
|
121
|
+
group: 'builtin',
|
|
122
|
+
position: 'after',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
pattern: '@cedarjs/**',
|
|
126
|
+
group: 'external',
|
|
127
|
+
position: 'after',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
// Matches...
|
|
131
|
+
// - src/directives/**/*.{js,ts}
|
|
132
|
+
// - src/services/**/*.{js,ts}
|
|
133
|
+
// - src/graphql/**/*.sdl.{js,ts}
|
|
134
|
+
//
|
|
135
|
+
// Uses https://github.com/isaacs/minimatch under the hood
|
|
136
|
+
// See https://github.com/isaacs/node-glob#glob-primer for syntax
|
|
137
|
+
pattern: 'src/*/**/*.?(sdl.){js,ts}',
|
|
138
|
+
patternOptions: {
|
|
139
|
+
nobrace: true,
|
|
140
|
+
noglobstar: true,
|
|
141
|
+
},
|
|
142
|
+
group: 'internal',
|
|
143
|
+
position: 'before',
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
alphabetize: {
|
|
147
|
+
order: 'asc',
|
|
148
|
+
caseInsensitive: true,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
'no-restricted-imports': [
|
|
153
|
+
'error',
|
|
154
|
+
{
|
|
155
|
+
patterns: [
|
|
156
|
+
{
|
|
157
|
+
group: ['$api/*'],
|
|
158
|
+
message:
|
|
159
|
+
'Importing from $api is only supported in *.routeHooks.{js,ts} files',
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
// React hooks rules for JSX/TSX files (excluding api)
|
|
167
|
+
{
|
|
168
|
+
files: ['**/*.tsx', '**/*.js', '**/*.jsx'],
|
|
169
|
+
ignores: ['api/src/**'],
|
|
170
|
+
plugins: {
|
|
171
|
+
'react-hooks': reactHooksPlugin,
|
|
172
|
+
},
|
|
173
|
+
rules: {
|
|
174
|
+
'react-hooks/rules-of-hooks': 'error',
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
// TypeScript-specific configuration
|
|
178
|
+
{
|
|
179
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
180
|
+
languageOptions: {
|
|
181
|
+
parser: tseslint.parser,
|
|
182
|
+
globals: {
|
|
183
|
+
...globals.browser,
|
|
184
|
+
JSX: 'readonly',
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
plugins: {
|
|
188
|
+
'@typescript-eslint': tseslint.plugin,
|
|
189
|
+
},
|
|
190
|
+
rules: {
|
|
191
|
+
...tseslint.configs.recommended.rules,
|
|
192
|
+
|
|
193
|
+
// TODO: look into enabling these eventually
|
|
194
|
+
'@typescript-eslint/no-empty-function': 'off',
|
|
195
|
+
'@typescript-eslint/prefer-function-type': 'off',
|
|
196
|
+
|
|
197
|
+
// Specific 'recommended' rules we alter
|
|
198
|
+
'@typescript-eslint/no-var-requires': 'off',
|
|
199
|
+
'@typescript-eslint/no-require-imports': 'off',
|
|
200
|
+
'@typescript-eslint/no-empty-object-type': 'off',
|
|
201
|
+
'@typescript-eslint/no-unused-vars': [
|
|
202
|
+
'error',
|
|
203
|
+
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
|
|
204
|
+
],
|
|
205
|
+
// Disable base rule as it conflicts with @typescript-eslint/no-unused-vars
|
|
206
|
+
'no-unused-vars': 'off',
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
// Test files
|
|
210
|
+
{
|
|
211
|
+
files: [
|
|
212
|
+
'**/*.test.*',
|
|
213
|
+
'**/__mocks__/**',
|
|
214
|
+
'**/*.scenarios.*',
|
|
215
|
+
'**/*.stories.*',
|
|
216
|
+
'**/*.mock.*',
|
|
217
|
+
],
|
|
218
|
+
languageOptions: {
|
|
219
|
+
globals: {
|
|
220
|
+
...globals.jest,
|
|
221
|
+
// Cedar test globals
|
|
222
|
+
mockCurrentUser: 'readonly',
|
|
223
|
+
defineScenario: 'readonly',
|
|
224
|
+
scenario: 'readonly',
|
|
225
|
+
describeScenario: 'readonly',
|
|
226
|
+
mockGraphQLQuery: 'readonly',
|
|
227
|
+
mockGraphQLMutation: 'readonly',
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
// Config files
|
|
232
|
+
{
|
|
233
|
+
files: [
|
|
234
|
+
'.babelrc.js',
|
|
235
|
+
'babel.config.js',
|
|
236
|
+
'.eslintrc.js',
|
|
237
|
+
'**/*.config.js',
|
|
238
|
+
'**/*.config.cjs',
|
|
239
|
+
'**/*.config.mjs',
|
|
240
|
+
'**/jest.setup.js',
|
|
241
|
+
],
|
|
242
|
+
languageOptions: {
|
|
243
|
+
parser: babelParser,
|
|
244
|
+
parserOptions: {
|
|
245
|
+
requireConfigFile: false,
|
|
246
|
+
ecmaVersion: 'latest',
|
|
247
|
+
},
|
|
248
|
+
globals: {
|
|
249
|
+
...globals.node,
|
|
250
|
+
...globals.commonjs,
|
|
251
|
+
},
|
|
252
|
+
sourceType: 'commonjs',
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
// Route hooks and entry server - allow $api imports
|
|
256
|
+
{
|
|
257
|
+
files: [
|
|
258
|
+
'web/src/**/*.routeHooks.{js,ts}',
|
|
259
|
+
'web/src/entry.server.{jsx,tsx}',
|
|
260
|
+
],
|
|
261
|
+
rules: {
|
|
262
|
+
'no-restricted-imports': 'off',
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
]
|