18

I have an Angular 10 app set up with eslint and prettier, which worked fine so far for linting Typescript files. I'm now trying to lint my component template files as well following this doc.

But when I run it with eslint . --ext .js,.ts,.component.html --fix I keep getting

Error while loading rule '@typescript-eslint/dot-notation': You have used a rule which requires parserServices to be generated. You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser.

My .eslintrc.js looks like this (note the second block in the overrides section):

module.exports = {
  extends: [
    "plugin:@angular-eslint/recommended",
    // For spec files
    "plugin:jasmine/recommended",
    // AirBnB Styleguide rules
    "airbnb-typescript/base",
    // Settings for Prettier
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended",
  ],
  plugins: [
    "prettier",
    "jasmine",
  ],
  rules: {
    "import/no-unresolved": "off",
    "@angular-eslint/component-selector": [
      "error", { type: "element", prefix: "icc", style: "kebab-case" }
    ],
    "@angular-eslint/directive-selector": [
      "error", { type: "attribute", prefix: "icc", style: "camelCase" }
    ],
    "import/extensions": "off",
    "@typescript-eslint/lines-between-class-members": "off",
    "lines-between-class-members": "off",
    "class-methods-use-this": "off",
    "import/prefer-default-export": "off",
    "prettier/prettier": ["error", {
      "endOfLine":"auto"
    }],
  },
  parser: "@typescript-eslint/parser",
  parserOptions: {
    project: "./tsconfig.app.json",
    ecmaVersion: 2020,
    sourceType: "module",
  },
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.ts', '.js'],
        moduleDirectory: ['node_modules', 'src/app'],
      }
    }
  },
  overrides: [
    {
      files: ["*.component.ts"],
      parser: "@typescript-eslint/parser",
      parserOptions: {
        project: "./tsconfig.app.json",
        ecmaVersion: 2020,
        sourceType: "module",
      },
      plugins: ["@angular-eslint/template"],
      processor: "@angular-eslint/template/extract-inline-html",
    },
    {
      files: ["*.component.html"],
      parser: "@angular-eslint/template-parser",
      parserOptions: {
        project: "./tsconfig.app.json",
        ecmaVersion: 2020,
        sourceType: "module",
      },
      plugins: ["@angular-eslint/template"],
    },
    {
      files: ["src/**/*.spec.ts", "src/**/*.d.ts"],
      parser: "@typescript-eslint/parser",
      parserOptions: {
        project: "./tsconfig.spec.json",
        ecmaVersion: 2020,
        sourceType: "module",
      },
      // Jasmine rules
      extends: ["plugin:jasmine/recommended"],
      // Plugin to run Jasmine rules
      plugins: ["jasmine"],
      env: { jasmine: true },
    }
  ],
};

As you can see I specify parserOptions.project everywhere. I'm especially confused that the error message complains about something relating to @typescript-eslint/parser which is not the parser that should be used anyway for templates. Removing the parserOptions block from the overrides section does not make a difference.

I could set "@typescript-eslint/dot-notation": "off" for all the rules it complains about but obviously that's not ideal. Can somebody point me towards what I'm missing?

UPDATE: I've turned off all type-aware rules as Brad suggested. However, the error I'm now getting is:

TypeError: Cannot read property 'length' of undefined
Occurred while linting /path/to/src/app/app.component.html:1
    at getUseStrictDirectives (/path/to/node_modules/eslint/lib/rules/strict.js:27:36)

But my app.component.html just looks like this:

<div class="content-root">
  <router-outlet></router-outlet>
</div>

So once again, I'm lost.

UPDATE 2: I've finally managed to get it working by turning rule after rule off for the template parser as Brad suggested in his answer. My working overrides block now looks like this:

{
  files: ["*.component.html"],
  parser: "@angular-eslint/template-parser",
  rules: {
    "@typescript-eslint/dot-notation": "off",
    "@typescript-eslint/no-implied-eval": "off",
    "@typescript-eslint/no-throw-literal": "off",
    "strict": "off",
    "import/first": "off",
    "lines-around-directive": "off"
  },
  plugins: ["@angular-eslint/template"],
},
1
  • For i18n localization template rules look here on SO Commented May 22, 2021 at 17:18

1 Answer 1

23

Your config here overrides the parser used for angular templates. This means that you're not using @typescript-eslint/parser to parse your angular templates.

{
  files: ["*.component.html"],
  parser: "@angular-eslint/template-parser",
  parserOptions: {
    project: "./tsconfig.app.json",
    ecmaVersion: 2020,
    sourceType: "module",
  },
  plugins: ["@angular-eslint/template"],
},

This makes sense, because @typescript-eslint/parser cannot understand angular templates.

However @angular-eslint/template-parser also does not have the infrastructure required to provide the information for type-aware linting.

This is why the lint rule fails on your file.

You need to disable all type-aware lint rules on your files parsed with @angular-eslint/template-parser

This FAQ article includes information about how to disable type-aware rules on such files https://typescript-eslint.io/troubleshooting/#i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file

Specifically something like this should work with the new flat config format using typescript-eslint's config util

export default tseslint.config(
  // ...
  {
    files: ["**/*.component.html"],
    extends: [tseslint.configs.disableTypeChecked],
  },
);

Or without the config util:

export default [
  // ...
  {
    files: ["**/*.component.html"],
    ...tseslint.configs.disableTypeChecked,
  },
];
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the clarification. I've updated my question with a new problem.
I don't know much about angular-eslint, but I would say that the way in which the project works means that you have to disable all standard eslint lint rules on an angular template file.
You were right, I managed to get it working now and updated my answer accordingly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.