Skip to content

Commit

Permalink
Merge pull request #440 from espoon-voltti/frontend-eslint-upgrade
Browse files Browse the repository at this point in the history
Upgrade frontend eslint to v9
  • Loading branch information
juhenius authored Nov 28, 2024
2 parents 2b3d0c6 + c295942 commit efa52b7
Show file tree
Hide file tree
Showing 10 changed files with 626 additions and 401 deletions.
1 change: 1 addition & 0 deletions frontend/.dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
!*.js
!*.json
!*.lock
!*.mjs
2 changes: 1 addition & 1 deletion frontend/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function serve() {
const middleware = express.static(outdir)

app.use('/', middleware)
app.get(`/*`, (req, res, next) => {
app.get(`/*`, (req, _res, next) => {
req.url = `index.html`
next()
})
Expand Down
140 changes: 140 additions & 0 deletions frontend/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// SPDX-FileCopyrightText: 2017-2024 City of Espoo
//
// SPDX-License-Identifier: LGPL-2.1-or-later

import { fixupPluginRules } from '@eslint/compat'
import eslint from '@eslint/js'
import importPlugin from 'eslint-plugin-import'
import jsxExpressionsPlugin from 'eslint-plugin-jsx-expressions'
import lodashPlugin from 'eslint-plugin-lodash'
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
import reactPlugin from 'eslint-plugin-react'
import reactHooksPlugin from 'eslint-plugin-react-hooks'
import globals from 'globals'
import typescriptEslint from 'typescript-eslint'

export default [
{ ignores: ['.yarn', 'dist'] },
eslint.configs.recommended,
...typescriptEslint.configs.recommendedTypeChecked,
...typescriptEslint.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
globals: globals.browser
}
}
},
{
files: ['**/*.{js,mjs}'],
...typescriptEslint.configs.disableTypeChecked
},
{
plugins: {
import: importPlugin
}
},
importPlugin.flatConfigs.typescript,
{
files: ['**/*.{ts,tsx,js,mjs}'],
rules: {
'import/order': [
'warn',
{
alphabetize: { order: 'asc' },
groups: [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index'
],
'newlines-between': 'always'
}
],
'no-console': ['error', { allow: ['warn', 'error'] }],
'prefer-arrow-callback': ['error', { allowNamedFunctions: true }],
'arrow-body-style': ['error', 'as-needed'],
'no-constant-binary-expression': ['error']
}
},
{
files: ['**/*.{ts,tsx,js,mjs}'],
rules: {
'@typescript-eslint/no-unused-vars': [
'warn',
{
args: 'all',
argsIgnorePattern: '^_',
caughtErrors: 'all',
caughtErrorsIgnorePattern: '^.*',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true
}
]
}
},
{
files: ['**/*.{ts,tsx}'],
plugins: {
react: reactPlugin,
'react-hooks': reactHooksPlugin,
'jsx-expressions': fixupPluginRules(jsxExpressionsPlugin)
},
settings: {
react: { version: 'detect' }
},
rules: {
...reactPlugin.configs.recommended.rules,
...reactHooksPlugin.configs.recommended.rules,
'react/jsx-curly-brace-presence': ['error', 'never'],
'react/prop-types': 'off',
'react/self-closing-comp': ['error', { component: true, html: true }],
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'jsx-expressions/strict-logical-expressions': 'error',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-empty-object-type': [
'error',
{ allowInterfaces: 'always' }
],
'@typescript-eslint/no-misused-promises': [
'error',
{ checksVoidReturn: false }
],
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'off'
}
},
{
files: ['**/*.{js,mjs}'],
languageOptions: {
globals: globals.node
},
rules: {
'@typescript-eslint/no-var-requires': 'off'
}
},
{
files: ['**/*.js'],
rules: {
'@typescript-eslint/no-require-imports': 'off'
}
},
{
// Only files that end up in the bundles
files: ['src/**/*.{ts,tsx,js,mjs}'],
plugins: {
lodash: fixupPluginRules(lodashPlugin)
},
rules: {
'lodash/import-scope': ['error', 'method']
}
},
eslintPluginPrettierRecommended
]
145 changes: 10 additions & 135 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"clean": "rm -rf dist node_modules/.cache",
"dev": "concurrently -n tsc,esbuild -c blue,green 'yarn type-check:watch' 'yarn build:serve'",
"lint": "eslint --ext .js,.jsx,.ts,.tsx --max-warnings 0 .",
"lint": "eslint --max-warnings 0 .",
"type-check": "tsc --build --force .",
"type-check:watch": "yarn type-check --watch --preserveWatchOutput",
"build": "node build.js",
Expand All @@ -33,6 +33,7 @@
"devDependencies": {
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@eslint/compat": "^1.2.3",
"@types/autosize": "^4.0.3",
"@types/lodash": "^4.17.12",
"@types/node": "^22.9.3",
Expand All @@ -41,26 +42,28 @@
"@types/react-dom": "^18.3.1",
"@types/react-router-dom": "^5.3.3",
"@types/styled-components": "^5.1.34",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"@typescript-eslint/eslint-plugin": "^8.16.0",
"@typescript-eslint/parser": "^8.15.0",
"axios": "^1.7.7",
"concurrently": "^9.1.0",
"esbuild": "^0.24.0",
"eslint": "^8.57.1",
"eslint": "^9.15.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-lodash": "^7.4.0",
"eslint-plugin-jsx-expressions": "^1.3.2",
"eslint-plugin-lodash": "^8.0.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-promise": "^6.6.0",
"eslint-plugin-promise": "^7.1.0",
"eslint-plugin-react": "^7.37.1",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-hooks": "^5.0.0",
"express": "^4.21.1",
"express-http-proxy": "^2.1.1",
"postcss": "^8.4.47",
"postcss-preset-env": "^10.1.1",
"prettier": "^3.3.3",
"ts-node": "^10.9.2",
"typescript": "~5.7.2",
"typescript-eslint": "^8.16.0",
"yargs": "^17.7.2"
},
"engines": {
Expand All @@ -77,133 +80,5 @@
"postcss-preset-env": true
}
},
"eslintConfig": {
"ignorePatterns": [
"**/dist"
],
"parserOptions": {
"ecmaVersion": "latest",
"ecmaFeatures": {
"jsx": true
}
},
"env": {
"browser": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:prettier/recommended",
"plugin:react-hooks/recommended"
],
"plugins": [
"import",
"react-hooks",
"lodash"
],
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"import/order": [
"warn",
{
"alphabetize": {
"order": "asc"
},
"groups": [
"builtin",
"external",
"internal",
"parent",
"sibling",
"index"
],
"newlines-between": "always"
}
],
"react/jsx-curly-brace-presence": [
"error",
"never"
],
"react/prop-types": "off",
"react/self-closing-comp": [
"error",
{
"component": true,
"html": true
}
],
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"no-console": [
"error",
{
"allow": [
"warn",
"error"
]
}
],
"prefer-arrow-callback": [
"error",
{
"allowNamedFunctions": true
}
],
"arrow-body-style": [
"error",
"as-needed"
]
},
"overrides": [
{
"files": "**/*.{ts,tsx}",
"extends": [
"plugin:@typescript-eslint/recommended-type-checked",
"plugin:@typescript-eslint/stylistic-type-checked"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.eslint.json"
},
"plugins": [
"@typescript-eslint",
"react-hooks"
],
"rules": {
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksVoidReturn": false
}
],
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
],
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/prefer-nullish-coalescing": "off",
"@typescript-eslint/prefer-optional-chain": "off",
"@typescript-eslint/no-var-requires": "off"
}
},
{
"files": "src/**/*.{js,jsx,ts,tsx}",
"rules": {
"lodash/import-scope": [
"error",
"method"
]
}
}
]
},
"packageManager": "[email protected]"
}
1 change: 1 addition & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { StudentPage } from './students/StudentPage'
import { StudentSearchProvider } from './students/StudentSearchContext'
import { StudentsSearchPage } from './students/StudentsSearchPage'

