@gooddata/eslint-config 4.1.1 → 11.4.0-alpha.4

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,49 +1,270 @@
1
- # GoodData JavaScript Style Guide
1
+ # @gooddata/eslint-config
2
2
 
3
- This package is build based on https://eslint.org/docs/developer-guide/shareable-configs. Provides common linting rules for gooddata TS/JS projects.
3
+ Unified, modular ESLint configuration for the GoodData.UI monorepo.
4
4
 
5
- Linter is using typescript-eslint parser to check typescript and javascript sources
5
+ ## Purpose
6
6
 
7
- More details: https://typescript-eslint.io, [typescript-eslint Roadmap](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/ROADMAP.md)
7
+ This package consolidates ESLint configurations that were previously scattered across:
8
8
 
9
- ## Install
9
+ - SDK root directory configurations
10
+ - Separate library in gdc-ui
10
11
 
11
- ```
12
- yarn add @gooddata/eslint-config --dev
13
- ```
12
+ The new approach provides:
14
13
 
15
- Add required eslint, parser & plugins
14
+ - **Modular structure** - Rules organized by plugin/concern in separate files
15
+ - **Easy to edit** - Find and modify rules in logical locations
16
+ - **Unified configs** - Single source of truth for linting standards
17
+ - **Type-safe** - TypeScript-based configuration with validation
18
+ - **Variant support** - Different preset combinations for various project types
16
19
 
17
- ```
18
- yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-header eslint-plugin-import eslint-plugin-jest --dev
19
- ```
20
+ ## How It Works
21
+
22
+ ### Architecture
23
+
24
+ 1. **Configuration Modules** (`src/configurations/`)
25
+ - Each file represents a plugin or concern (typescript, react, header, etc.)
26
+ - Defines: required packages, plugin name, rules, extends, overrides
27
+ - Type-safe with `IConfiguration<RulePrefix>` interface
28
+
29
+ 2. **Index File** (`src/index.ts`)
30
+ - `common` array: Base rules applied to all configs
31
+ - `variants` object: Different combinations for specific use cases
32
+
33
+ 3. **Build Process** (`npm run build`)
34
+ - Merges configuration modules into JSON files in `dist/`
35
+ - Creates `base.json` (all common configs)
36
+ - Creates variant files: `browser.json`, `react.json`, `esm-react.json`, etc.
37
+ - Consumers import via: `@gooddata/eslint-config/react` � `dist/react.json`
38
+
39
+ 4. **Package Sync** (`npm run update-package`)
40
+ - Auto-updates `package.json` dependencies and peer dependencies
41
+ - Reads package requirements from each configuration module
42
+ - Syncs versions to ensure consistency
43
+
44
+ ## Available Variants
45
+
46
+ - **base** (`.`) - Core rules for all packages
47
+ - **browser** (`/browser`) - For packages using browser APIs (document, window)
48
+ - **browser-esm** (`/browser-esm`) - Browser + ESM import rules
49
+ - **esm** (`/esm`) - ESM-specific import rules
50
+ - **esm-vitest** (`/esm-vitest`) - ESM + Vitest rules
51
+ - **react** (`/react`) - Browser + React + React Hooks rules
52
+ - **react-cypress** (`/react-cypress`) - Browser + React + React Hooks + Cypress rules
53
+ - **esm-react** (`/esm-react`) - Browser + React + React Hooks + ESM rules (most React libraries)
54
+ - **esm-react-cypress** (`/esm-react-cypress`) - Browser + React + React Hooks + ESM + Cypress rules
55
+ - **esm-react-vitest** (`/esm-react-vitest`) - Browser + React + React Hooks + ESM + Vitest rules
20
56
 
21
57
  ## Usage
22
58
 
23
- Add or edit in project `.eslintrc.js` file.
59
+ ### TypeScript Projects (Recommended)
60
+
61
+ For TypeScript projects, use the `tsOverride` helper which automatically configures the TypeScript parser, import resolver, and other required settings:
24
62
 
