-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🔧 Migrate to ESLint v9 #3993
base: master
Are you sure you want to change the base?
🔧 Migrate to ESLint v9 #3993
Conversation
✅ Deploy Preview for actualbudget ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
Bundle Stats — desktop-clientHey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle. As this PR is updated, I'll keep you updated on how the bundle size is impacted. Total
Changeset
View detailed bundle breakdownAdded No assets were added Removed No assets were removed Bigger
Smaller
Unchanged
|
Bundle Stats — loot-coreHey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle. As this PR is updated, I'll keep you updated on how the bundle size is impacted. Total
Changeset
View detailed bundle breakdownAdded No assets were added Removed No assets were removed Bigger No assets were bigger Smaller No assets were smaller Unchanged
|
WalkthroughThis pull request introduces a comprehensive update to the project's ESLint configuration and linting strategy. The changes involve removing the existing The modifications span multiple packages, including updates to dependency versions for ESLint-related plugins and tools. The new ESLint configuration provides more granular control over linting rules, with specific settings for JavaScript, TypeScript, React, and accessibility. The configuration aims to enforce consistent coding standards across the project while providing flexibility for different file types and directories. Alongside the ESLint changes, the pull request includes various minor updates across different packages, such as modifications to type definitions, build configurations, and utility functions. These changes reflect an ongoing effort to improve code quality, maintainability, and consistency throughout the project. The update also involves simplifying linting commands, updating dependency versions, and removing some legacy configuration elements like strict mode directives in various files. Possibly related PRs
Suggested labels
Suggested reviewers
Tip CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🔭 Outside diff range comments (3)
packages/desktop-client/src/browser-preload.browser.js (3)
Line range hint
39-57
: Enhance service worker update handlingThe current implementation lacks error handling and user feedback for service worker updates.
Consider this enhancement:
let isUpdateReadyForDownload = false; let markUpdateReadyForDownload; const isUpdateReadyForDownloadPromise = new Promise(resolve => { markUpdateReadyForDownload = () => { isUpdateReadyForDownload = true; resolve(true); }; }); const updateSW = registerSW({ immediate: true, onNeedRefresh: markUpdateReadyForDownload, + onRegistered(registration) { + console.log('SW registered:', registration); + }, + onRegisterError(error) { + console.error('SW registration error:', error); + }, });
Line range hint
82-134
: Enhance file handling securityThe current file handling implementation could benefit from additional security measures.
Consider these security enhancements:
openFileDialog: async ({ filters = [] }) => { return new Promise(resolve => { let createdElement = false; let input = document.body.querySelector( 'input[id="open-file-dialog-input"]', ); if (!input) { createdElement = true; input = document.createElement('input'); } input.type = 'file'; input.id = 'open-file-dialog-input'; input.value = null; const filter = filters.find(filter => filter.extensions); if (filter) { input.accept = filter.extensions.map(ext => '.' + ext).join(','); } + // Validate file size + const MAX_FILE_SIZE = 50 * 1024 * 1024; // 50MB input.onchange = e => { const file = e.target.files[0]; + if (file.size > MAX_FILE_SIZE) { + alert('File size exceeds maximum limit'); + return; + } const filename = file.name.replace(/.*(\.[^.]*)/, 'file$1'); if (file) { const reader = new FileReader(); reader.readAsArrayBuffer(file); reader.onload = async function (ev) { const filepath = `/uploads/${filename}`; + // Validate file type + const validTypes = new Set(['text/csv', 'application/json']); + if (!validTypes.has(file.type)) { + alert('Invalid file type'); + return; + } window.__actionsForMenu .uploadFile(filename, ev.target.result) .then(() => resolve([filepath])); };
Line range hint
169-173
: Improve app update implementationThe current implementation of
applyAppUpdate
creates an unresolved promise.Fix the implementation:
applyAppUpdate: async () => { - updateSW(); - // Wait for the app to reload - await new Promise(() => {}); + try { + await updateSW(); + window.location.reload(); + } catch (error) { + console.error('Failed to apply update:', error); + throw error; + } },
🧹 Nitpick comments (14)
eslint.config.mjs (3)
680-680
: Consider Re-enabling 'import/no-unused-modules' When StableThe rule
'import/no-unused-modules'
is currently disabled due to crashing issues. Once the underlying issue is resolved, consider re-enabling it to help identify and remove unused modules, improving code cleanliness.
464-468
: Plan to Re-enable Temporarily Disabled RulesThe following rules are currently disabled with a TODO comment to re-enable them:
'react/react-in-jsx-scope': 'off'
'no-var': 'warn'
'react/jsx-curly-brace-presence': 'warn'
'object-shorthand': ['warn', 'properties']
Ensure to revisit and re-enable these rules to maintain code quality and consistency.
516-521
: Review Disabled TypeScript Rules Post-MigrationThe TypeScript-specific rules are disabled during the migration:
'@typescript-eslint/no-var-requires': 'off'
'@typescript-eslint/no-empty-function': 'off'
'@typescript-eslint/no-require-imports': 'off'
After completing the TypeScript migration, consider re-enabling these rules to enforce best practices in TypeScript code.
packages/desktop-client/src/build-shims.js (1)
11-12
: Remove Redundant Export of 'process'Since the focus has shifted to exporting
global
, the export ofprocess
may be redundant. Ifprocess
is no longer used elsewhere, consider removing it to clean up the exports.Apply this diff to remove the redundant export:
export { process }; export { global };packages/loot-core/peg-transform.mjs (1)
9-9
: Simplify Unused Variable SuppressionInstead of using an eslint-disable comment, you can prefix the unused parameter with an underscore to indicate it's intentionally unused, which suppresses the linter warning without additional comments.
Apply this diff:
-// eslint-disable-next-line @typescript-eslint/no-unused-vars process(sourceText, sourcePath, _options) {
packages/api/index.ts (2)
11-12
: Consider consolidating ESLint directivesMultiple ESLint disable directives could be combined. Also, the import resolution issues should be addressed in the ESLint config.
-// eslint-disable-next-line import/extensions, import/no-unresolved +/* eslint-disable import/extensions, import/no-unresolved */ import * as bundle from './app/bundle.api.js'; +/* eslint-enable import/extensions, import/no-unresolved */
Line range hint
19-21
: Plan removal of deprecated exportThe comment indicates this export should be removed in v7. Consider:
- Creating a tracking issue for this removal
- Adding a proper deprecation warning using
console.warn
Would you like me to create a GitHub issue to track the removal of this deprecated export?
packages/desktop-client/playwright.config.js (1)
Line range hint
1-1
: Consider implementing a comprehensive module resolution strategyTo address the recurring module resolution issues across multiple files, consider:
- Implementing a consistent module alias system
- Configuring ESLint's import resolver plugins
- Aligning TypeScript and ESLint path configurations
Example configuration for the new ESLint flat config:
import { glob } from 'glob'; import path from 'path'; const tsConfig = glob.sync('**/tsconfig.json').map(file => ({ name: path.dirname(file), path: file })); export default [{ plugins: { '@typescript-eslint': tsPlugin, 'import': importPlugin }, settings: { 'import/resolver': { typescript: { project: tsConfig } } } }];packages/loot-core/src/types/server-handlers.d.ts (1)
21-21
: Consider fixing the module resolution instead of disabling ESLint.While the ESLint disable directive works as a temporary solution, it would be better to properly configure the module resolution in your TypeScript and ESLint configuration. This ensures better maintainability and type safety.
Consider:
- Adding proper path aliases in
tsconfig.json
- Configuring ESLint's import resolver to understand your project structure
- Using proper relative paths if the module is within the same package
-// eslint-disable-next-line import/no-unresolved -import { Query } from './query'; +import { Query } from '../shared/query';packages/loot-core/src/server/main.ts (1)
Line range hint
1-2412
: Consider breaking down this large file for better maintainability.The file is quite large and handles multiple concerns. Consider splitting it into smaller, focused modules:
- Handler definitions
- Initialization logic
- Cloud storage operations
- Budget operations
This would improve:
- Code maintainability
- Testing capabilities
- Code reusability
- Error handling consistency
packages/desktop-client/vite.config.mts (4)
69-69
: Consider removing empty line 69This empty line appears to be unnecessary and doesn't contribute to code readability.
Line range hint
71-82
: Consider enhancing environment variable validationWhile the environment loading looks correct, consider adding validation for required environment variables to fail fast if critical configurations are missing.
Example enhancement:
export default defineConfig(async ({ mode }) => { const env = loadEnv(mode, process.cwd(), ''); + const requiredEnvVars = []; + const missingEnvVars = requiredEnvVars.filter(key => !env[key]); + if (missingEnvVars.length > 0) { + throw new Error(`Missing required environment variables: ${missingEnvVars.join(', ')}`); + } const devHeaders = { 'Cross-Origin-Opener-Policy': 'same-origin', 'Cross-Origin-Embedder-Policy': 'require-corp', };
Line range hint
143-157
: Consider enhancing PWA caching strategiesThe current PWA configuration is basic. Consider adding more specific caching strategies for different types of assets to optimize performance.
Example enhancement:
VitePWA({ registerType: 'prompt', workbox: { globPatterns: [ '**/*.{js,css,html,txt,wasm,sql,sqlite,ico,png,woff2,webmanifest}', ], ignoreURLParametersMatching: [/^v$/], + runtimeCaching: [ + { + urlPattern: /^https:\/\/api\./i, + handler: 'NetworkFirst', + options: { + cacheName: 'api-cache', + expiration: { + maxEntries: 100, + maxAgeSeconds: 60 * 60 * 24, // 24 hours + }, + }, + }, + ], }, }),
Line range hint
108-134
: Consider adding build optimization configurationsThe build configuration could benefit from additional optimizations for production builds.
Example enhancement:
build: { target: 'es2022', sourcemap: true, outDir: mode === 'desktop' ? 'build-electron' : 'build', assetsDir: 'static', manifest: true, assetsInlineLimit: 0, chunkSizeWarningLimit: 1500, + minify: 'terser', + terserOptions: { + compress: { + drop_console: mode === 'production', + drop_debugger: mode === 'production', + }, + }, rollupOptions: {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
upcoming-release-notes/3993.md
is excluded by!**/*.md
yarn.lock
is excluded by!**/yarn.lock
,!**/*.lock
📒 Files selected for processing (25)
.eslintignore
(0 hunks).eslintrc.js
(0 hunks)eslint.config.mjs
(1 hunks)package.json
(1 hunks)packages/api/index.ts
(1 hunks)packages/desktop-client/globals.d.ts
(1 hunks)packages/desktop-client/playwright.config.js
(1 hunks)packages/desktop-client/src/browser-preload.browser.js
(1 hunks)packages/desktop-client/src/build-shims.js
(1 hunks)packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx
(0 hunks)packages/desktop-client/vite.config.mts
(1 hunks)packages/desktop-electron/beforePackHook.ts
(1 hunks)packages/eslint-plugin-actual/.eslintrc.js
(0 hunks)packages/eslint-plugin-actual/lib/rules/__tests__/prefer-if-statement.js
(0 hunks)packages/eslint-plugin-actual/lib/rules/__tests__/typography.js
(0 hunks)packages/eslint-plugin-actual/lib/rules/prefer-if-statement.js
(0 hunks)packages/eslint-plugin-actual/lib/rules/typography.js
(0 hunks)packages/loot-core/peg-transform.mjs
(1 hunks)packages/loot-core/src/platform/client/undo/index.d.ts
(1 hunks)packages/loot-core/src/server/accounts/payees.ts
(0 hunks)packages/loot-core/src/server/importers/ynab4-types.d.ts
(0 hunks)packages/loot-core/src/server/importers/ynab5-types.d.ts
(0 hunks)packages/loot-core/src/server/main.ts
(1 hunks)packages/loot-core/src/shared/environment.ts
(0 hunks)packages/loot-core/src/types/server-handlers.d.ts
(1 hunks)
💤 Files with no reviewable changes (12)
- packages/loot-core/src/server/importers/ynab5-types.d.ts
- packages/loot-core/src/shared/environment.ts
- packages/eslint-plugin-actual/.eslintrc.js
- packages/eslint-plugin-actual/lib/rules/tests/typography.js
- packages/loot-core/src/server/importers/ynab4-types.d.ts
- .eslintignore
- packages/eslint-plugin-actual/lib/rules/tests/prefer-if-statement.js
- packages/eslint-plugin-actual/lib/rules/typography.js
- packages/eslint-plugin-actual/lib/rules/prefer-if-statement.js
- .eslintrc.js
- packages/loot-core/src/server/accounts/payees.ts
- packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx
✅ Files skipped from review due to trivial changes (1)
- packages/desktop-electron/beforePackHook.ts
🔇 Additional comments (9)
eslint.config.mjs (1)
525-541
: Verify TypeScript Parser Configuration
Ensure that the TypeScript parser is correctly configured with the appropriate tsconfig.json
paths. Incorrect paths may lead to unexpected linting behavior or rules not being applied properly.
Run the following script to check the existence of tsconfig.json
:
✅ Verification successful
Let me verify the content of the tsconfig.json file to ensure it's properly configured for the ESLint setup.
TypeScript Configuration is Valid
The TypeScript configuration is correctly set up. The tsconfig.json
exists at the root and contains appropriate compiler options for ESLint integration, including:
- Proper module resolution (
moduleResolution: "Node10"
) - JSX support (
jsx: "preserve"
) - Correct include/exclude patterns for the monorepo structure
- Essential compiler options for type checking
The path in the ESLint config (./tsconfig.json
) correctly points to this file.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that tsconfig.json exists at the specified path.
# Test: Check if tsconfig.json exists. Expect: File exists.
CONFIG_PATH="$(pwd)/tsconfig.json"
if [ -f "$CONFIG_PATH" ]; then
echo "tsconfig.json found at $CONFIG_PATH"
else
echo "tsconfig.json not found at $CONFIG_PATH"
fi
Length of output: 220
Script:
#!/bin/bash
# Check the content of tsconfig.json and look for essential compiler options
cat tsconfig.json
# Also check for any other tsconfig files that might be present
fd tsconfig.json
Length of output: 1504
packages/desktop-client/globals.d.ts (1)
1-1
:
Avoid Deep Import from '@emotion/css'
Importing CSSObject
from an internal path can lead to module resolution errors. Instead, import directly from the package root to improve compatibility and prevent potential issues.
Apply this diff to adjust the import:
-import { type CSSObject } from '@emotion/css/dist/declarations/src/create-instance';
+import { type CSSObject } from '@emotion/css';
Likely invalid or redundant comment.
packages/loot-core/src/platform/client/undo/index.d.ts (2)
Line range hint 4-30
: LGTM! Well-structured type definitions
The type definitions are well-organized with:
- Clear type structure for
UndoState
- Proper generic constraints for type safety
- Consistent type alias exports for function types
1-2
: Consider fixing the module resolution for modals import
The ESLint disable directive is addressing a known issue mentioned in the PR objectives. Instead of disabling the rule, consider:
- Adding the path to
tsconfig.json
paths configuration - Using a module alias resolver in the ESLint config
✅ Verification successful
Import path is correctly configured, ESLint directive can be removed
The import path ../../client/state-types/modals
is actually valid and properly configured in the project's TypeScript setup. The root tsconfig.json
has a path alias configuration that maps loot-core/*
to ./packages/loot-core/src/*
, and the codebase consistently uses this pattern. The ESLint disable directive is unnecessary as the import resolution works correctly.
- Remove the ESLint disable directive from line 1
- The import can be kept as is, or optionally refactored to use the aliased path:
loot-core/src/client/state-types/modals
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if the module path exists and is properly configured
fd -t f "modals.(ts|d.ts)" -x echo "Found potential module at: {}"
# Verify tsconfig paths configuration
fd -t f "tsconfig.*json" -x cat {} | jq -r '.compilerOptions.paths // empty'
Length of output: 523
Script:
#!/bin/bash
# Let's check the actual content of tsconfig files
fd -t f "tsconfig.*json" -x echo "=== Content of {}" \; -x cat {}
# Check the actual import usage in the codebase
rg -g "*.ts" -g "*.tsx" "from '.*modals'" -A 1
Length of output: 6971
packages/desktop-client/playwright.config.js (1)
66-66
: LGTM! Properly scoped ESLint directive
The ESLint directive is correctly focused on the specific rule needed for the default export, which is a common pattern in configuration files.
package.json (2)
41-42
: LGTM: Simplified lint command and added verbose mode
The simplified lint command aligns with ESLint v9's improved file extension handling. The addition of verbose mode will help debug configuration issues.
48-67
: Verify compatibility between ESLint v9 and related plugins
The major version bump of ESLint (v8 to v9) along with updates to related packages requires careful verification:
- ESLint v9 with typescript-eslint v8
- ESLint v9 with eslint-plugin-react v7
- ESLint v9 with eslint-plugin-import v2
✅ Verification successful
The previous command had issues with the output being too large. Let's try a more focused approach to check ESLint configuration and verify the compatibility requirements.
Let's try to find the ESLint configuration to verify the compatibility requirements between ESLint v9 and the plugins.
Let's try one more time to locate any ESLint configuration files that might be hidden in subdirectories or have different naming patterns.
We found a reference to a root ESLint config file in the plugin's configuration. Let's check both the root config and the plugin's package.json to understand the version compatibility requirements.
ESLint v9 upgrade appears compatible with current plugin setup
The ESLint upgrade to v9 should be compatible with the current setup:
- The local
eslint-plugin-actual
only requireseslint: ">=7"
in its peerDependencies, which is satisfied by v9 - The updated external plugins in package.json are all recent versions that support ESLint v9:
- typescript-eslint v8.x
- eslint-plugin-react v7.x
- eslint-plugin-import v2.x
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for known compatibility issues between ESLint v9 and plugins
# Check package.json files in the repository for potential conflicts
echo "Checking for potential plugin conflicts..."
rg -l '"eslint":|"@typescript-eslint|"eslint-plugin' | xargs cat
Length of output: 69143
Script:
#!/bin/bash
# Check for ESLint configuration files to verify plugin compatibility
echo "Checking ESLint configuration files..."
fd -e js -e json -e yaml -e yml -g '*eslint*' --exec cat {}
# Check for any TypeScript configuration that might affect ESLint
echo -e "\nChecking TypeScript configuration..."
fd -g 'tsconfig*.json' --exec cat {}
Length of output: 3365
Script:
#!/bin/bash
# Let's check for the actual ESLint configuration file at the root
echo "Checking root .eslintrc file..."
cat .eslintrc.js || cat .eslintrc.json || cat .eslintrc.yaml || cat .eslintrc.yml || cat .eslintrc
# Also check for any ESLint extends or plugin configurations in package.json
echo -e "\nChecking package.json for ESLint configuration..."
fd -g 'package.json' -x jq -r '.eslintConfig' {} 2>/dev/null
Length of output: 595
Script:
#!/bin/bash
# Search for any ESLint config files in the entire repository
echo "Searching for ESLint config files recursively..."
fd -H -t f -e js -e json -e yaml -e yml -g '*.eslint*' -x echo "Found: {}" \; -x cat {}
# Check for any ESLint related files in the root config directory
echo -e "\nChecking config directory..."
fd -t f -g '*eslint*' config/ -x echo "Found: {}" \; -x cat {} 2>/dev/null
Length of output: 790
Script:
#!/bin/bash
# The eslint plugin config extends from root config, let's check for it
echo "Checking for root ESLint config..."
cat ./.eslintrc.js
# Let's also check the actual version compatibility requirements in the eslint plugin's package.json
echo -e "\nChecking ESLint plugin package.json..."
cat ./packages/eslint-plugin-actual/package.json
Length of output: 730
packages/loot-core/src/server/main.ts (1)
Line range hint 2395-2412
: Great improvement in type safety! 👍
The addition of proper TypeScript generics to the send
function improves type checking and provides better IDE support. The implementation correctly preserves the handler's parameter and return types.
packages/desktop-client/src/browser-preload.browser.js (1)
1-3
: Address ESLint module resolution warning
The PR objectives mention an unresolved module error for 'virtual:pwa-register'. This needs to be addressed in the ESLint configuration.
Let's verify the module resolution configuration:
I'm having some trouble getting the tests for |
This is quite a big change diff wise, it took /far/ too long to get the new flat config format to work.
Unfortunately, I can not get the below rule to work. When enabled, ESLint crashes completely, with very little in the way of useful logging.
I also fixed some strict usage that it was complaining about in the custom rule package.
These errors are new in this new config. I've ignored them, but if you can see better fixes please shout.