mightyiam/eslint-config-love

Switch to Flat Config Format

Closed this issue ยท 12 comments

I saw in this commit in eslint-config-standard that the repo has been switched over to the new ESLint flat config format. It'd be cool if this repo could be switched over as well. ๐Ÿ™‚

We'd love to do that but I don't yet have npm publish permission for eslint-config-standard or any package other than this one.

Ah, gotcha. Thanks for the clarification. ๐Ÿ™‚

Just out of curiosity, when you do get to that point, were you thinking of using the new cascade so eslint-config-standard would apply to JavaScript files and eslint-config-standard-with-typescript would apply to TypeScript files? Something like this?

[
  {
    ...eslintConfigStandard,
    files: ["*.js", "*.jsx", "*.cjs", "*.msj"]
  },
  {
    ...eslintConfigStandardWithTypeScript,
    files: ["*.ts", "*.tsx"]
  }
]

I'm thinking of leaving setting file patterns to the user.

As a workaround :

import { FlatCompat } from '@eslint/eslintrc'
const compat = new FlatCompat()
export default [
  ...compat.extends('standard-with-typescript'),
]

See https://eslint.org/docs/latest/use/configure/migration-guide#using-eslintrc-configs-in-flat-config

Note also that, related to this, this statement is out-of-date:

Yes, this is a large number of peerDependencies. This is due to eslint/eslint#3458.

With #1498 this is right around the corner!

How should I import eslint-config-love into eslint.config.js?

This is file, I don't think writing love works.

import pluginVue from 'eslint-plugin-vue'
import globals from 'globals'

import { FlatCompat } from '@eslint/eslintrc'
import pluginJs from '@eslint/js'
import tseslint from 'typescript-eslint'

import path from 'path'
import { fileURLToPath } from 'url'

// mimic CommonJS variables -- not needed if using CommonJS
const _filename = fileURLToPath(import.meta.url)
const _dirname = path.dirname(_filename)
const compat = new FlatCompat({ baseDirectory: _dirname, recommendedConfig: pluginJs.configs.recommended, allConfig: pluginJs.configs.all })

export default [
  {
    languageOptions: {
      globals: {
        __statics: 'readonly',
        __QUASAR_SSR__: 'readonly',
        __QUASAR_SSR_SERVER__: 'readonly',
        __QUASAR_SSR_CLIENT__: 'readonly',
        __QUASAR_SSR_PWA__: 'readonly',
        ...globals.browser
      },
      parserOptions: {
        extraFileExtensions: ['.vue']
      }
    },
    ignores: [
      'dist/*',
      '.quasar/*',
      'node_modules/*',
      'src-capacitor/*',
      'src-cordova/*',
      'src-electron/*',
      'quasar.config.*.temporary.compiled*'
    ]
  },
  ...compat.extends('prettier', 'love'),
  ...pluginVue.configs['flat/recommended'],
  ...tseslint.configs.recommended
]



eslint --debug . --fix --ignore-pattern '.quasar/*'


eslintrc:config-array-factory Loading {extends:"love"} relative to  +2ms
  eslintrc:config-array-factory Loaded: eslint-config-love@47.0.0 (G:\Roboqbo\qbo-5\client\node_modules\eslint-config-love\lib\index.js) +1ms
  eslintrc:config-array-factory Loading JS config file: G:\Roboqbo\qbo-5\client\node_modules\eslint-config-love\lib\index.js +0ms
  eslintrc:config-array-factory Error reading JavaScript file: G:\Roboqbo\qbo-5\client\node_modules\eslint-config-love\lib\index.js +2ms

