diff --git a/.changeset/pretty-glasses-admire.md b/.changeset/pretty-glasses-admire.md new file mode 100644 index 0000000000..318271ddc9 --- /dev/null +++ b/.changeset/pretty-glasses-admire.md @@ -0,0 +1,9 @@ +--- +'@backstage/cli': patch +--- + +Removed the `import/no-duplicates` lint rule from the frontend and backend ESLint configurations. This rule is quite expensive to execute and only provides a purely cosmetic benefit, so we opted to remove it from the set of default rules. If you would like to keep this rule you can add it back in your local ESLint configuration: + +```js + 'import/no-duplicates': 'warn' +``` diff --git a/.changeset/three-dolls-fly.md b/.changeset/three-dolls-fly.md new file mode 100644 index 0000000000..df711c547d --- /dev/null +++ b/.changeset/three-dolls-fly.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Switched the `lint` command to invoke ESLint directly through its Node.js API rather than spawning a new process. diff --git a/packages/cli/config/eslint.backend.js b/packages/cli/config/eslint.backend.js index a97f26f8da..519b388b96 100644 --- a/packages/cli/config/eslint.backend.js +++ b/packages/cli/config/eslint.backend.js @@ -54,11 +54,10 @@ module.exports = { 'no-console': 0, // Permitted in console programs 'new-cap': ['error', { capIsNew: false }], // Because Express constructs things e.g. like 'const r = express.Router()' 'import/newline-after-import': 'error', - 'import/no-duplicates': 'warn', 'import/no-extraneous-dependencies': [ 'error', { - devDependencies: false, + devDependencies: ['**/*.test.*', 'src/setupTests.*', 'dev/**'], optionalDependencies: true, peerDependencies: true, bundledDependencies: true, @@ -97,16 +96,6 @@ module.exports = { { files: ['*.test.*', 'src/setupTests.*', 'dev/**'], rules: { - // Tests are allowed to import dev dependencies - 'import/no-extraneous-dependencies': [ - 'error', - { - devDependencies: true, - optionalDependencies: true, - peerDependencies: true, - bundledDependencies: true, - }, - ], 'no-restricted-syntax': ['error', ...globalRestrictedSyntax], }, }, diff --git a/packages/cli/config/eslint.js b/packages/cli/config/eslint.js index 781af13577..06f22933e8 100644 --- a/packages/cli/config/eslint.js +++ b/packages/cli/config/eslint.js @@ -49,11 +49,15 @@ module.exports = { '@typescript-eslint/no-redeclare': 'error', 'no-undef': 'off', 'import/newline-after-import': 'error', - 'import/no-duplicates': 'warn', 'import/no-extraneous-dependencies': [ 'error', { - devDependencies: false, + devDependencies: [ + '**/*.test.*', + '**/*.stories.*', + 'src/setupTests.*', + 'dev/**', + ], optionalDependencies: true, peerDependencies: true, bundledDependencies: true, @@ -101,20 +105,5 @@ module.exports = { 'no-undef': 'off', }, }, - { - files: ['*.test.*', '*.stories.*', 'src/setupTests.*', 'dev/**'], - rules: { - // Tests are allowed to import dev dependencies - 'import/no-extraneous-dependencies': [ - 'error', - { - devDependencies: true, - optionalDependencies: true, - peerDependencies: true, - bundledDependencies: true, - }, - ], - }, - }, ], }; diff --git a/packages/cli/src/commands/lint.ts b/packages/cli/src/commands/lint.ts index 5c3e0a88e3..6db17dbfc4 100644 --- a/packages/cli/src/commands/lint.ts +++ b/packages/cli/src/commands/lint.ts @@ -15,19 +15,29 @@ */ import { Command } from 'commander'; -import { run } from '../lib/run'; import { paths } from '../lib/paths'; +import { ESLint } from 'eslint'; + +export default async (cmd: Command) => { + const eslint = new ESLint({ + cwd: paths.targetDir, + fix: cmd.fix, + extensions: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'], + }); + + const results = await eslint.lintFiles(['.']); -export default async (cmd: Command, cmdArgs: string[]) => { - const args = [ - '--ext=js,jsx,ts,tsx,mjs,cjs', - '--max-warnings=0', - `--format=${cmd.format}`, - ...(cmdArgs ?? [paths.targetDir]), - ]; if (cmd.fix) { - args.push('--fix'); + await ESLint.outputFixes(results); } - await run('eslint', args); + const formatter = await eslint.loadFormatter(cmd.format); + const resultText = formatter.format(results); + + // If there is any feedback at all, we treat it as a lint failure. This should be + // consistent with our old behavior of passing `--max-warnings=0` when invoking eslint. + if (resultText) { + console.log(resultText); + process.exit(1); + } };