// eslint-disable-next-line @typescript-eslint/no-require-imports
const EspooLogo = require('./images/EspooLogoPrimary.svg') as string

const Header = styled.nav`
Expand Down
1 change: 0 additions & 1 deletion frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ import './index.css'
import './fonts/fonts.css'
import { appRouter } from './App'

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const root = createRoot(document.getElementById('app')!)
root.render(<RouterProvider router={appRouter} />)
2 changes: 1 addition & 1 deletion frontend/src/shared/api-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ export type JsonOf<T> = T extends string | number | boolean | null | undefined
? JsonOf<U>[]
: T extends (infer U)[]
? JsonOf<U>[]
: T extends object // eslint-disable-line @typescript-eslint/ban-types
: T extends object
? { [P in keyof T]: JsonOf<T[P]> }
: never
2 changes: 1 addition & 1 deletion frontend/src/shared/form/InputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ export const InputField = React.memo(function InputField({
onFocus={onFocus}
onBlur={(e) => {
setTouched(true)
onBlur && onBlur(e)
if (onBlur) onBlur(e)
}}
placeholder={placeholder}
readOnly={readonly}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/shared/form/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const TextArea = React.memo(function TextArea({
onFocus={onFocus}
onBlur={(e) => {
setTouched(true)
onBlur && onBlur(e)
if (onBlur) onBlur(e)
}}
placeholder={placeholder}
readOnly={readonly}
Expand Down Expand Up @@ -143,7 +143,7 @@ const TextareaAutosize = React.memo(function TextAreaAutosize({
}, [])

useEffect(() => {
textarea.current && autosize.update(textarea.current)
if (textarea.current) autosize.update(textarea.current)
})

return (
Expand Down
Loading

0 comments on commit efa52b7

Please sign in to comment.