Skip to content

Commit e5a97b8

Browse files
Merge branch 'develop' into feat/cy-prompt
2 parents fe63715 + d5c8885 commit e5a97b8

18 files changed

+2064
-413
lines changed

guides/eslint-migration.md

Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
# ESLint Migration Guide: Monorepo Alignment
2+
3+
## Migration Checklist
4+
5+
### Batch 1: Small npm utilities
6+
- [x] npm/grep ✅ **COMPLETED** - Uses unified ESLint config with package-specific lint-staged handling
7+
- [ ] npm/puppeteer
8+
- [ ] npm/mount-utils
9+
- [ ] npm/cypress-schematic
10+
11+
### Batch 2: Framework adapters
12+
- [ ] npm/react
13+
- [ ] npm/vue
14+
- [ ] npm/svelte
15+
16+
### Batch 3: Build-related
17+
- [ ] npm/webpack-batteries-included-preprocessor
18+
- [ ] npm/webpack-preprocessor
19+
- [ ] npm/webpack-dev-server
20+
- [ ] npm/vite-plugin-cypress-esm
21+
- [ ] npm/vite-dev-server
22+
23+
### Batch 4a: Core packages (part 1)
24+
- [ ] packages/frontend-shared
25+
- [ ] packages/icons
26+
- [ ] packages/launcher
27+
- [ ] packages/https-proxy
28+
- [ ] packages/proxy
29+
- [ ] packages/net-stubbing
30+
- [ ] packages/driver
31+
- [ ] packages/rewriter
32+
- [ ] packages/reporter
33+
- [ ] packages/server
34+
35+
### Batch 4b: Core packages (part 2)
36+
- [ ] packages/runner
37+
- [ ] packages/extension
38+
- [ ] packages/graphql
39+
- [ ] packages/network
40+
- [ ] packages/socket
41+
- [ ] packages/telemetry
42+
- [ ] packages/launchpad
43+
- [ ] packages/errors
44+
- [ ] packages/data-context
45+
- [ ] packages/app
46+
47+
### Batch 4c: Core packages (part 3)
48+
- [ ] packages/config
49+
- [ ] packages/root
50+
- [ ] packages/resolve-dist
51+
- [ ] packages/packherd-require
52+
- [ ] packages/v8-snapshot-require
53+
- [ ] packages/web-config
54+
- [ ] packages/types
55+
- [ ] packages/example
56+
57+
### Batch 5: Test and script folders
58+
- [ ] system-tests
59+
- [ ] scripts
60+
61+
---
62+
63+
This guide describes how to migrate all packages in the Cypress monorepo to the new unified ESLint configuration (`@packages/eslint-config`).
64+
65+
---
66+
67+
## Why Migrate?
68+
- **Consistency:** Enforce the same linting rules and plugins across all packages.
69+
- **Simplicity:** Remove the need for custom plugins like `@cypress/eslint-plugin-dev`.
70+
- **Maintainability:** Make it easier to update and maintain lint rules.
71+
- **Modernization:** Replace obsolete TSLint with the appropriate ESLint TypeScript plugin (`@typescript-eslint`).
72+
73+
---
74+
75+
## Migration Strategy
76+
77+
### 1. **Lint-Staged Configuration**
78+
During the migration period, the root `package.json` uses explicit lint-staged patterns to ensure each package gets the correct linting treatment:
79+
80+
- **Migrated packages** (like `npm/grep`): Use `yarn lint:fix` which runs ESLint from the package directory with the correct config
81+
- **Non-migrated packages**: Use `eslint --fix` which runs from the root with the root config
82+
- **Root files**: Covered by `*.{js,jsx,ts,tsx,json,eslintrc,vue}` pattern
83+
84+
This configuration will be simplified once all packages are migrated to the unified ESLint setup.
85+
86+
### 2. **Batch Packages for Migration**
87+
- **Batch by directory/type** to keep PRs manageable and reduce risk.
88+
- **Batch size:** 4–8 packages per PR, grouped by similarity.
89+
90+
### 2. **Migration Steps for Each Package**
91+
92+
For each package in the batch:
93+
94+
1. **Remove old ESLint config and plugin references:**
95+
- Delete `.eslintrc`, `.eslintrc.json`, or `.eslintrc.js` in the package.
96+
- Remove any references to `@cypress/eslint-plugin-dev` in `package.json` (if present).
97+
- **Remove TSLint configs:** Delete `tslint.json` and remove `tslint` dependencies from `package.json`.
98+
2. **Add a new ESLint config file:**
99+
- Create `eslint.config.ts` in the package root:
100+
```ts
101+
import baseConfig from '@packages/eslint-config'
102+
export default baseConfig
103+
```
104+
3. **Ensure dependencies are up to date:**
105+
- Remove any package-local ESLint plugins now provided by the shared config.
106+
- Remove TSLint-related dependencies (the new config includes `@typescript-eslint`).
107+
- **Add the shared ESLint config as a dev dependency:**
108+
- In each migrated package, add `@packages/eslint-config` to `devDependencies` (use a relative file path if not published to npm).
109+
- **Add ESLint as a dev dependency:**
110+
- Since `@packages/eslint-config` has ESLint as a peer dependency, add `eslint: "^9.18.0"` to `devDependencies`.
111+
4. **Run lint and autofix:**
112+
- From the package root, run:
113+
```
114+
npx eslint . --ext .js,.ts,.tsx,.jsx --fix
115+
```
116+
- Manually fix any remaining lint errors.
117+
5. **Verify TypeScript configuration:**
118+
- Ensure the package has a valid `tsconfig.json` that works with the new ESLint config.
119+
- Run `npx tsc --noEmit` to check for TypeScript compilation errors.
120+
- Verify that the new ESLint config can properly parse TypeScript files in the package.
121+
6. **Run tests for the package** to ensure nothing broke.
122+
7. **Commit changes** with a clear message, e.g.:
123+
```
124+
chore(npm/grep): migrate to @packages/eslint-config and remove legacy eslint-plugin-dev
125+
```
126+
127+
### 3. **Open a PR for Each Batch**
128+
- Keep each migration PR focused (one batch per PR).
129+
- List all affected packages in the PR description.
130+
- Include a checklist for each package:
131+
- [ ] Removed old ESLint config
132+
- [ ] Added new config
133+
- [ ] Ran lint and fixed errors
134+
- [ ] Ran tests
135+
136+
### 4. **Document Issues or Gaps**
137+
- If you hit any missing rules or plugin gaps, note them for follow-up.
138+
- If a package needs a custom override, add it in a local `eslint.config.ts` (prefer to upstream to the shared config if possible).
139+
140+
### 5. **Deprecate and Remove Old Plugin**
141+
- Once all packages are migrated, remove `@cypress/eslint-plugin-dev` from the repo and CI.
142+
143+
### 6. **Simplify Lint-Staged Configuration**
144+
After all packages are migrated, simplify the lint-staged configuration in root `package.json`:
145+
146+
```json
147+
{
148+
"lint-staged": {
149+
"**/*.{js,jsx,ts,tsx,json,eslintrc,vue}": "eslint --fix",
150+
"*workflows.yml": "node scripts/format-workflow-file.js"
151+
}
152+
}
153+
```
154+
155+
### 7. **Update Lerna/Monorepo Config**
156+
- Ensure all packages reference the new config in their `package.json`/`eslint.config.ts`.
157+
- Update documentation and developer onboarding guides.
158+
159+
---
160+
161+
## Example: Migrating a Batch
162+
163+
1. **Select batch:** e.g., `npm/grep`, `npm/puppeteer`, `npm/mount-utils`, `npm/cypress-schematic`
164+
2. **For each package:**
165+
- Remove `.eslintrc*` files
166+
- Add `eslint.config.ts` as above
167+
- Remove local plugin deps
168+
- Run lint and fix errors
169+
- Run tests
170+
3. **Commit and open PR**
171+
172+
---
173+
174+
## Troubleshooting Guide
175+
176+
### Common Issues and Solutions
177+
178+
#### 1. **Jiti Version Compatibility Error**
179+
**Error:** `Error: You are using an outdated version of the 'jiti' library. Please update to the latest version of 'jiti' to ensure compatibility and access to the latest features.`
180+
181+
**Solution:**
182+
- Add `jiti: "^2.4.2"` to the package's `devDependencies`
183+
- ESLint 9.x requires jiti >= 2.2.0, but monorepo dependencies might provide older versions
184+
185+
#### 2. **TypeScript Project Service Errors**
186+
**Error:** `was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject`
187+
188+
**Solutions:**
189+
- **Create/update `tsconfig.json`** that extends the base config:
190+
```json
191+
{
192+
"extends": "../../packages/ts/tsconfig.json",
193+
"compilerOptions": {
194+
"esModuleInterop": true,
195+
"allowJs": true,
196+
"checkJs": false
197+
},
198+
"include": [
199+
"src/**/*",
200+
"cypress/**/*",
201+
"*.js",
202+
"*.ts",
203+
"*.jsx",
204+
"*.tsx"
205+
],
206+
"exclude": ["node_modules", "dist"]
207+
}
208+
```
209+
- **For Cypress packages**, ensure `cypress/tsconfig.json` includes all test files:
210+
```json
211+
{
212+
"compilerOptions": {
213+
"types": ["cypress"]
214+
},
215+
"include": [
216+
"**/*.ts",
217+
"**/*.js"
218+
]
219+
}
220+
```
221+
- **Add `allowDefaultProject: true`** to ESLint config for problematic files:
222+
```ts
223+
{
224+
files: ['**/*.js', '**/*.ts', '**/*.jsx', '**/*.tsx'],
225+
languageOptions: {
226+
parserOptions: {
227+
allowDefaultProject: true,
228+
},
229+
},
230+
}
231+
```
232+
233+
#### 3. **Skip Comment Rule Violations**
234+
**Error:** `@cypress/dev/skip-comment` rule violations for `it.skip()` tests
235+
236+
**Solution:**
237+
- Replace `eslint-disable-next-line @cypress/dev/skip-comment` with proper explanatory comments:
238+
```js
239+
// NOTE: This test is skipped for demonstration purposes
240+
it.skip('first test', () => {})
241+
```
242+
243+
#### 4. **Rule Mismatches in Pre-commit Hook**
244+
**Error:** ESLint rule violations that don't match the package's ESLint configuration (e.g., `Unexpected console statement` when `no-console` is off in package config)
245+
246+
**Root Cause:** Pre-commit hook runs ESLint from root directory using root-level config, not package-specific config
247+
248+
**Solution:**
249+
- The root `package.json` now includes explicit lint-staged patterns for each package:
250+
```json
251+
"lint-staged": {
252+
"npm/grep/**/*.{js,jsx,ts,tsx}": "yarn lint:fix",
253+
"*.{js,jsx,ts,tsx,json,eslintrc,vue}": "eslint --fix",
254+
"cli/**/*.{js,jsx,ts,tsx,json,eslintrc,vue}": "eslint --fix",
255+
"packages/**/*.{js,jsx,ts,tsx,json,eslintrc,vue}": "eslint --fix",
256+
// ... explicit patterns for each directory
257+
}
258+
```
259+
- **For migrated packages:** Use `yarn lint:fix` which runs the lerna command to execute ESLint from the package directory
260+
- **For non-migrated packages:** Use `eslint --fix` which runs from the root with the root config
261+
- **Note:** This verbose configuration is temporary during migration and will be simplified once all packages are migrated
262+
263+
#### 5. **ESLint Script Changes**
264+
**Before ESLint 9.x:**
265+
```json
266+
"lint": "eslint . --ext .js,.ts"
267+
```
268+
269+
**After ESLint 9.x:**
270+
```json
271+
"lint": "eslint"
272+
```
273+
ESLint 9.x auto-detects file extensions, so `--ext` flag is no longer needed.
274+
275+
#### 6. **Package Dependencies**
276+
**Required additions to `package.json`:**
277+
```json
278+
{
279+
"devDependencies": {
280+
"@packages/eslint-config": "0.0.0-development",
281+
"eslint": "^9.18.0",
282+
"jiti": "^2.4.2"
283+
}
284+
}
285+
```
286+
287+
#### 7. **Custom Package Rules**
288+
If a package needs custom rules, extend the base config:
289+
```ts
290+
import baseConfig from '@packages/eslint-config'
291+
292+
export default [
293+
...baseConfig,
294+
{
295+
files: ['**/*.js', '**/*.ts', '**/*.jsx', '**/*.tsx'],
296+
rules: {
297+
'no-console': 'off',
298+
'no-restricted-syntax': 'off',
299+
},
300+
},
301+
{
302+
files: ['cypress/**/*.js', 'cypress/**/*.ts'],
303+
languageOptions: {
304+
globals: {
305+
Cypress: 'readonly',
306+
cy: 'readonly',
307+
},
308+
},
309+
},
310+
]
311+
```
312+
313+
### Migration Checklist Template
314+
315+
For each package, ensure you've completed:
316+
317+
- [ ] Removed `.eslintrc*` files
318+
- [ ] Created `eslint.config.ts` with proper configuration
319+
- [ ] Added required dependencies (`eslint`, `@packages/eslint-config`, `jiti`)
320+
- [ ] Created/updated `tsconfig.json` that extends base config
321+
- [ ] Updated ESLint scripts (removed `--ext` flag)
322+
- [ ] Ran `yarn lint` successfully
323+
- [ ] Ran tests to ensure nothing broke
324+
325+
---
326+
327+
## Tips
328+
- Use a tracking issue or project board to coordinate and document progress.
329+
- If a package is especially noisy, consider splitting it into its own PR.
330+
- Communicate with the team about the migration timeline and process.
331+
- **Test the pre-commit hook** before pushing to ensure lint-staged works correctly.
332+
333+
## Recent Updates
334+
- **Fixed lint-staged configuration** to properly handle migrated vs non-migrated packages
335+
- **Added explicit directory patterns** to ensure complete coverage during migration period
336+
337+
---
338+
339+
**Happy linting!**