25
63
  ```javascript
64
+ // (C) 2020 GoodData Corporation
65
+
66
+ const { tsOverride } = require("@gooddata/eslint-config/tsOverride");
67
+
26
68
  module.exports = {
27
- root: true,
28
- extends: ["@gooddata"],
69
+ extends: ["@gooddata/eslint-config/react"],
70
+ overrides: [
71
+ tsOverride(__dirname, {
72
+ // Optional: Add custom TypeScript rule overrides here
73
+ "@typescript-eslint/no-namespace": "off",
74
+ "@typescript-eslint/no-unsafe-assignment": "off",
75
+ }),
76
+ ],
77
+ };
78
+ ```
79
+
80
+ **What `tsOverride` does:**
81
+ - Sets up the TypeScript parser (`@typescript-eslint/parser`)
82
+ - Configures `tsconfigRootDir` to point to your project directory
83
+ - Configures the import resolver to handle TypeScript imports correctly
84
+ - Applies to `**/*.ts` and `**/*.tsx` files
85
+ - Allows you to pass custom rule overrides as the second parameter
86
+
87
+ ### Non-TypeScript Projects
88
+
89
+ For non-TypeScript projects, simply extend the configuration:
90
+
91
+ ```javascript
92
+ module.exports = {
93
+ extends: ["@gooddata/eslint-config/react"],
94
+ };
95
+ ```
96
+
97
+ **Important Notes:**
98
+
99
+ - **TypeScript Projects**: Using `tsOverride(__dirname, rules)` is **mandatory** for TypeScript projects. Without it, `@typescript-eslint/parser` won't know where to find your `tsconfig.json`, and import resolution will not work correctly.
100
+
101
+ - **Peer Dependencies**: Only packages from the `common` configuration are listed in `peerDependencies`. Variant-specific packages (e.g., `eslint-plugin-react` for the `react` variant) are **not** included as peer dependencies since they're not required by all consumers.
102
+
103
+ - **Verify Dependencies**: After adopting a configuration, run `npm run eslint` (or your lint command) to ensure all necessary dependencies are present in your project. If you get plugin errors, install the missing packages.
104
+
105
+ ## Development Guide
106
+
107
+ ### Adding a New Configuration Module
108
+
109
+ 1. Create a new file in `src/configurations/` (e.g., `my-plugin.ts`):
110
+
111
+ ```typescript
112
+ // (C) 2025 GoodData Corporation
113
+
114
+ import type { IConfiguration } from "../types.js";
115
+
116
+ const configuration: IConfiguration<"my-plugin"> = {
117
+ packages: [
118
+ {
119
+ name: "eslint-plugin-my-plugin",
120
+ version: "1.0.0",
121
+ },
122
+ ],
123
+ plugin: "my-plugin",
124
+ extends: ["plugin:my-plugin/recommended"],
29
125
  rules: {
30
- // Custom rules
126
+ "my-plugin/some-rule": "error",
31
127
  },
32
128
  };
129
+
130
+ export default configuration;
33
131
  ```
34
132
 
35
- ## Development
133
+ 2. Export it from `src/configurations/index.ts`:
36
134
 
