I’ve got an .eslintrc.json
file that enforces Angular template files (*.html
) to use self-closing tags (Angular 18.1 project). But for the life of me, I cannot figure out how to get that same rule to apply to inline templates. I’ve included the full file below (it’s pretty verbose). But I figured what I would just need to do is add this:
"@angular-eslint/template/prefer-self-closing-tags": "error",
…to the rules
section of the "files": [*.ts]
section. However, if I do that, I get this error:
You have used a rule which requires '@angular-eslint/template-parser' to be used as the 'parser' in your ESLint config.
If I add @angular-eslint/template-parser
to the extends
part of the *.ts
section, then I get:
Failed to load config "plugin:@angular-eslint/template-parser" to extend from
And anyway, I would have thought the "plugin:@angular-eslint/template/process-inline-templates",
would do the trick here, but it doesn’t.
Any help is appreciated.
Here’s the relevant section of my package.json file:
"@angular-devkit/build-angular": "^18.1.1",
"@angular-eslint/builder": "18.1.0",
"@angular-eslint/eslint-plugin": "18.1.0",
"@angular-eslint/eslint-plugin-template": "18.1.0",
"@angular-eslint/schematics": "18.1.0",
"@angular-eslint/template-parser": "18.1.0",
"@angular/cli": "^18.1.1",
"@angular/compiler-cli": "^18.1.1",
…and the complete .eslintrc.json
file:
{
"root": true,
"ignorePatterns": ["projects/**/*", "**/*.py", "dev_index.html"],
"overrides": [
{
"files": ["*.ts"],
"parserOptions": {
"project": ["./tsconfig.eslint.json"],
"createDefaultProgram": true
},
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates",
"plugin:prettier/recommended"
],
"plugins": ["rxjs"],
"rules": {
"@typescript-eslint/explicit-function-return-type": [
"off",
{
"allowExpressions": true
}
],
"no-await-in-loop": "error",
"no-extra-parens": "off",
"no-prototype-builtins": "off",
"no-template-curly-in-string": "error",
"valid-jsdoc": "off",
"@typescript-eslint/array-type": [
"off",
{
"default": "array"
}
],
"accessor-pairs": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": [
"off",
{
"vars": "all",
"args": "none",
"ignoreRestSiblings": true,
"caughtErrors": "none",
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_"
}
],
"array-callback-return": "error",
"block-scoped-var": "error",
"class-methods-use-this": "off",
"complexity": "off",
"consistent-return": "error",
"curly": "error",
"default-case": "error",
"dot-location": ["error", "property"],
"no-console": [
"off",
{
"allow": ["warn", "error"]
}
],
"dot-notation": "off",
"eqeqeq": "off",
"guard-for-in": "off",
"no-alert": "off",
"no-caller": "error",
"no-div-regex": "error",
"no-else-return": "off",
"no-empty-function": "off",
"no-eq-null": "error",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-label": "error",
"no-floating-decimal": "error",
"no-implicit-coercion": "off",
"no-implicit-globals": "error",
"no-implied-eval": "error",
"no-invalid-this": "off",
"no-iterator": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-loop-func": "error",
"no-magic-numbers": [
"off",
{
"ignore": [-1, 0, 1],
"ignoreArrayIndexes": true
}
],
"no-multi-spaces": [
"error",
{
"ignoreEOLComments": true,
"exceptions": {
"AssignmentExpression": true,
"ArrowFunctionExpression": true,
"CallExpression": true,
"VariableDeclarator": true
}
}
],
"no-multi-str": "error",
"no-new": "error",
"no-new-func": "off",
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-param-reassign": "off",
"no-proto": "error",
"no-restricted-properties": "error",
"no-return-assign": "error",
"no-return-await": "error",
"no-script-url": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-throw-literal": "error",
"no-unmodified-loop-condition": "error",
"no-unused-expressions": "off",
"no-useless-call": "error",
"no-useless-concat": "error",
"no-useless-return": "error",
"no-void": "error",
"no-warning-comments": "off",
"no-with": "error",
"prefer-promise-reject-errors": "error",
"radix": "error",
"require-await": "off",
"vars-on-top": "off",
"wrap-iife": "error",
"yoda": "error",
"strict": "error",
"init-declarations": "off",
"no-catch-shadow": "off",
"no-label-var": "error",
"no-restricted-globals": "error",
"no-shadow": "off",
"no-shadow-restricted-names": "error",
"no-undef-init": "error",
"no-undefined": "off",
"no-use-before-define": "off",
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "app",
"style": "kebab-case"
}
],
"rxjs/no-unsafe-takeuntil": [
"warn",
{ "alias": ["takeUntilDestroyed"] }
],
"rxjs/no-async-subscribe": ["warn"],
"rxjs/no-create": ["warn"],
"rxjs/no-index": ["warn"],
"rxjs/no-ignored-replay-buffer": ["warn"],
"rxjs/no-ignored-takewhile-value": ["warn"],
"rxjs/no-internal": ["warn"],
"rxjs/no-nested-subscribe": ["warn"],
"rxjs/no-redundant-notify": ["warn"],
"rxjs/no-subject-unsubscribe": ["warn"],
"rxjs/no-unbound-methods": ["warn"],
"rxjs/no-unsafe-subject-next": ["warn"]
}
},
{
"files": ["*.html"],
"extends": [
"plugin:@angular-eslint/template/recommended",
"plugin:prettier/recommended"
],
"rules": {
"@angular-eslint/template/label-has-associated-control": "off",
"@angular-eslint/template/valid-aria": "off",
"@angular-eslint/template/alt-text": "error",
"@angular-eslint/template/no-autofocus": "off",
"@angular-eslint/template/no-distracting-elements": "error",
"@angular-eslint/template/use-track-by-function": "off",
"@angular-eslint/template/prefer-self-closing-tags": "error"
}
},
{
"files": ["*.html"],
"excludedFiles": ["*inline-template-*.component.html"],
"extends": ["plugin:prettier/recommended"],
"rules": {
"prettier/prettier": [
"warn",
{
"parser": "angular"
}
]
}
}
]
}