Oops! Something went wrong! :(

ESLint: 9.2.0

Error: Cannot read config file: G:\Roboqbo\qbo-5\client\node_modules\eslint-config-love\lib\index.js
Error: This method cannot be used with flat config. Add your entries directly into the config array.
Referenced from:
    at assertEslintrcConfig (G:\Roboqbo\qbo-5\client\node_modules\eslint\lib\linter\linter.js:1256:15)
    at Linter.getRules (G:\Roboqbo\qbo-5\client\node_modules\eslint\lib\linter\linter.js:2185:9)
    at Object.<anonymous> (G:\Roboqbo\qbo-5\client\node_modules\eslint-config-love\lib\index.js:391:53)
    at Module._compile (node:internal/modules/cjs/loader:1364:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
    at Module.load (node:internal/modules/cjs/loader:1203:32)
    at Module._load (node:internal/modules/cjs/loader:1019:12)
    at Module.require (node:internal/modules/cjs/loader:1231:19)
    at require (node:internal/modules/helpers:177:18)
    at module.exports (G:\Roboqbo\qbo-5\client\node_modules\import-fresh\index.js:32:32)
import pluginVue from 'eslint-plugin-vue'
import globals from 'globals'

import { FlatCompat } from '@eslint/eslintrc'
import pluginJs from '@eslint/js'
import eslintLove from 'eslint-config-love'
import tseslint from 'typescript-eslint'

import path from 'path'
import { fileURLToPath } from 'url'

// mimic CommonJS variables -- not needed if using CommonJS
const _filename = fileURLToPath(import.meta.url)
const _dirname = path.dirname(_filename)
const compat = new FlatCompat({ baseDirectory: _dirname, recommendedConfig: pluginJs.configs.recommended, allConfig: pluginJs.configs.all })

export default [
  {
    languageOptions: {
      globals: {
        __statics: 'readonly',
        __QUASAR_SSR__: 'readonly',
        __QUASAR_SSR_SERVER__: 'readonly',
        __QUASAR_SSR_CLIENT__: 'readonly',
        __QUASAR_SSR_PWA__: 'readonly',
        ...globals.browser
      },
      parserOptions: {
        extraFileExtensions: ['.vue']
      }
    },
    ignores: [
      'dist/*',
      '.quasar/*',
      'node_modules/*',
      'src-capacitor/*',
      'src-cordova/*',
      'src-electron/*',
      'quasar.config.*.temporary.compiled*'
    ]
  },
  ...compat.extends('prettier'),
  ...eslintLove,
  ...pluginVue.configs['flat/recommended'],
  ...tseslint.configs.recommended
]



Oops! Something went wrong! :(

ESLint: 9.2.0

Error: This method cannot be used with flat config. Add your entries directly into the config array.
    at assertEslintrcConfig (G:\Roboqbo\qbo-5\client\node_modules\eslint\lib\linter\linter.js:1256:15)
    at Linter.getRules (G:\Roboqbo\qbo-5\client\node_modules\eslint\lib\linter\linter.js:2185:9)
    at Object.<anonymous> (G:\Roboqbo\qbo-5\client\node_modules\eslint-config-love\lib\index.js:391:53)
    at Module._compile (node:internal/modules/cjs/loader:1364:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
    at Module.load (node:internal/modules/cjs/loader:1203:32)
    at Module._load (node:internal/modules/cjs/loader:1019:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:203:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:337:24)

I used this workaround before

As a workaround :

import { FlatCompat } from '@eslint/eslintrc'
const compat = new FlatCompat()
export default [
  ...compat.extends('standard-with-typescript'),
]

See https://eslint.org/docs/latest/use/configure/migration-guide#using-eslintrc-configs-in-flat-config

๐ŸŽ‰ This issue has been resolved in version 48.0.0 ๐ŸŽ‰

The release is available on:

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€

Are these packages no longer necessary? or do they still need to be installed as stated in the previous version?

Yarn

Yarn does not automatically install peerDependencies, so if that's what you're using, install them manually. Here is an example, but use it only for reference, because your decisions regarding version ranges and range specifiers may vary.

yarn add --dev \
  typescript@\* \
  eslint@^8.0.1 \
  eslint-plugin-promise@^6.0.0 \
  eslint-plugin-import@^2.25.2 \
  eslint-plugin-n@^15.0.0 \
  @typescript-eslint/eslint-plugin@^7.0.1 \
  eslint-config-love@latest

If I remove them all it gives me this error and I had to reinstall eslint:

yarn install
โžค YN0000: ยท Yarn 4.2.2
โžค YN0000: โ”Œ Resolution step
โžค YN0000: โ”” Completed
โžค YN0000: โ”Œ Post-resolution validation
โžค YN0002: โ”‚ proj@workspace:. doesn't provide eslint (p4123a), requested by eslint-config-love.
โžค YN0002: โ”‚ proj@workspace:. doesn't provide eslint (p5f692), requested by eslint-config-prettier.
โžค YN0002: โ”‚ proj@workspace:. doesn't provide eslint (pafd61), requested by eslint-plugin-vue.
โžค YN0002: โ”‚ proj@workspace:. doesn't provide eslint (pd5ee7), requested by typescript-eslint.

The new version still throw exception:

yarn lint
  eslint:cli CLI args: [ '--debug', '.', '--fix' ] +0ms
  eslint:cli Using flat config? true +5ms
  eslint:cli Running on files +6ms
  eslint:eslint Using file patterns: . +0ms
  eslint:eslint Searching for eslint.config.js +0ms
  eslint:eslint Loading config from G:\MyProj\proj\client\eslint.config.js +5ms
  eslint:eslint Config file URL is file:///G:/MyProj/proj/client/eslint.config.js +0ms
  eslint:rules Loading rule 'array-bracket-newline' (remaining=289) +0ms
  eslint:rules Loading rule 'array-bracket-spacing' (remaining=288) +15ms
  eslint:rules Loading rule 'array-element-newline' (remaining=287) +6ms
  eslint:rules Loading rule 'arrow-spacing' (remaining=286) +6ms
  eslint:rules Loading rule 'block-spacing' (remaining=285) +35ms
  eslint:rules Loading rule 'brace-style' (remaining=284) +6ms
  eslint:rules Loading rule 'camelcase' (remaining=283) +4ms
  eslint:rules Loading rule 'comma-dangle' (remaining=282) +3ms
  eslint:rules Loading rule 'comma-spacing' (remaining=281) +7ms
  eslint:rules Loading rule 'comma-style' (remaining=280) +5ms
  eslint:rules Loading rule 'dot-location' (remaining=279) +12ms
  eslint:rules Loading rule 'dot-notation' (remaining=278) +5ms
  eslint:rules Loading rule 'eqeqeq' (remaining=277) +5ms
  eslint:rules Loading rule 'func-call-spacing' (remaining=276) +4ms
  eslint:rules Loading rule 'key-spacing' (remaining=275) +15ms
  eslint:rules Loading rule 'keyword-spacing' (remaining=274) +12ms
  eslint:rules Loading rule 'multiline-ternary' (remaining=273) +10ms
  eslint:rules Loading rule 'no-console' (remaining=272) +9ms
  eslint:rules Loading rule 'no-constant-condition' (remaining=271) +3ms
  eslint:rules Loading rule 'no-empty-pattern' (remaining=270) +17ms
  eslint:rules Loading rule 'no-extra-parens' (remaining=269) +6ms
  eslint:rules Loading rule 'no-loss-of-precision' (remaining=268) +9ms
  eslint:rules Loading rule 'no-restricted-syntax' (remaining=267) +21ms
  eslint:rules Loading rule 'no-sparse-arrays' (remaining=266) +7ms
  eslint:rules Loading rule 'no-useless-concat' (remaining=265) +19ms
  eslint:rules Loading rule 'object-curly-newline' (remaining=264) +8ms
  eslint:rules Loading rule 'object-curly-spacing' (remaining=263) +5ms
  eslint:rules Loading rule 'object-property-newline' (remaining=262) +4ms
  eslint:rules Loading rule 'object-shorthand' (remaining=261) +4ms
  eslint:rules Loading rule 'operator-linebreak' (remaining=260) +5ms
  eslint:rules Loading rule 'prefer-template' (remaining=259) +11ms
  eslint:rules Loading rule 'quote-props' (remaining=258) +4ms
  eslint:rules Loading rule 'space-in-parens' (remaining=257) +20ms
  eslint:rules Loading rule 'space-infix-ops' (remaining=256) +5ms
  eslint:rules Loading rule 'space-unary-ops' (remaining=255) +5ms
  eslint:rules Loading rule 'template-curly-spacing' (remaining=254) +5ms
  eslint:rules Loading rule 'consistent-return' (remaining=253) +630ms
  eslint:rules Loading rule 'indent' (remaining=252) +24ms
  eslint:rules Loading rule 'init-declarations' (remaining=251) +7ms
  eslint:rules Loading rule 'lines-around-comment' (remaining=250) +4ms
  eslint:rules Loading rule 'lines-between-class-members' (remaining=249) +4ms
  eslint:rules Loading rule 'max-params' (remaining=248) +3ms
  eslint:rules Loading rule 'no-dupe-class-members' (remaining=247) +24ms
  eslint:rules Loading rule 'no-empty-function' (remaining=246) +4ms
  eslint:rules Loading rule 'no-extra-semi' (remaining=245) +5ms
  eslint:rules Loading rule 'no-invalid-this' (remaining=244) +15ms
  eslint:rules Loading rule 'no-loop-func' (remaining=243) +3ms
  eslint:rules Loading rule 'no-magic-numbers' (remaining=242) +4ms
  eslint:rules Loading rule 'no-restricted-imports' (remaining=241) +19ms
  eslint:rules Loading rule 'no-unused-expressions' (remaining=240) +42ms
  eslint:rules Loading rule 'no-useless-constructor' (remaining=239) +5ms
  eslint:rules Loading rule 'prefer-destructuring' (remaining=238) +15ms
  eslint:rules Loading rule 'quotes' (remaining=237) +44ms
  eslint:rules Loading rule 'semi' (remaining=236) +11ms
  eslint:rules Loading rule 'space-before-blocks' (remaining=235) +4ms

Oops! Something went wrong! :(

ESLint: 9.3.0

Error: This method cannot be used with flat config. Add your entries directly into the config array.
    at assertEslintrcConfig (G:\MyProj\proj\client\node_modules\eslint\lib\linter\linter.js:1256:15)
    at Linter.getRules (G:\MyProj\proj\client\node_modules\eslint\lib\linter\linter.js:2185:9)
    at Object.<anonymous> (G:\MyProj\proj\client\node_modules\eslint-config-love\lib\index.js:418:61)
    at Module._compile (node:internal/modules/cjs/loader:1364:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
    at Module.load (node:internal/modules/cjs/loader:1203:32)
    at Module._load (node:internal/modules/cjs/loader:1019:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:203:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:337:24)

eslint.config.js

import pluginVue from 'eslint-plugin-vue'
import globals from 'globals'

import { FlatCompat } from '@eslint/eslintrc'
import pluginJs from '@eslint/js'
import eslintLove from 'eslint-config-love'

import path from 'path'
import { fileURLToPath } from 'url'

// mimic CommonJS variables -- not needed if using CommonJS
const _filename = fileURLToPath(import.meta.url)
const _dirname = path.dirname(_filename)
const compat = new FlatCompat({ baseDirectory: _dirname, recommendedConfig: pluginJs.configs.recommended, allConfig: pluginJs.configs.all })

export default [
  {
    languageOptions: {
      globals: {
        __statics: 'readonly',
        __QUASAR_SSR__: 'readonly',
        __QUASAR_SSR_SERVER__: 'readonly',
        __QUASAR_SSR_CLIENT__: 'readonly',
        __QUASAR_SSR_PWA__: 'readonly',
        ...globals.browser
      },
      parserOptions: {
        extraFileExtensions: ['.vue']
      }
    },
    ignores: [
      './dist/*',
      './.quasar/*',
      './node_modules/*',
      './src-capacitor/*',
      './src-cordova/*',
      './src-electron/*',
      './quasar.config.*.temporary.compiled*'
    ]
  },
  ...compat.extends('prettier'),
  ...pluginVue.configs['flat/recommended'],
  ...eslintLove
]

eslint-config-love/lib/index.js

......
......
......
const eslintRuleNames = [...(new utils_1.TSESLint.Linter()).getRules().keys()];
const namesOfEslintRulesForWhichWeAreUsingTsEquivalents = eslintRuleNames
    .filter(name => Object.hasOwn(rules, `@typescript-eslint/${name}`));
const config = {
    languageOptions: {
        parser: typescript_eslint_1.parser,
        parserOptions: {
            project: true
        }
    },
    plugins: {
        '@typescript-eslint': typescript_eslint_1.plugin,
        import: importPlugin,
        n: nPlugin,
        promise: promisePlugin
    },
    rules: {
        ...Object.fromEntries(namesOfEslintRulesForWhichWeAreUsingTsEquivalents.map(name => [name, ['off']])),
        ...rules
    }
};
module.exports = config;
//# sourceMappingURL=index.js.map

@zN3utr4l eslint and typescript are now the only peerDeps. Since it seems obvious that all users would have them installed, the entire section was removed.

Sorry. Could you, please use the discussions feature for support? I'd love to help you there.

Commenting here in case it might help anyone landing here in the future.

At the time of writing, if you encounter the This method cannot be used with flat config. Add your entries directly into the config array. error and check your eslint version. If it's 9.x, downgrade to the supported eslint 8 version as specified in the package.json for this package.

Discussion