37
- Install [Node.js](http://nodejs.org) and [Yarn](https://classic.yarnpkg.com) (for versions, see [config](docker/.config)).
135
+ ```typescript
136
+ export { default as myPlugin } from "./my-plugin.js";
137
+ ```
38
138
 
39
- Install dependencies:
139
+ 3. Add it to `common` or a variant in `src/index.ts`:
40
140
 
141
+ ```typescript
142
+ export const common = [
143
+ // ... existing configs
144
+ myPlugin,
145
+ ];
41
146
  ```
42
- yarn install --frozen-lockfile
147
+
148
+ 4. **Run `npm run update-package`** to sync dependencies to `package.json`
149
+
150
+ 5. Run `npm run build` to generate updated JSON configs
151
+
152
+ ### Adding a New Variant
153
+
154
+ 1. Add the variant to `src/index.ts`:
155
+
156
+ ```typescript
157
+ export const variants = {
158
+ // ... existing variants
159
+ "my-variant": [browserEnv, myPlugin],
160
+ };
161
+ ```
162
+
163
+ 2. **Run `npm run update-package`** to update `package.json` exports
164
+
165
+ 3. Run `npm run build` to generate the new variant JSON file
166
+
167
+ ### Upgrading a Package Version
168
+
169
+ 1. Update the version in the configuration file (e.g., `src/configurations/typescript.ts`):
170
+
171
+ ```typescript
172
+ const configuration: IConfiguration = {
173
+ packages: [
174
+ {
175
+ name: "@typescript-eslint/parser",
176
+ version: "8.50.0", // � Update here
177
+ },
178
+ ],
179
+ // ...
180
+ };
181
+ ```
182
+
183
+ 2. **Run `npm run update-package`** to sync to `package.json`
184
+
185
+ 3. Run `npm run build` to regenerate configs
186
+
187
+ ### Modifying Rules
188
+
189
+ 1. Find the relevant configuration file in `src/configurations/`
190
+ 2. Update the rules object:
191
+
192
+ ```typescript
193
+ rules: {
194
+ "my-plugin/some-rule": "off", // Disable
195
+ "my-plugin/another-rule": ["error", { option: true }], // Configure
196
+ }
43
197
  ```
44
198
 
45
- ## Release
199
+ 3. Run `npm run build` to regenerate JSON configs
200
+
201
+ ## Scripts
202
+
203
+ - **`npm run build`** - Generates JSON configuration files in `dist/`
204
+ - Merges all configuration modules
205
+ - Creates base.json and all variant files
206
+ - Required before publishing or testing changes
207
+
208
+ - **`npm run update-package`** - Syncs dependencies and exports
209
+ - Updates `devDependencies` and `peerDependencies` in `package.json`
210
+ - Updates `exports` field based on available variants
211
+ - **Must run after**: adding variants, adding configs, changing package versions
212
+
213
+ - **`npm run validate`** - Type-checks TypeScript files
214
+
215
+ - **`npm run eslint`** - Lints the configuration source code
216
+
217
+ ## Configuration Structure
218
+
219
+ Each configuration module follows this structure:
220
+
221
+ ```typescript
222
+ interface IConfiguration<RulePrefix extends string = ""> {
223
+ // Packages required for this configuration
224
+ packages?: Array<{
225
+ name: string;
226
+ version: string;
227
+ }>;
228
+
229
+ // Parser to use (e.g., "@typescript-eslint/parser")
230
+ parser?: string;
231
+
232
+ // Plugin to register (e.g., "react")
233
+ plugin?: string;
234
+
235
+ // Shareable configs to extend
236
+ extends?: string[];
237
+
238
+ // Parser options
239
+ parserOptions?: Record<string, number | string>;
240
+
241
+ // ESLint rules
242
+ rules?: Rules<RulePrefix>;
243
+
244
+ override?: {
245
+ files: string[];
246
+ parser?: string;
247
+ plugin?: string;
248
+ extends?: string[];
249
+ parserOptions?: Record<string, number | string>;
250
+ rules?: Rules<RulePrefix>;
251
+ settings?: Record<string, object>;
252
+ env?: Record<string, boolean>;
253
+ ignorePatterns?: string[];
254
+ };
255
+
256
+ // Plugin settings
257
+ settings?: Record<string, object>;
258
+
259
+ // Environment settings
260
+ env?: Record<string, boolean>;
261
+
262
+ // Ignore patterns (e.g., "**/dist/**/*.*")
263
+ ignorePatterns?: string[];
264
+ }
265
+ ```
46
266
 
47
- Package publishing is done via Jenkins Job:
267
+ **Notes**:
48
268
 
49
- https://checklist.intgdc.com/job/client-libs/job/gdc-js-style-javascript-release/
269
+ - The base configuration automatically ignores `**/dist/**/*.*` and `**/esm/**/*.*` files.
270
+ - **ESM vs ImportESM**: The `esm` configuration sets `parserOptions.sourceType: "module"` to tell the parser to treat files as ES modules. The `importEsm` configuration adds the `eslint-plugin-import-esm` plugin which enforces ESM-specific import rules (e.g., requiring `.js` extensions in imports). Most ESM projects need both.