Skip to content

Commit 413041a

Browse files
authored
chore: migrate to oxlint (#19134)
Replaces eslint with oxlint, we had an outdated Eslint 8.x setup anyways and we needed to either upgrade it or move to something else. Oxlint brings so much speed gains given how slow linting is, and almost no one is running it locally project wide because of how slow it is. The changes can look like a lot but most of it is just: - Comment Replacement due to rule name changes. - Config file swapping (from `.eslintrc.js` to `.oxlintrc.json` I downgraded a few rules, but they will be cleaned up in a follow up PR in ## Benchmarks ### Overall | Metric | Before (ESLint) | After (Oxlint) | Speedup | |--------|-----------------|----------------|---------| | CI Time | ~6 minutes | ~10 seconds | **36x**\* | Note that: - ~Lerna adds a considerable overhead that eats a lot of the gains we can potentially get.~ We removed Lerna and also we will just lint the entire project rather than go package by package. - ~CI time is hogged by building types step~ Not relevant anymore, typeaware mode works wonderfully after [oxc-project/tsgolint#739](oxc-project/tsgolint#739) was merged. #### SDK Packages | Package | Files | ESLint | Oxlint | Speedup | | ----------------- | ----- | ------ | ------ | -------- | | `core` | 365 | 9.6s | 53ms | **181x** | | `browser` | 136 | 6.8s | 55ms | **124x** | | `node` | 105 | 6.1s | 64ms | **95x** | | `node-core` | 101 | 6.2s | 56ms | **111x** | | `nextjs` | 181 | 10.9s | 79ms | **138x** | | `sveltekit` | 63 | 6.4s | 71ms | **90x** | | `opentelemetry` | 58 | 4.3s | 52ms | **83x** | | `cloudflare` | 43 | 3.8s | 45ms | **84x** | | `remix` | 38 | 7.1s | 42ms | **169x** | | `react` | 39 | 6.5s | 49ms | **133x** | | `feedback` | 38 | 3.8s | 48ms | **79x** | | `replay-internal` | 152 | 5.6s | 38ms | **147x** | | `vue` | 24 | 4.0s | 48ms | **83x** | | `svelte` | 15 | 4.0s | 52ms | **77x** | | `angular` | 12 | 3.7s | 37ms | **100x** | #### Dev Packages | Package | Files | ESLint | Oxlint | Speedup | | ------------------------------ | ----- | -------- | ------ | -------- | | `browser-integration-tests` | 778 | 10.8s | 209ms | **52x** | | `node-integration-tests` | 605 | 9.0s | 291ms | **31x** | | `node-core-integration-tests` | 268 | 6.2s | 74ms | **84x** | | `e2e-tests` | 10 | 2.6s | 44ms | **59x** | | `cloudflare-integration-tests` | 27 | 2.5s | 35ms | **71x** | | `test-utils` | 5 | 2.4s | 21ms | **114x** | | `rollup-utils` | 13 | ❌ error | 22ms | N/A | | `bundler-tests` | 3 | ❌ error | 51ms | N/A | --- closes #19222
1 parent 5e5487b commit 413041a

File tree

212 files changed

+1137
-1498
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

212 files changed

+1137
-1498
lines changed

.eslintrc.js

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

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ jobs:
308308
with:
309309
dependency_cache_key: ${{ needs.job_build.outputs.dependency_cache_key }}
310310
- name: Lint source files
311-
run: yarn lint:eslint
311+
run: yarn lint:oxlint
312312
- name: Lint for ES compatibility
313313
run: yarn lint:es-compatibility
314314

.oxlintrc.json

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
{
2+
"$schema": "./node_modules/oxlint/configuration_schema.json",
3+
"plugins": ["typescript", "import", "jsdoc", "jest", "vitest"],
4+
"jsPlugins": [
5+
{
6+
"name": "sdk",
7+
"specifier": "@sentry-internal/eslint-plugin-sdk"
8+
}
9+
],
10+
"categories": {},
11+
"rules": {
12+
// === Base rules from eslint-config-sdk/base.js ===
13+
"no-console": "error",
14+
"no-alert": "error",
15+
"no-param-reassign": "error",
16+
"prefer-template": "error",
17+
"no-bitwise": "error",
18+
"complexity": ["error", { "max": 33 }],
19+
"no-unused-expressions": ["error", { "allowShortCircuit": true }],
20+
"guard-for-in": "error",
21+
"array-callback-return": ["error", { "allowImplicit": true }],
22+
"quotes": ["error", "single", { "avoidEscape": true }],
23+
"no-return-await": "error",
24+
"max-lines": ["error", { "max": 300, "skipComments": true, "skipBlankLines": true }],
25+
26+
// === Import rules ===
27+
"import/namespace": "off",
28+
"import/no-unresolved": "off",
29+
30+
// === Jest/Vitest rules ===
31+
"jest/no-focused-tests": "error",
32+
"jest/no-disabled-tests": "error",
33+
34+
// === Rules turned off (not enforced in ESLint or causing false positives) ===
35+
"no-control-regex": "off",
36+
"jsdoc/check-tag-names": "off",
37+
"jsdoc/require-yields": "off",
38+
"no-useless-rename": "off",
39+
"no-constant-binary-expression": "off",
40+
"jest/no-conditional-expect": "off",
41+
"jest/expect-expect": "off",
42+
"jest/no-standalone-expect": "off",
43+
"jest/require-to-throw-message": "off",
44+
"jest/valid-title": "off",
45+
"jest/no-export": "off",
46+
"jest/valid-describe-callback": "off",
47+
"vitest/hoisted-apis-on-top": "off",
48+
"vitest/no-conditional-tests": "off",
49+
"no-unsafe-optional-chaining": "off",
50+
"no-eval": "off",
51+
"no-import-assign": "off",
52+
53+
// === Custom SDK rules (via JS plugin) ===
54+
"sdk/no-eq-empty": "error"
55+
},
56+
"overrides": [
57+
{
58+
"files": ["**/*.ts", "**/*.tsx", "**/*.d.ts"],
59+
"rules": {
60+
"typescript/ban-ts-comment": "error",
61+
"typescript/consistent-type-imports": "error",
62+
"typescript/no-unnecessary-type-assertion": "error",
63+
"typescript/prefer-for-of": "error",
64+
// "typescript/no-floating-promises": ["error", { "ignoreVoid": false }],
65+
"typescript/no-dynamic-delete": "error",
66+
// "typescript/no-unsafe-member-access": "error",
67+
"typescript/unbound-method": "error",
68+
"typescript/no-explicit-any": "error",
69+
"typescript/no-empty-function": "off",
70+
71+
// === FIXME: Rules to turn back as error ===
72+
"typescript/prefer-optional-chain": "warn",
73+
"typescript/no-floating-promises": "warn",
74+
"typescript/no-unsafe-member-access": "warn"
75+
}
76+
},
77+
{
78+
"files": ["**/*.js", "**/*.mjs", "**/*.cjs"],
79+
"rules": {
80+
"typescript/ban-ts-comment": "off",
81+
"typescript/consistent-type-imports": "off",
82+
"typescript/prefer-optional-chain": "off",
83+
"typescript/no-unnecessary-type-assertion": "off",
84+
"typescript/prefer-for-of": "off",
85+
"typescript/no-floating-promises": "off",
86+
"typescript/no-dynamic-delete": "off",
87+
"typescript/no-unsafe-member-access": "off",
88+
"typescript/unbound-method": "off",
89+
"typescript/no-explicit-any": "off"
90+
}
91+
},
92+
{
93+
"files": [
94+
"**/*.test.ts",
95+
"**/*.test.tsx",
96+
"**/*.test.js",
97+
"**/*.test.jsx",
98+
"**/test/**",
99+
"**/tests/**",
100+
"**/suites/**",
101+
"**/loader-suites/**"
102+
],
103+
"rules": {
104+
"typescript/explicit-function-return-type": "off",
105+
"no-unused-expressions": "off",
106+
"typescript/no-unused-expressions": "off",
107+
"typescript/no-unnecessary-type-assertion": "off",
108+
"typescript/no-unsafe-member-access": "off",
109+
"typescript/no-explicit-any": "off",
110+
"typescript/no-non-null-assertion": "off",
111+
"typescript/no-floating-promises": "off",
112+
"typescript/unbound-method": "off",
113+
"max-lines": "off",
114+
"complexity": "off"
115+
}
116+
},
117+
{
118+
"files": ["*.tsx"],
119+
"rules": {
120+
"jsdoc/require-jsdoc": "off"
121+
}
122+
},
123+
{
124+
"files": ["*.config.js", "*.config.mjs", "*.config.ts", "vite.config.ts", ".size-limit.js"],
125+
"rules": {
126+
"no-console": "off",
127+
"max-lines": "off"
128+
}
129+
},
130+
{
131+
"files": [
132+
"**/scenarios/**",
133+
"**/rollup-utils/**",
134+
"**/bundle-analyzer-scenarios/**",
135+
"**/bundle-analyzer-scenarios/*.cjs",
136+
"**/bundle-analyzer-scenarios/*.js"
137+
],
138+
"rules": {
139+
"no-console": "off"
140+
}
141+
},
142+
{
143+
"files": ["**/src/**"],
144+
"rules": {
145+
"no-restricted-globals": ["error", "window", "document", "location", "navigator"],
146+
"sdk/no-class-field-initializers": "error",
147+
"sdk/no-regexp-constructor": "error"
148+
}
149+
}
150+
],
151+
"env": {
152+
"es2017": true,
153+
"node": true
154+
},
155+
"globals": {},
156+
"ignorePatterns": [
157+
"coverage/**",
158+
"build/**",
159+
"dist/**",
160+
"cjs/**",
161+
"esm/**",
162+
"examples/**",
163+
"test/manual/**",
164+
"types/**",
165+
"scripts/*.js",
166+
"node_modules/**"
167+
]
168+
}

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Use **yarn**: `yarn install`, `yarn build:dev`, `yarn test`, `yarn lint`
2020
| `yarn build:dev:filter @sentry/<pkg>` | Build one package + deps |
2121
| `yarn build:bundle` | Browser bundles only |
2222
| `yarn test` | All unit tests |
23-
| `yarn lint` | ESLint + Oxfmt |
23+
| `yarn lint` | Oxlint + Oxfmt |
2424
| `yarn fix` | Auto-fix lint + format |
2525
| `yarn format` | Auto-fix formatting (Oxfmt) |
2626

dev-packages/.eslintrc.js

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

dev-packages/.oxlintrc.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"$schema": "../node_modules/oxlint/configuration_schema.json",
3+
"extends": ["../.oxlintrc.json"],
4+
"rules": {
5+
"typescript/no-explicit-any": "off",
6+
"max-lines": "off",
7+
"no-unused-expressions": "off"
8+
}
9+
}

dev-packages/browser-integration-tests/.eslintrc.js

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"$schema": "../../node_modules/oxlint/configuration_schema.json",
3+
"extends": ["../.oxlintrc.json"],
4+
"env": {
5+
"browser": true,
6+
"node": true
7+
},
8+
"ignorePatterns": [
9+
"suites/**/subject.js",
10+
"suites/**/dist/*",
11+
"loader-suites/**/dist/*",
12+
"loader-suites/**/subject.js",
13+
"scripts/**",
14+
"fixtures/**",
15+
"tmp/**"
16+
],
17+
"overrides": [
18+
{
19+
"files": ["**/*.ts", "**/*.tsx"],
20+
"rules": {
21+
"typescript/no-unsafe-member-access": "off"
22+
}
23+
},
24+
{
25+
"files": ["loader-suites/**/{subject,init}.js"],
26+
"globals": {
27+
"Sentry": "readonly"
28+
}
29+
}
30+
]
31+
}

dev-packages/browser-integration-tests/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
"scripts": {
1111
"clean": "rimraf -g suites/**/dist loader-suites/**/dist tmp",
1212
"install-browsers": "[[ -z \"$SKIP_PLAYWRIGHT_BROWSER_INSTALL\" ]] && npx playwright install --with-deps || echo 'Skipping browser installation'",
13-
"lint": "eslint . --format stylish",
14-
"fix": "eslint . --format stylish --fix",
13+
"lint": "oxlint .",
14+
"fix": "oxlint . --fix",
1515
"type-check": "tsc",
1616
"postinstall": "yarn install-browsers",
1717
"pretest": "yarn clean && yarn type-check",

dev-packages/bundler-tests/.eslintrc.js

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

0 commit comments

Comments
 (0)