Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
update eslint to v9
and all related dependencies

Refresh rules config - to avoid breaking changes.
indent rule should work better now - although it's still buggy - there might be reports on code which was not reported before.
The biggest pain point might be that `typeof` does not mark a variable as used by `no-unused-vars` rule - now error is reported. Related thread: typescript-eslint/typescript-eslint#10266
  • Loading branch information
falkenhawk committed Jan 9, 2025
commit 46721a868fc2e8490ee2ce5a88e6593185999424
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ The configuration is based on the recommended rulesets from [ESLint](https://esl

It also includes [ESLint Stylistic](https://eslint.style/) which replaces deprecated rules from eslint and typescript-eslint.

Currently, it uses ESLint v8 and typescript-eslint v6. (nodejs v16.10+ required)
The upgrade to ESLint v9 and typescript-eslint v8 is planned for the next major release.
Currently, it uses ESLint v9 and typescript-eslint v8. (nodejs v18.18+ required)
If you need to use this package on older nodejs v16, you may switch to older v2.x version, which is based on ESLint v8 (nodejs v16.10+ required)


`@ovos-media/coding-standard/eslint` exports a function that accepts an object with the following options:
Expand Down
78 changes: 30 additions & 48 deletions eslint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ type CustomizeOptions = {

// shared settings - for js + ts equivalent rules
const shared: Linter.RulesRecord = {
'no-unused-vars': ['error', { varsIgnorePattern: '^_', args: 'none' }],
'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
'no-unused-vars': ['error', { varsIgnorePattern: '^_', args: 'none', caughtErrors: 'none' }],
};

/**
Expand Down Expand Up @@ -91,7 +92,7 @@ function customize(options: CustomizeOptions = {}) {
parser: tsParser,
parserOptions: {
// https://typescript-eslint.io/packages/parser/
project: true,
projectService: true,
},
},
plugins: {
Expand Down Expand Up @@ -121,7 +122,7 @@ function customize(options: CustomizeOptions = {}) {
'*.setup.ts',
...disableTypeChecked,
],
languageOptions: { parserOptions: { project: null } }, // this is what basically the 'disable-type-checked' config does, when 'recommended-type-checked' is not used
languageOptions: { parserOptions: { projectService: null } }, // this is what basically the 'disable-type-checked' config does, when 'recommended-type-checked' is not used
},
];

Expand All @@ -132,6 +133,7 @@ function customize(options: CustomizeOptions = {}) {
files: ['**/*.?(m|c)js?(x)'],
rules: {
// ** eslint:recommended overrides:
'no-unused-expressions': shared['no-unused-expressions'],
'no-unused-vars': shared['no-unused-vars'],
// ** end eslint:recommended overrides

Expand All @@ -158,10 +160,14 @@ function customize(options: CustomizeOptions = {}) {
'@typescript-eslint/no-explicit-any': 'off',
// allow @ts-ignore
'@typescript-eslint/ban-ts-comment': 'off',
// even though `no-unused-vars` is already reconfigured, this needs to be reconfigured again for typescript files, with the same options repeated
'@typescript-eslint/no-unused-vars': shared['no-unused-vars'],
// we still sometimes want to use dynamic, sync `require()` instead of `await import()`
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-require-imports': 'off',
// allow `interface I extends Base<Param> {}` syntax
'@typescript-eslint/no-empty-object-type': ['error', { allowInterfaces: 'with-single-extends' }],
// even though the rules blow are already reconfigured for eslint:recommended,
// they need to be reconfigured again for typescript files, with the same options repeated
'@typescript-eslint/no-unused-expressions': shared['no-unused-expressions'],
'@typescript-eslint/no-unused-vars': shared['no-unused-vars'],
// ** end typescript-eslint:recommended overrides

// additional rules
Expand Down Expand Up @@ -248,50 +254,30 @@ function customize(options: CustomizeOptions = {}) {
indent,
{
SwitchCase: 1,
// indenting parameters on multiline function calls is sometimes broken
CallExpression: { arguments: 'off' },
// @typescript-eslint/indent is broken and unmaintained,
// but there is no other, better option available at the moment. (except the prettier itself?)
// Eslint cuts ties with stylistic lints while leaving them in broken state
// https://github.com/eslint/eslint/issues/17522
// Maybe it'll be fixed one day at https://github.com/eslint-stylistic/eslint-stylistic/ 🙄
//
// Apply workarounds posted in https://github.com/typescript-eslint/typescript-eslint/issues/1824 et al.
// only enable when 'indent' is 2 spaces, as it's broken otherwise -> https://github.com/eslint-stylistic/eslint-stylistic/issues/514
offsetTernaryExpressions: indent === 2,
ignoredNodes: [
// https://github.com/typescript-eslint/typescript-eslint/issues/1824#issuecomment-1378327382
'PropertyDefinition[decorators]',
'FunctionExpression[params]:has(Identifier[decorators])',
// copied list of ignoredNodes from https://github.com/eslint-stylistic/eslint-stylistic/blob/main/packages/eslint-plugin/configs/customize.ts
// which just disables indent rules for cases not properly supported by the plugin
// (issues have been carried over from the original indent and @typescript-eslint/indent rules
// and now are being addressed occasionally, one by one, in eslint-stylistic)
'TSUnionType',
'TSIntersectionType',
// https://github.com/typescript-eslint/typescript-eslint/issues/1824#issuecomment-943783564
// Generics are not properly indented
'TSTypeParameterInstantiation',
'FunctionExpression > .params[decorators.length > 0]',
'FunctionExpression > .params > :matches(Decorator, :not(:first-child))',
// some more exclusions are needed:
// does not indent multiline interface extends (conflicts with prettier)
'TSInterfaceHeritage',
// checking indentation of multiline ternary expression is broken
// https://github.com/eslint/eslint/issues/14058
'.superTypeArguments',
// multiline generic type parameters in function calls
'CallExpression > .typeArguments',
// checking indentation of multiline ternary expression is broken in some cases (i.a. nested function calls)
'ConditionalExpression *',
// breaking on nested arrow functions
// still breaking on nested (chained) arrow functions () => () => {}
'ArrowFunctionExpression',
// https://stackoverflow.com/questions/52178093/ignore-the-indentation-in-a-template-literal-with-the-eslint-indent-rule
'TemplateLiteral *',
// ignore jsx indentation - copied from https://github.com/eslint-stylistic/eslint-stylistic/blob/main/packages/eslint-plugin/configs/customize.ts
// use jsx-indent rule instead
'JSXElement',
'JSXElement > *',
'JSXAttribute',
'JSXIdentifier',
'JSXNamespacedName',
'JSXMemberExpression',
'JSXSpreadAttribute',
'JSXExpressionContainer',
'JSXOpeningElement',
'JSXClosingElement',
'JSXFragment',
'JSXOpeningFragment',
'JSXClosingFragment',
'JSXText',
'JSXEmptyExpression',
'JSXSpreadChild',
'TemplateLiteral *', // even after some fixes in @stylistic, still not handling multiline expressions in template literals properly
],
},
],
Expand Down Expand Up @@ -390,10 +376,7 @@ function customize(options: CustomizeOptions = {}) {
rules: {
// allow i.a. `type Props = {}` in react components
// https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492
'@typescript-eslint/ban-types': [
'error',
{ extendDefaults: true, types: { '{}': false } },
],
'@typescript-eslint/no-empty-object-type': ['error', { allowWithName: 'Props$' }],
},
},
// our rules and overrides (react 2/2: jsx+tsx)
Expand Down Expand Up @@ -429,7 +412,6 @@ function customize(options: CustomizeOptions = {}) {
'@stylistic/jsx-equals-spacing': 'error',
'@stylistic/jsx-first-prop-new-line': 'error',
'@stylistic/jsx-function-call-newline': 'error',
'@stylistic/jsx-indent': ['error', indent],
'@stylistic/jsx-indent-props': ['error', indent],
'@stylistic/jsx-props-no-multi-spaces': 'error',
'@stylistic/jsx-quotes': 'error',
Expand Down Expand Up @@ -540,7 +522,7 @@ function customize(options: CustomizeOptions = {}) {
}

if (vitest) {
const vitestPlugin = require('eslint-plugin-vitest');
const vitestPlugin = require('@vitest/eslint-plugin');
config.push({
name: 'vitest',
files: [
Expand Down
47 changes: 23 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ovos-media/coding-standard",
"version": "2.0.2",
"version": "3.0.0-rc.0",
"description": "ovos-media coding standard",
"main": "index.js",
"types": "index.d.ts",
Expand All @@ -9,35 +9,34 @@
"repository": "https://github.com/ovos/coding-standard",
"homepage": "https://github.com/ovos/coding-standard",
"scripts": {
"prepublish": "yarn run build",
"lint": "yarn run eslint .",
"build": "tsc -p ./tsconfig.json",
"release": "standard-version"
"prepublish": "yarn build",
"lint": "eslint .",
"build": "tsc -p ./tsconfig.json"
},
"dependencies": {
"@stylistic/eslint-plugin": "^1.8.1",
"@types/eslint": "8.56.10",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"eslint": "^8.57.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-check-file": "2.6.2",
"eslint-plugin-cypress": "^3.3.0",
"eslint-plugin-import": "npm:[email protected]",
"eslint-plugin-jest": "28.4.0",
"eslint-plugin-mocha": "^10.4.3",
"eslint-plugin-react": "^7.34.2",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-vitest": "0.3.10",
"globals": "^13.24.0"
"@stylistic/eslint-plugin": "^2.12.1",
"@types/eslint": "^9.6.1",
"@typescript-eslint/eslint-plugin": "^8.19.1",
"@typescript-eslint/parser": "^8.19.1",
"@typescript-eslint/utils": "^8.19.1",
"@vitest/eslint-plugin": "^1.1.24",
"eslint": "^9.17.0",
"eslint-import-resolver-typescript": "^3.7.0",
"eslint-plugin-check-file": "^2.8.0",
"eslint-plugin-cypress": "^4.1.0",
"eslint-plugin-import": "npm:eslint-plugin-import-x@^4.6.1",
"eslint-plugin-jest": "^28.10.0",
"eslint-plugin-mocha": "^10.5.0",
"eslint-plugin-react": "^7.37.3",
"eslint-plugin-react-hooks": "^5.1.0",
"globals": "^15.14.0"
},
"devDependencies": {
"@types/eslint-plugin-mocha": "10.4.0",
"@types/eslint__js": "8.42.3",
"@types/node": "20.14.1",
"@types/node": "20.17.10",
"@types/prettier": "3.0.0",
"prettier": "3.3.0",
"typescript": "5.4.5"
"prettier": "3.4.2",
"typescript": "5.7.2"
},
"engines": {
"node": ">=16.10"
Expand Down