npm/grep/.eslintrc

Lines changed: 0 additions & 16 deletions
This file was deleted.

npm/grep/cypress/e2e/omit-and-skip-spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// @ts-check
44
describe('Page', () => {
55
describe('List', { tags: ['@us1'] }, () => {
6-
// eslint-disable-next-line @cypress/dev/skip-comment
6+
// NOTE: This test is skipped for demonstration purposes
77
it.skip('first test', () => {})
88
it('second test', () => {})
99
it('third test', () => {})

npm/grep/cypress/e2e/skip-spec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
/* eslint-disable @cypress/dev/skip-comment */
21
/// <reference types="cypress" />
32
describe('tests that use .skip', () => {
43
// use a template literal
54
it(`works`, () => {})
65

6+
// NOTE: This test is pending for demonstration
77
it.skip('is pending', () => {})
88

9+
// NOTE: This test is also pending for demonstration
910
it.skip('is pending again', () => {})
1011
})

npm/grep/cypress/tsconfig.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
{
22
"compilerOptions": {
3-
"types": ["cypress"]
3+
"types": ["cypress"],
4+
"allowJs": true,
5+
"checkJs": false
46
},
5-
"include": ["e2e/**/*.ts"]
7+
"include": [
8+
"**/*.ts",
9+
"**/*.js"
10+
]
611
}

0 commit comments

Comments
 (0)