From 8a9ef701df9628288a8d874df96252311447064e Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Thu, 26 Sep 2024 12:45:05 +0200 Subject: [PATCH 1/3] Update all packages to use `createConfig` --- packages/base/src/index.d.mts | 60 ++++++++++++++++- packages/browser/src/index.mjs | 34 +++------- packages/commonjs/src/index.mjs | 34 +++------- packages/jest/src/index.mjs | 89 +++++++++---------------- packages/mocha/src/index.mjs | 69 +++++++------------ packages/nodejs/src/index.mjs | 107 +++++++++++++----------------- packages/typescript/src/index.mjs | 16 ++--- packages/vitest/src/index.mjs | 102 +++++++++++----------------- 8 files changed, 227 insertions(+), 284 deletions(-) diff --git a/packages/base/src/index.d.mts b/packages/base/src/index.d.mts index 3f913173..98df94e8 100644 --- a/packages/base/src/index.d.mts +++ b/packages/base/src/index.d.mts @@ -1,6 +1,64 @@ declare module '@metamask/eslint-config' { import type { Linter } from 'eslint'; - const config: Linter.Config[]; + /** + * An ESLint configuration object. + */ + type Config = Linter.Config; + + /** + * An ESLint configuration object that may extend other configurations. This + * can only be used with the {@link createConfig} function. + */ + type ConfigWithExtends = Config & { + extends?: Config | Config[] | Config[][]; + }; + + /** + * Create a config object that extends other configs. + * + * ESLint 9 removed support for extending arrays of configs, so this function + * provides a workaround. It takes an array of config objects, where each object + * may have an `extends` property that is an array of other config objects. + * + * This function is inspired by the `config` function in the `typescript-eslint` + * package, but to avoid a dependency on that package, this function is + * implemented here. + * + * @param configs - An array of config objects. + * @returns An array of config objects with all `extends` properties + * resolved. + * @example Basic usage. + * import { createConfig } from '@metamask/eslint-config'; + * import typescript from '@metamask/eslint-config-typescript'; + * + * const configs = createConfig([ + * { + * files: ['**\/*.ts'], + * extends: typescript, + * }, + * ]); + * + * export default configs; + * + * @example Multiple extends are supported as well. + * import { createConfig } from '@metamask/eslint-config'; + * import typescript from '@metamask/eslint-config-typescript'; + * import nodejs from '@metamask/eslint-config-nodejs'; + * + * const configs = createConfig([ + * { + * files: ['**\/*.ts'], + * extends: [typescript, nodejs], + * }, + * ]); + * + * export default configs; + */ + export function createConfig( + configs: ConfigWithExtends | ConfigWithExtends[], + ): Config[]; + + const config: Config[]; export default config; } diff --git a/packages/browser/src/index.mjs b/packages/browser/src/index.mjs index 7a86d5b5..97333758 100644 --- a/packages/browser/src/index.mjs +++ b/packages/browser/src/index.mjs @@ -1,3 +1,4 @@ +import { createConfig } from '@metamask/eslint-config'; import globals from 'globals'; import { createRequire } from 'module'; @@ -8,33 +9,18 @@ const environmentRules = customRequire('./environment.json'); /** * @type {import('eslint').Linter.Config[]} */ -const config = [ - { - name: '@metamask/eslint-config-browser', +const config = createConfig({ + name: '@metamask/eslint-config-browser', - files: [ - '**/*.js', - '**/*.jsx', - '**/*.mjs', - '**/*.cjs', - '**/*.ts', - '**/*.tsx', - '**/*.mts', - '**/*.cts', - '**/*.mtsx', - '**/*.ctsx', - ], - - languageOptions: { - globals: { - ...globals.browser, - }, + languageOptions: { + globals: { + ...globals.browser, }, + }, - rules: { - ...environmentRules, - }, + rules: { + ...environmentRules, }, -]; +}); export default config; diff --git a/packages/commonjs/src/index.mjs b/packages/commonjs/src/index.mjs index 9011983e..18479d21 100644 --- a/packages/commonjs/src/index.mjs +++ b/packages/commonjs/src/index.mjs @@ -1,3 +1,4 @@ +import { createConfig } from '@metamask/eslint-config'; import globals from 'globals'; import { createRequire } from 'module'; @@ -8,33 +9,18 @@ const environmentRules = customRequire('./environment.json'); /** * @type {import('eslint').Linter.Config[]} */ -const config = [ - { - name: '@metamask/eslint-config-commonjs', +const config = createConfig({ + name: '@metamask/eslint-config-commonjs', - files: [ - '**/*.js', - '**/*.jsx', - '**/*.mjs', - '**/*.cjs', - '**/*.ts', - '**/*.tsx', - '**/*.mts', - '**/*.cts', - '**/*.mtsx', - '**/*.ctsx', - ], - - languageOptions: { - globals: { - ...globals.commonjs, - }, + languageOptions: { + globals: { + ...globals.commonjs, }, + }, - rules: { - ...environmentRules, - }, + rules: { + ...environmentRules, }, -]; +}); export default config; diff --git a/packages/jest/src/index.mjs b/packages/jest/src/index.mjs index 3ca690ed..a3199001 100644 --- a/packages/jest/src/index.mjs +++ b/packages/jest/src/index.mjs @@ -1,69 +1,46 @@ +import { createConfig } from '@metamask/eslint-config'; import jest from 'eslint-plugin-jest'; import globals from 'globals'; /** * @type {import('eslint').Linter.Config[]} */ -const config = [ - jest.configs['flat/recommended'], - jest.configs['flat/style'], +const config = createConfig({ + name: '@metamask/eslint-config-jest', - { - name: '@metamask/eslint-config-jest', + extends: [jest.configs['flat/recommended'], jest.configs['flat/style']], - files: [ - '**/*.test.js', - '**/*.spec.js', - '**/*.test.mjs', - '**/*.spec.mjs', - '**/*.test.cjs', - '**/*.spec.cjs', - '**/*.test.ts', - '**/*.spec.ts', - '**/*.test.tsx', - '**/*.spec.tsx', - '**/*.test.mts', - '**/*.spec.mts', - '**/*.test.cts', - '**/*.spec.cts', - '**/*.test.mtsx', - '**/*.spec.mtsx', - '**/*.test.ctsx', - '**/*.spec.ctsx', - ], - - languageOptions: { - globals: { - ...globals.jest, - }, + languageOptions: { + globals: { + ...globals.jest, }, + }, - rules: { - 'jest/consistent-test-it': ['error', { fn: 'it' }], - 'jest/no-duplicate-hooks': 'error', - 'jest/no-conditional-in-test': 'error', - 'jest/no-test-return-statement': 'error', - 'jest/prefer-hooks-on-top': 'error', - 'jest/prefer-lowercase-title': ['error', { ignore: ['describe'] }], - 'jest/prefer-spy-on': 'error', - 'jest/prefer-strict-equal': 'error', - 'jest/prefer-todo': 'error', - 'jest/require-top-level-describe': 'error', - 'jest/require-to-throw-message': 'error', - 'jest/valid-expect': ['error', { alwaysAwait: true }], - 'jest/no-restricted-matchers': [ - 'error', - { - resolves: 'Use `expect(await promise)` instead.', - toBeFalsy: 'Avoid `toBeFalsy`', - toBeTruthy: 'Avoid `toBeTruthy`', - toMatchSnapshot: 'Use `toMatchInlineSnapshot()` instead', - toThrowErrorMatchingSnapshot: - 'Use `toThrowErrorMatchingInlineSnapshot()` instead', - }, - ], - }, + rules: { + 'jest/consistent-test-it': ['error', { fn: 'it' }], + 'jest/no-duplicate-hooks': 'error', + 'jest/no-conditional-in-test': 'error', + 'jest/no-test-return-statement': 'error', + 'jest/prefer-hooks-on-top': 'error', + 'jest/prefer-lowercase-title': ['error', { ignore: ['describe'] }], + 'jest/prefer-spy-on': 'error', + 'jest/prefer-strict-equal': 'error', + 'jest/prefer-todo': 'error', + 'jest/require-top-level-describe': 'error', + 'jest/require-to-throw-message': 'error', + 'jest/valid-expect': ['error', { alwaysAwait: true }], + 'jest/no-restricted-matchers': [ + 'error', + { + resolves: 'Use `expect(await promise)` instead.', + toBeFalsy: 'Avoid `toBeFalsy`', + toBeTruthy: 'Avoid `toBeTruthy`', + toMatchSnapshot: 'Use `toMatchInlineSnapshot()` instead', + toThrowErrorMatchingSnapshot: + 'Use `toThrowErrorMatchingInlineSnapshot()` instead', + }, + ], }, -]; +}); export default config; diff --git a/packages/mocha/src/index.mjs b/packages/mocha/src/index.mjs index f5ef7984..68ff187c 100644 --- a/packages/mocha/src/index.mjs +++ b/packages/mocha/src/index.mjs @@ -1,3 +1,4 @@ +import { createConfig } from '@metamask/eslint-config'; import mocha from 'eslint-plugin-mocha'; const SIMPLE_TEST_NAME_REGEX = '^[#_]{0,2}[A-Za-z0-9]'; @@ -5,53 +6,31 @@ const SIMPLE_TEST_NAME_REGEX = '^[#_]{0,2}[A-Za-z0-9]'; /** * @type {import('eslint').Linter.Config[]} */ -const config = [ - mocha.configs.flat.recommended, - { - name: '@metamask/eslint-config-mocha', +const config = createConfig({ + name: '@metamask/eslint-config-mocha', - files: [ - '**/*.test.js', - '**/*.spec.js', - '**/*.test.mjs', - '**/*.spec.mjs', - '**/*.test.cjs', - '**/*.spec.cjs', - '**/*.test.ts', - '**/*.spec.ts', - '**/*.test.tsx', - '**/*.spec.tsx', - '**/*.test.mts', - '**/*.spec.mts', - '**/*.test.cts', - '**/*.spec.cts', - '**/*.test.mtsx', - '**/*.spec.mtsx', - '**/*.test.ctsx', - '**/*.spec.ctsx', - ], + extends: [mocha.configs.flat.recommended], - rules: { - 'mocha/no-exclusive-tests': 'error', - 'mocha/no-hooks-for-single-case': 'error', - 'mocha/no-pending-tests': 'error', - 'mocha/no-return-from-async': 'error', - 'mocha/no-skipped-tests': 'error', - 'mocha/no-top-level-hooks': 'error', - 'mocha/valid-suite-description': [ - 'error', - SIMPLE_TEST_NAME_REGEX, - ['describe', 'context', 'suite'], - 'Invalid test suite description found', - ], - 'mocha/valid-test-description': [ - 'error', - SIMPLE_TEST_NAME_REGEX, - ['it', 'test', 'specify'], - 'Invalid test description found', - ], - }, + rules: { + 'mocha/no-exclusive-tests': 'error', + 'mocha/no-hooks-for-single-case': 'error', + 'mocha/no-pending-tests': 'error', + 'mocha/no-return-from-async': 'error', + 'mocha/no-skipped-tests': 'error', + 'mocha/no-top-level-hooks': 'error', + 'mocha/valid-suite-description': [ + 'error', + SIMPLE_TEST_NAME_REGEX, + ['describe', 'context', 'suite'], + 'Invalid test suite description found', + ], + 'mocha/valid-test-description': [ + 'error', + SIMPLE_TEST_NAME_REGEX, + ['it', 'test', 'specify'], + 'Invalid test description found', + ], }, -]; +}); export default config; diff --git a/packages/nodejs/src/index.mjs b/packages/nodejs/src/index.mjs index b6741aae..5b029625 100644 --- a/packages/nodejs/src/index.mjs +++ b/packages/nodejs/src/index.mjs @@ -1,3 +1,4 @@ +import { createConfig } from '@metamask/eslint-config'; import node from 'eslint-plugin-n'; import globals from 'globals'; import { createRequire } from 'module'; @@ -9,73 +10,59 @@ const environmentRules = customRequire('./environment.json'); /** * @type {import('eslint').Linter.Config[]} */ -const config = [ - node.configs['flat/recommended'], - { - name: '@metamask/eslint-config-nodejs', +const config = createConfig({ + name: '@metamask/eslint-config-nodejs', - files: [ - '**/*.js', - '**/*.jsx', - '**/*.mjs', - '**/*.cjs', - '**/*.ts', - '**/*.tsx', - '**/*.mts', - '**/*.cts', - '**/*.mtsx', - '**/*.ctsx', - ], + extends: [node.configs['flat/recommended']], - languageOptions: { - globals: { - // See comment below. - ...globals.es2022, - ...globals.node, - }, - - // The EcmaScript version option here and for `env` above need to be set - // to the same values as in the base config, or they will be overwritten - // by the recommended Node.js plugin rules. - ecmaVersion: 2022, + languageOptions: { + globals: { + // See comment below. + ...globals.es2022, + ...globals.node, }, - rules: { - ...environmentRules, + // The EcmaScript version option here and for `env` above need to be set + // to the same values as in the base config, or they will be overwritten + // by the recommended Node.js plugin rules. + ecmaVersion: 2022, + }, + + rules: { + ...environmentRules, - // Possible Errors - 'n/handle-callback-err': ['error', '^(err|error)$'], - 'n/no-callback-literal': 'error', - 'n/no-missing-import': 'off', // Duplicates `import-x/no-unresolved` - 'n/no-missing-require': 'off', // Duplicates `import-x/no-unresolved` - 'n/no-new-require': 'error', - 'n/no-path-concat': 'error', - 'n/no-unsupported-features/es-syntax': 'off', + // Possible Errors + 'n/handle-callback-err': ['error', '^(err|error)$'], + 'n/no-callback-literal': 'error', + 'n/no-missing-import': 'off', // Duplicates `import-x/no-unresolved` + 'n/no-missing-require': 'off', // Duplicates `import-x/no-unresolved` + 'n/no-new-require': 'error', + 'n/no-path-concat': 'error', + 'n/no-unsupported-features/es-syntax': 'off', - // Stylistic rules - 'n/callback-return': 'error', - 'n/exports-style': 'error', - 'n/global-require': 'error', - 'n/no-mixed-requires': 'error', - 'n/no-process-env': 'error', - 'n/no-restricted-import': 'error', - 'n/no-restricted-require': 'error', - 'n/no-sync': 'error', - 'n/prefer-global/buffer': 'error', - 'n/prefer-global/console': 'error', - 'n/prefer-global/process': 'error', - 'n/prefer-global/text-decoder': 'error', - 'n/prefer-global/text-encoder': 'error', - 'n/prefer-global/url-search-params': 'error', - 'n/prefer-global/url': 'error', - 'n/prefer-promises/dns': 'error', - 'n/prefer-promises/fs': 'error', + // Stylistic rules + 'n/callback-return': 'error', + 'n/exports-style': 'error', + 'n/global-require': 'error', + 'n/no-mixed-requires': 'error', + 'n/no-process-env': 'error', + 'n/no-restricted-import': 'error', + 'n/no-restricted-require': 'error', + 'n/no-sync': 'error', + 'n/prefer-global/buffer': 'error', + 'n/prefer-global/console': 'error', + 'n/prefer-global/process': 'error', + 'n/prefer-global/text-decoder': 'error', + 'n/prefer-global/text-encoder': 'error', + 'n/prefer-global/url-search-params': 'error', + 'n/prefer-global/url': 'error', + 'n/prefer-promises/dns': 'error', + 'n/prefer-promises/fs': 'error', - // Enabled in the base config, but this should be allowed in Node.js - // projects. - 'import-x/no-nodejs-modules': 'off', - }, + // Enabled in the base config, but this should be allowed in Node.js + // projects. + 'import-x/no-nodejs-modules': 'off', }, -]; +}); export default config; diff --git a/packages/typescript/src/index.mjs b/packages/typescript/src/index.mjs index 3f395c33..6bdc2439 100644 --- a/packages/typescript/src/index.mjs +++ b/packages/typescript/src/index.mjs @@ -1,3 +1,4 @@ +import { createConfig } from '@metamask/eslint-config'; import * as resolver from 'eslint-import-resolver-typescript'; import importX from 'eslint-plugin-import-x'; import jsdoc from 'eslint-plugin-jsdoc'; @@ -5,7 +6,7 @@ import jsdoc from 'eslint-plugin-jsdoc'; // eslint-disable-next-line import-x/no-unresolved import typescript from 'typescript-eslint'; -const config = typescript.config({ +const config = createConfig({ name: '@metamask/eslint-config-typescript', plugins: { @@ -13,21 +14,12 @@ const config = typescript.config({ }, extends: [ - ...typescript.configs.recommended, - ...typescript.configs.recommendedTypeChecked, + typescript.configs.recommended, + typescript.configs.recommendedTypeChecked, importX.flatConfigs.typescript, jsdoc.configs['flat/recommended-typescript-error'], ], - files: [ - '**/*.ts', - '**/*.tsx', - '**/*.mts', - '**/*.cts', - '**/*.mtsx', - '**/*.ctsx', - ], - languageOptions: { sourceType: 'module', parserOptions: { diff --git a/packages/vitest/src/index.mjs b/packages/vitest/src/index.mjs index 03b6c537..5afaa6d1 100644 --- a/packages/vitest/src/index.mjs +++ b/packages/vitest/src/index.mjs @@ -1,73 +1,51 @@ +import { createConfig } from '@metamask/eslint-config'; import vitest from '@vitest/eslint-plugin'; /** * @type {import('eslint').Linter.Config[]} */ -const config = [ - vitest.configs.recommended, +const config = createConfig({ + name: '@metamask/eslint-config-vitest', - { - name: '@metamask/eslint-config-vitest', + extends: [vitest.configs.recommended], - files: [ - '**/*.test.js', - '**/*.spec.js', - '**/*.test.mjs', - '**/*.spec.mjs', - '**/*.test.cjs', - '**/*.spec.cjs', - '**/*.test.ts', - '**/*.spec.ts', - '**/*.test.tsx', - '**/*.spec.tsx', - '**/*.test.mts', - '**/*.spec.mts', - '**/*.test.cts', - '**/*.spec.cts', - '**/*.test.mtsx', - '**/*.spec.mtsx', - '**/*.test.ctsx', - '**/*.spec.ctsx', + rules: { + 'vitest/consistent-test-it': ['error', { fn: 'it' }], + 'vitest/no-alias-methods': 'error', + 'vitest/no-commented-out-tests': 'error', + 'vitest/no-conditional-expect': 'error', + 'vitest/no-conditional-in-test': 'error', + 'vitest/no-disabled-tests': 'error', + 'vitest/no-duplicate-hooks': 'error', + 'vitest/no-focused-tests': 'error', + 'vitest/no-interpolation-in-snapshots': 'error', + 'vitest/no-mocks-import': 'error', + 'vitest/no-standalone-expect': 'error', + 'vitest/no-test-prefixes': 'error', + 'vitest/no-test-return-statement': 'error', + 'vitest/prefer-hooks-on-top': 'error', + 'vitest/prefer-lowercase-title': ['error', { ignore: ['describe'] }], + 'vitest/prefer-spy-on': 'error', + 'vitest/prefer-strict-equal': 'error', + 'vitest/prefer-to-be': 'error', + 'vitest/prefer-to-contain': 'error', + 'vitest/prefer-to-have-length': 'error', + 'vitest/prefer-todo': 'error', + 'vitest/require-to-throw-message': 'error', + 'vitest/require-top-level-describe': 'error', + 'vitest/valid-expect': ['error', { alwaysAwait: true }], + 'vitest/no-restricted-matchers': [ + 'error', + { + resolves: 'Use `expect(await promise)` instead.', + toBeFalsy: 'Avoid `toBeFalsy`.', + toBeTruthy: 'Avoid `toBeTruthy`.', + toMatchSnapshot: 'Use `toMatchInlineSnapshot()` instead.', + toThrowErrorMatchingSnapshot: + 'Use `toThrowErrorMatchingInlineSnapshot()` instead.', + }, ], - - rules: { - 'vitest/consistent-test-it': ['error', { fn: 'it' }], - 'vitest/no-alias-methods': 'error', - 'vitest/no-commented-out-tests': 'error', - 'vitest/no-conditional-expect': 'error', - 'vitest/no-conditional-in-test': 'error', - 'vitest/no-disabled-tests': 'error', - 'vitest/no-duplicate-hooks': 'error', - 'vitest/no-focused-tests': 'error', - 'vitest/no-interpolation-in-snapshots': 'error', - 'vitest/no-mocks-import': 'error', - 'vitest/no-standalone-expect': 'error', - 'vitest/no-test-prefixes': 'error', - 'vitest/no-test-return-statement': 'error', - 'vitest/prefer-hooks-on-top': 'error', - 'vitest/prefer-lowercase-title': ['error', { ignore: ['describe'] }], - 'vitest/prefer-spy-on': 'error', - 'vitest/prefer-strict-equal': 'error', - 'vitest/prefer-to-be': 'error', - 'vitest/prefer-to-contain': 'error', - 'vitest/prefer-to-have-length': 'error', - 'vitest/prefer-todo': 'error', - 'vitest/require-to-throw-message': 'error', - 'vitest/require-top-level-describe': 'error', - 'vitest/valid-expect': ['error', { alwaysAwait: true }], - 'vitest/no-restricted-matchers': [ - 'error', - { - resolves: 'Use `expect(await promise)` instead.', - toBeFalsy: 'Avoid `toBeFalsy`.', - toBeTruthy: 'Avoid `toBeTruthy`.', - toMatchSnapshot: 'Use `toMatchInlineSnapshot()` instead.', - toThrowErrorMatchingSnapshot: - 'Use `toThrowErrorMatchingInlineSnapshot()` instead.', - }, - ], - }, }, -]; +}); export default config; From fe56ca1fd3fabd35f658fdda2a3d8f4ebafd14c5 Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Thu, 26 Sep 2024 12:45:56 +0200 Subject: [PATCH 2/3] Update main config to use `createConfig` --- eslint.config.mjs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index df9a7bc1..f98df8db 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,13 +1,11 @@ // @ts-check -import base from '@metamask/eslint-config'; +import base, { createConfig } from '@metamask/eslint-config'; import nodejs from '@metamask/eslint-config-nodejs'; import typescript from '@metamask/eslint-config-typescript'; import vitest from '@metamask/eslint-config-vitest'; -// eslint-disable-next-line import-x/no-unresolved -import tseslint from 'typescript-eslint'; -const config = tseslint.config( +const config = createConfig([ { ignores: ['.yarn/'], }, @@ -58,6 +56,6 @@ const config = tseslint.config( 'n/no-unpublished-require': 'off', }, }, -); +]); export default config; From 8d4e554104d2077905a9005dd53eac08e8491176 Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Thu, 26 Sep 2024 12:49:44 +0200 Subject: [PATCH 3/3] Update all READMEs --- packages/base/README.md | 20 +++++++------- packages/browser/README.md | 21 ++++++++------- packages/commonjs/README.md | 22 ++++++++-------- packages/jest/README.md | 24 ++++++++--------- packages/mocha/README.md | 22 ++++++++-------- packages/nodejs/README.md | 24 ++++++++--------- packages/typescript/README.md | 49 +++++++++++++++++------------------ packages/vitest/README.md | 22 ++++++++-------- 8 files changed, 102 insertions(+), 102 deletions(-) diff --git a/packages/base/README.md b/packages/base/README.md index 3731d97e..ac05a7f5 100644 --- a/packages/base/README.md +++ b/packages/base/README.md @@ -24,17 +24,17 @@ with `@metamask/eslint-config` first, and `@metamask/eslint-config-*` in any order thereafter. ```js -import base from '@metamask/eslint-config'; - -const config = { - // Any custom shared config should be added here. - // ... - - // This should be added last unless you know what you're doing. - ...base, +import base, { createConfig } from '@metamask/eslint-config'; +const config = createConfig({ { - // Your overrides here. + extends: [ + // Any custom shared config should be added here. + // ... + + // This should be added last unless you know what you're doing. + base, + ], } -}; +}); ``` diff --git a/packages/browser/README.md b/packages/browser/README.md index 593fbcd9..a844395b 100644 --- a/packages/browser/README.md +++ b/packages/browser/README.md @@ -25,18 +25,19 @@ with `@metamask/eslint-config` first, and `@metamask/eslint-config-*` in any order thereafter. ```js -import base from '@metamask/eslint-config'; +import base, { createConfig } from '@metamask/eslint-config'; import browser from '@metamask/eslint-config-browser'; -const config = { - // Any custom shared config should be added here. - // ... - - // This should be added last unless you know what you're doing. - ...base, - ...browser, +const config = createConfig({ { - // Your overrides here. + extends: [ + // Any custom shared config should be added here. + // ... + + // This should be added last unless you know what you're doing. + base, + browser, + ], } -}; +}); ``` diff --git a/packages/commonjs/README.md b/packages/commonjs/README.md index b7a9309d..d7af4370 100644 --- a/packages/commonjs/README.md +++ b/packages/commonjs/README.md @@ -23,19 +23,19 @@ with `@metamask/eslint-config` first, and `@metamask/eslint-config-*` in any order thereafter. ```js -import base from '@metamask/eslint-config'; +import base, { createConfig } from '@metamask/eslint-config'; import commonjs from '@metamask/eslint-config-commonjs'; -const config = { - // Any custom shared config should be added here. - // ... - - // This should be added last unless you know what you're doing. - ...base, - ...commonjs, - +const config = createConfig({ { - // Your overrides here. + extends: [ + // Any custom shared config should be added here. + // ... + + // This should be added last unless you know what you're doing. + base, + commonjs, + ], } -}; +}); ``` diff --git a/packages/jest/README.md b/packages/jest/README.md index e845de7c..087c4c6c 100644 --- a/packages/jest/README.md +++ b/packages/jest/README.md @@ -24,19 +24,19 @@ with `@metamask/eslint-config` first, and `@metamask/eslint-config-*` in any order thereafter. ```js -import base from '@metamask/eslint-config'; -import commonjs from '@metamask/eslint-config-commonjs'; - -const config = { - // Any custom shared config should be added here. - // ... - - // This should be added last unless you know what you're doing. - ...base, - ...commonjs, +import base, { createConfig } from '@metamask/eslint-config'; +import jest from '@metamask/eslint-config-jest'; +const config = createConfig({ { - // Your overrides here. + extends: [ + // Any custom shared config should be added here. + // ... + + // This should be added last unless you know what you're doing. + base, + jest, + ], } -}; +}); ``` diff --git a/packages/mocha/README.md b/packages/mocha/README.md index d8065bff..e7e58ada 100644 --- a/packages/mocha/README.md +++ b/packages/mocha/README.md @@ -24,21 +24,21 @@ with `@metamask/eslint-config` first, and `@metamask/eslint-config-*` in any order thereafter. ```js -import base from '@metamask/eslint-config'; +import base, { createConfig } from '@metamask/eslint-config'; import mocha from '@metamask/eslint-config-mocha'; -const config = { - // Any custom shared config should be added here. - // ... - - // This should be added last unless you know what you're doing. - ...base, - ...mocha, - +const config = createConfig({ { - // Your overrides here. + extends: [ + // Any custom shared config should be added here. + // ... + + // This should be added last unless you know what you're doing. + base, + mocha, + ], } -}; +}); ``` If your project has `prefer-arrow-callback` you will need to disable that and diff --git a/packages/nodejs/README.md b/packages/nodejs/README.md index c2cdf567..9fca80bf 100644 --- a/packages/nodejs/README.md +++ b/packages/nodejs/README.md @@ -24,21 +24,21 @@ with `@metamask/eslint-config` first, and `@metamask/eslint-config-*` in any order thereafter. ```js -import base from '@metamask/eslint-config'; -import mocha from '@metamask/eslint-config-mocha'; - -const config = { - // Any custom shared config should be added here. - // ... - - // This should be added last unless you know what you're doing. - ...base, - ...mocha, +import base, { createConfig } from '@metamask/eslint-config'; +import nodejs from '@metamask/eslint-config-nodejs'; +const config = createConfig({ { - // Your overrides here. + extends: [ + // Any custom shared config should be added here. + // ... + + // This should be added last unless you know what you're doing. + base, + nodejs, + ], } -}; +}); ``` To lint the `.eslintrc.js` file itself, you will **need** to add this config in addition to the base config. diff --git a/packages/typescript/README.md b/packages/typescript/README.md index 665d2b6e..86aeb6cd 100644 --- a/packages/typescript/README.md +++ b/packages/typescript/README.md @@ -24,32 +24,31 @@ with `@metamask/eslint-config` first, and `@metamask/eslint-config-*` in any order thereafter. ```js -import base from '@metamask/eslint-config'; +import base, { createConfig } from '@metamask/eslint-config'; import typescript from '@metamask/eslint-config-typescript'; -import tseslint from 'typescript-eslint'; - -const config = tseslint.config({ - // The TypeScript config disables certain rules that you want to keep for - // non-TypeScript files, so it should be added in an override. - files: ['**/*.ts', '**/*.mts', '**/*.cts'], - - extends: [ - // Any custom shared config should be added here. - // ... - - // This should be added last unless you know what you're doing. - ...base, - ...typescript, - ], - - languageOptions: { - parserOptions: { - // This is required for rules that use type information. - // See here for more information: https://typescript-eslint.io/getting-started/typed-linting - tsconfigRootDir: import.meta.dirname, - }, - }, - // Your overrides here. +const config = createConfig({ + { + // The TypeScript config disables certain rules that you want to keep for + // non-TypeScript files, so it should be added in an override. + files: ['**/*.ts', '**/*.mts', '**/*.cts'], + + extends: [ + // Any custom shared config should be added here. + // ... + + // This should be added last unless you know what you're doing. + ...base, + ...typescript, + ], + + languageOptions: { + parserOptions: { + // This is required for rules that use type information. + // See here for more information: https://typescript-eslint.io/getting-started/typed-linting + tsconfigRootDir: import.meta.dirname, + }, + }, + } }); ``` diff --git a/packages/vitest/README.md b/packages/vitest/README.md index 5d7b6cd2..27d3d190 100644 --- a/packages/vitest/README.md +++ b/packages/vitest/README.md @@ -24,19 +24,19 @@ with `@metamask/eslint-config` first, and `@metamask/eslint-config-*` in any order thereafter. ```js -import base from '@metamask/eslint-config'; +import base, { createConfig } from '@metamask/eslint-config'; import vitest from '@metamask/eslint-config-vitest'; -const config = { - // Any custom shared config should be added here. - // ... - - // This should be added last unless you know what you're doing. - ...base, - ...vitest, - +const config = createConfig({ { - // Your overrides here. + extends: [ + // Any custom shared config should be added here. + // ... + + // This should be added last unless you know what you're doing. + base, + vitest, + ], } -}; +}); ```