fix: replace eslint with oxlint#8677
Conversation
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... 📒 Files selected for processing (4)
✏️ Tip: You can disable in-progress messages and the fortune message in your review settings. Tip You can customize the high-level summary generated by CodeRabbit.Configure the 📝 WalkthroughWalkthroughThe PR migrates linting from ESLint to OxLint across the monorepo (configs, package scripts, CI, turbo), removes the old ESLint configuration and related devDependencies, adds a new .oxlintrc.json, adjusts CI lint/type jobs, updates documentation, and includes a small runtime bug fix and removal of explicit constructors in several service classes. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR migrates the monorepo’s linting setup from ESLint to OxLint, updating tooling config, package scripts, and CI/docs accordingly.
Changes:
- Replace ESLint-based
check:lint/fix:lintscripts across apps/packages withoxlintequivalents. - Introduce root
.oxlintrc.json, removeeslint.config.mjs, and update Turbo global deps/caching for lint tasks. - Update linting documentation and CI workflow to run lint independently of build.
Reviewed changes
Copilot reviewed 30 out of 31 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
turbo.json |
Switch global dependency from eslint.config.mjs to .oxlintrc.json; adjust lint task outputs/deps for OxLint workflow. |
pnpm-lock.yaml |
Remove ESLint dependency tree; add OxLint packages/bindings. |
packages/utils/package.json |
Update lint scripts to oxlint. |
packages/ui/package.json |
Update lint scripts to oxlint. |
packages/types/package.json |
Update lint scripts to oxlint. |
packages/shared-state/package.json |
Update lint scripts to oxlint. |
packages/services/src/module/operations.service.ts |
Remove redundant constructor; leaves minor whitespace cleanup needed. |
packages/services/src/module/module.service.ts |
Remove redundant constructor; leaves minor whitespace cleanup needed. |
packages/services/src/module/link.service.ts |
Remove redundant constructor but leaves stale constructor JSDoc block that should be cleaned up. |
packages/services/package.json |
Update lint scripts to oxlint. |
packages/propel/package.json |
Update lint scripts to oxlint. |
packages/logger/package.json |
Update lint scripts to oxlint. |
packages/i18n/package.json |
Update lint scripts to oxlint. |
packages/hooks/src/use-local-storage.tsx |
Replace incorrect typeof window === undefined check, but introduces duplicated condition that should be simplified. |
packages/hooks/package.json |
Update lint scripts to oxlint. |
packages/eslint-config/.prettierignore |
Remove Prettier ignore file from the eslint-config package. |
packages/editor/package.json |
Update lint scripts to oxlint. |
packages/decorators/package.json |
Update lint scripts to oxlint. |
packages/constants/package.json |
Update lint scripts to oxlint. |
package.json |
Drop ESLint devDependencies; add oxlint; update lint-staged to run oxlint. |
eslint.config.mjs |
Remove ESLint flat config. |
docs/linting.md |
Add OxLint-focused linting documentation. |
docs/eslint.md |
Remove ESLint documentation. |
apps/web/package.json |
Update lint scripts to oxlint. |
apps/space/package.json |
Update lint scripts to oxlint. |
apps/live/package.json |
Update lint scripts to oxlint. |
apps/admin/package.json |
Update lint scripts to oxlint. |
CONTRIBUTING.md |
Update contributor guidance to reference OxLint + oxfmt instead of ESLint + Prettier. |
AGENTS.md |
Update agent/dev workflow notes to reference OxLint. |
.oxlintrc.json |
Add root OxLint configuration. |
.github/workflows/pull-request-build-lint-web-apps.yml |
Split out check:lint into its own job (no build dependency) and keep check:types gated on build. |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/services/src/module/link.service.ts (1)
17-21:⚠️ Potential issue | 🟡 MinorRemove stale constructor JSDoc after constructor deletion.
Lines 17–20 still document a constructor (
baseURL) that no longer exists, which is misleading.✂️ Suggested cleanup
export class ModuleLinkService extends APIService { - /** - * Creates an instance of ModuleLinkService. - * `@param` {string} baseURL - The base URL for the API endpoints - */ - - /** * Creates a new module link.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/services/src/module/link.service.ts` around lines 17 - 21, The JSDoc block describing a constructor and a baseURL parameter is stale after removal of the constructor in ModuleLinkService; remove the orphaned JSDoc (the /** ... */ block referencing the constructor/baseURL) from packages/services/src/module/link.service.ts or replace it with an accurate class-level comment for ModuleLinkService, ensuring there are no remaining `@param` tags for baseURL and no misleading constructor documentation.packages/hooks/src/use-local-storage.tsx (2)
42-46:⚠️ Potential issue | 🟠 MajorMissing SSR guard in
clearValuecallback.Same issue as
setValue- directwindowaccess without SSR guard.🐛 Proposed fix
const clearValue = useCallback(() => { + if (typeof window === "undefined") return; window.localStorage.removeItem(key); setStoredValue(null); window.dispatchEvent(new Event(`local-storage:${key}`)); }, [key]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/hooks/src/use-local-storage.tsx` around lines 42 - 46, The clearValue callback directly accesses window (window.localStorage.removeItem and window.dispatchEvent) causing SSR failures; update the clearValue function (the useCallback that references key and setStoredValue) to first check typeof window !== "undefined" before calling window.localStorage.removeItem or window.dispatchEvent, and still call setStoredValue(null) unconditionally so state updates work on the server; mirror the same SSR guard pattern used in setValue to keep behavior consistent.
33-38:⚠️ Potential issue | 🟠 MajorMissing SSR guard in
setValuecallback.The
setValuefunction directly accesseswindow.localStoragewithout the same SSR guard used ingetValueFromLocalStorageandsetValueIntoLocalStorage. This will throw aReferenceErrorduring server-side rendering.🐛 Proposed fix
const setValue = useCallback( (value: T) => { + if (typeof window === "undefined") return; window.localStorage.setItem(key, JSON.stringify(value)); setStoredValue(value); window.dispatchEvent(new Event(`local-storage:${key}`)); }, [key] );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/hooks/src/use-local-storage.tsx` around lines 33 - 38, The setValue callback in use-local-storage.tsx directly accesses window.localStorage and will throw during SSR; update the setValue function (the useCallback block) to guard access with the same client-side check used in getValueFromLocalStorage and setValueIntoLocalStorage (e.g., if (typeof window === "undefined") return or only call window.localStorage when window exists), ensure setStoredValue(value) still runs on server-safe paths as appropriate, and keep the window.dispatchEvent call behind the same guard so no window access occurs during SSR.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/hooks/src/use-local-storage.tsx`:
- Line 10: The guard in use-local-storage (inside the useLocalStorage hook)
repeats the same check; replace the second duplicate `typeof window ===
"undefined"` with a check for localStorage availability (e.g., `typeof
window.localStorage === "undefined"` or equivalent) so the condition correctly
returns defaultValue when running server-side or when localStorage is
unavailable.
- Line 21: The guard in use-local-storage.tsx currently repeats the same check
twice ("typeof window === 'undefined' || typeof window === 'undefined'"); update
that condition to verify localStorage exists instead (e.g., change the second
check to typeof window.localStorage === 'undefined') so the early return
correctly handles server environments and browsers without localStorage—apply
this change to the guard used in the useLocalStorage/getValueFromLocalStorage
logic.
In `@packages/services/src/module/module.service.ts`:
- Around line 12-14: ModuleService currently extends APIService but omitted a
constructor, causing a TypeScript error because APIService requires a baseURL;
add a constructor on ModuleService that either accepts a baseURL parameter and
calls super(baseURL) or calls super(DEFAULT_API_BASE_URL) (or another
env-derived default) so the base class is properly initialized; update the
ModuleService class declaration to include this constructor and ensure any
callers are adjusted if you choose the required-arg form.
---
Outside diff comments:
In `@packages/hooks/src/use-local-storage.tsx`:
- Around line 42-46: The clearValue callback directly accesses window
(window.localStorage.removeItem and window.dispatchEvent) causing SSR failures;
update the clearValue function (the useCallback that references key and
setStoredValue) to first check typeof window !== "undefined" before calling
window.localStorage.removeItem or window.dispatchEvent, and still call
setStoredValue(null) unconditionally so state updates work on the server; mirror
the same SSR guard pattern used in setValue to keep behavior consistent.
- Around line 33-38: The setValue callback in use-local-storage.tsx directly
accesses window.localStorage and will throw during SSR; update the setValue
function (the useCallback block) to guard access with the same client-side check
used in getValueFromLocalStorage and setValueIntoLocalStorage (e.g., if (typeof
window === "undefined") return or only call window.localStorage when window
exists), ensure setStoredValue(value) still runs on server-safe paths as
appropriate, and keep the window.dispatchEvent call behind the same guard so no
window access occurs during SSR.
In `@packages/services/src/module/link.service.ts`:
- Around line 17-21: The JSDoc block describing a constructor and a baseURL
parameter is stale after removal of the constructor in ModuleLinkService; remove
the orphaned JSDoc (the /** ... */ block referencing the constructor/baseURL)
from packages/services/src/module/link.service.ts or replace it with an accurate
class-level comment for ModuleLinkService, ensuring there are no remaining
`@param` tags for baseURL and no misleading constructor documentation.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (30)
.github/workflows/pull-request-build-lint-web-apps.yml.oxlintrc.jsonAGENTS.mdCONTRIBUTING.mdapps/admin/package.jsonapps/live/package.jsonapps/space/package.jsonapps/web/package.jsondocs/eslint.mddocs/linting.mdeslint.config.mjspackage.jsonpackages/constants/package.jsonpackages/decorators/package.jsonpackages/editor/package.jsonpackages/eslint-config/.prettierignorepackages/hooks/package.jsonpackages/hooks/src/use-local-storage.tsxpackages/i18n/package.jsonpackages/logger/package.jsonpackages/propel/package.jsonpackages/services/package.jsonpackages/services/src/module/link.service.tspackages/services/src/module/module.service.tspackages/services/src/module/operations.service.tspackages/shared-state/package.jsonpackages/types/package.jsonpackages/ui/package.jsonpackages/utils/package.jsonturbo.json
💤 Files with no reviewable changes (3)
- docs/eslint.md
- packages/eslint-config/.prettierignore
- eslint.config.mjs
|
|
||
| export const getValueFromLocalStorage = (key: string, defaultValue: any) => { | ||
| if (typeof window === undefined || typeof window === "undefined") return defaultValue; | ||
| if (typeof window === "undefined" || typeof window === "undefined") return defaultValue; |
There was a problem hiding this comment.
Duplicate condition detected.
The guard typeof window === "undefined" || typeof window === "undefined" repeats the same check twice, which is redundant. This appears to be a copy-paste error.
🐛 Proposed fix
- if (typeof window === "undefined" || typeof window === "undefined") return defaultValue;
+ if (typeof window === "undefined") return defaultValue;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (typeof window === "undefined" || typeof window === "undefined") return defaultValue; | |
| if (typeof window === "undefined") return defaultValue; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/hooks/src/use-local-storage.tsx` at line 10, The guard in
use-local-storage (inside the useLocalStorage hook) repeats the same check;
replace the second duplicate `typeof window === "undefined"` with a check for
localStorage availability (e.g., `typeof window.localStorage === "undefined"` or
equivalent) so the condition correctly returns defaultValue when running
server-side or when localStorage is unavailable.
|
|
||
| export const setValueIntoLocalStorage = (key: string, value: any) => { | ||
| if (typeof window === undefined || typeof window === "undefined") return false; | ||
| if (typeof window === "undefined" || typeof window === "undefined") return false; |
There was a problem hiding this comment.
Same duplicate condition issue.
Same redundant guard here as in getValueFromLocalStorage.
🐛 Proposed fix
- if (typeof window === "undefined" || typeof window === "undefined") return false;
+ if (typeof window === "undefined") return false;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (typeof window === "undefined" || typeof window === "undefined") return false; | |
| if (typeof window === "undefined") return false; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/hooks/src/use-local-storage.tsx` at line 21, The guard in
use-local-storage.tsx currently repeats the same check twice ("typeof window ===
'undefined' || typeof window === 'undefined'"); update that condition to verify
localStorage exists instead (e.g., change the second check to typeof
window.localStorage === 'undefined') so the early return correctly handles
server environments and browsers without localStorage—apply this change to the
guard used in the useLocalStorage/getValueFromLocalStorage logic.
After makeplane#8677 replaced ESLint with OxLint, the react-in-jsx-scope rule was not disabled. This causes all commits touching JSX files to fail the pre-commit hook (oxlint --deny-warnings). React 17+ uses automatic JSX runtime so explicit React imports are not required. Fixes makeplane#8681
Type of Change
Summary by CodeRabbit
Chores
Documentation
Bug Fixes