-2

I have two commands written in my package.json file-

"format": "prettier --write \"{src,{tests,mocks}}/**/*.{js,ts,vue}\"",
"lint": "eslint . -c .eslintrc.js --rulesdir eslint-internal-rules/ --ext .ts,.js,.vue,.tsx,.jsx --fix --ignore-path .gitignore", 

First I do run npm run format and then I run npm run lint. The behavior I am noticing on running those commands back and forth-

  1. npm run format - All okay
  2. npm run lint - Few files are showing changes
  3. npm run format - Changes gone
  4. np run lint - Changes come again

And the changes which are showing on npm run lint are having spacing changes and in some files having multi-line code to a single lines, like this-

enter image description here

enter image description here

enter image description here

It seems that the format which Prettier chooses, Eslint is reverting it back as per its own rules.

Here is my .prettierrc file-

{
    "semi": true,
    "trailingComma": "none",
    "singleQuote": true,
    "printWidth": 80,
    "arrowParens": "avoid"
}

and here is my .eslintrc.js file-

module.exports = {
  ...,
  extends: [
    ...,
    'prettier',
  ],
  ...,
  plugins: [
    ...,
    'prettier',
  ],
  
    // indentation (Already present in TypeScript)
    'indent': ['error', 2, { SwitchCase: 1 }],
    'no-tabs': ['error', { allowIndentationTabs: true }],

    // Enforce trailing comma (Already present in TypeScript)
    'comma-dangle': [0, 'always-multiline'],

    // Enforce consistent spacing inside braces of object (Already present in TypeScript)
    'object-curly-spacing': ['error', 'always'],

    // Disable max-len
    'max-len': 'off',

    // max-statements-per-line
    'max-statements-per-line': ['error', { max: 2 }],

    // we don't want it
    'semi': [ 0, 'never'],

    // add parens ony when required in arrow function
    'arrow-parens': ['error', 'as-needed'],

    // add new line above comment
    'newline-before-return': 'error',

    // add new line above comment
    'lines-around-comment': [
      'error',
      {
        beforeBlockComment: true,
        beforeLineComment: false,
        allowBlockStart: true,
        allowClassStart: true,
        allowObjectStart: true,
        allowArrayStart: true,
      },
    ],

    'array-element-newline': ['error', 'consistent'],
    'array-bracket-newline': ['error', 'consistent'],

    'vue/multi-word-component-names': 'off',

    'padding-line-between-statements': [
      0,
      { blankLine: 'always', prev: 'expression', next: 'const' },
      { blankLine: 'always', prev: 'const', next: 'expression' },
      { blankLine: 'always', prev: 'multiline-const', next: '*' },
      { blankLine: 'always', prev: '*', next: 'multiline-const' },
    ],

    // Plugin: eslint-plugin-import
    'import/prefer-default-export': 'off',
    'import/newline-after-import': ['error', { count: 1 }],

    // Plugin: eslint-plugin-import
    // For omitting extension for ts files
    'import/extensions': [
      'error',
      'ignorePackages',
      {
        js: 'never',
        jsx: 'never',
        ts: 'never',
        tsx: 'never',
      },
    ],

    // ignore virtual files
    'import/no-unresolved': [2, {
      ignore: [
        '~pages$',
        'virtual:generated-layouts',

        // Ignore vite's ?raw imports
        '.*\?raw',
      ],
    }],

    'import/no-named-as-default': 0,

    // Thanks: https://stackoverflow.com/a/63961972/10796681
    'no-shadow': 'off',
    '@typescript-eslint/no-shadow': ['error'],

    '@typescript-eslint/consistent-type-imports': 'error',
    '@typescript-eslint/no-non-null-assertion': 'warn',

    // Plugin: eslint-plugin-promise
    'promise/always-return': 'off',
    'promise/catch-or-return': 'off',

    // ESLint plugin vue
    'vue/singleline-html-element-content-newline': 'off',
    'vue/multiline-html-element-content-newline': 'off',
    'vue/block-tag-newline': 'error',
    'vue/component-api-style': 'error',
    'vue/component-name-in-template-casing': ['error', 'PascalCase', { registeredComponentsOnly: false }],
    'vue/custom-event-name-casing': ['error', 'camelCase', {
      ignores: [
        '/^(click):[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?/',
      ],
    }],
    'vue/define-macros-order': 'error',
    'vue/html-comment-content-newline': 'error',
    'vue/html-comment-content-spacing': 'error',
    'vue/html-comment-indent': 'error',
    'vue/match-component-file-name': 'error',
    'vue/no-child-content': 'error',

    // -- Extension Rules
    'vue/no-irregular-whitespace': 'error',
    'vue/template-curly-spacing': 'error',

    // -- Sonarlint
    'sonarjs/no-duplicate-string': 'off',
    'sonarjs/no-nested-template-literals': 'off',

    // Internal Rules
    'valid-appcardcode-code-prop': 'off',
    'valid-appcardcode-demo-sfc': 'off',
  },
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.ts', '.js', '.tsx', '.jsx', '.mjs'],
      },
      typescript: {},
    },
  },
}

If the npm run format is not giving any changes then how can I make my npm run lint to follows the same formatting rules of prettier so that Eslint only gives the linting errors, not the formatting errors?

Neha Soni
  • 3,935
  • 2
  • 10
  • 32

1 Answers1

1

TLDR;

You added some rules to the ESLint configuration in .eslintrc.js. You must remove all formatting-related rules from there. For example: indent, no-tabs, etc.

Explanation

ESLint and Prettier have some rules conflicting with each other because ESLint historically has some formatting rules which shouldn't be there in the first place. eslint-config-prettier provides a solution for this problem and turns off all the rules that are unnecessary or might conflict with Prettier.

You added eslint-config-prettier, which is correct. However, then you added the rules removed by eslint-config-prettier by your hand. They are the reason for this conflict.

You can find all formatting-related rules in eslint-config-prettier source.

If there is still conflict, remove all rules from .eslintrc.js and try to add the first 10 rules and check if the conflict still exists. If not, add the next 10 and continue to eliminate all conflicting rules.

Finally, configure .prettierrc to act the same for the removed rules. Please note Prettier is an opinionated tool, so some rules may not have equivalents in Prettier. You have to accept it as it is and cannot do anything for those.

özüm
  • 1,166
  • 11
  • 23
  • Thank you so much for your response. Let me try the ways you suggested. – Neha Soni Aug 09 '23 at 16:10
  • @NehaSoni, you're welcome. I hope it helps. – özüm Aug 10 '23 at 05:11
  • That's amazing. All spacing changes have been removed after commenting on the eslint tabs and indent rules. Just one more question- If you will take a look at the third image in the question, the left-hand side is changed by prettier which breaks the code into multiple lines, and the right-hand side is eslint which reverts it back to one line. Any idea how to sync this as well? – Neha Soni Aug 10 '23 at 05:28
  • 1
    Just a guess. Increase `printWidth` in `.prettierrc` and delete `max-len` and `max-statements-per-line` from `.eslintrc.js`. Maybe you try to delete `array-element-newline` and `array-bracket-newline`. It is not possible to know without deleting rules and testing the results. Nonetheless, you should delete all formatting rules because even if they do not seem to conflict today, they sure will in the future. – özüm Aug 11 '23 at 07:38
  • Thank you so much for your all suggestions. It helped a lot. – Neha Soni Aug 11 '23 at 08:28
  • @NehaSoni, you are welcome. – özüm Aug 11 '23 at 08:59