ESLint is already installed in my Angular project and linting all the typescript files. I have also written some set of rules for typescript files to display warnings instead of errors. But the rules I wrote for html didn't work. I am not able to lint my html files
eslintrc.json
{
"root": true,
"ignorePatterns": ["projects/**/*"],
"overrides": [
{
"files": ["*.ts"],
"parserOptions": {
"project": ["tsconfig.json", "e2e/tsconfig.json"],
"createDefaultProgram": true
},
"extends": [
"plugin:@angular-eslint/ng-cli-compat",
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "app",
"style": "kebab-case"
}
],
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
],
"@typescript-eslint/consistent-type-definitions": "error",
"@typescript-eslint/dot-notation": "off",
"@typescript-eslint/explicit-member-accessibility": [
"off",
{
"accessibility": "explicit"
}
],
"@typescript-eslint/no-use-before-define": "error",
"brace-style": ["warn", "1tbs"],
"id-blacklist": "off",
"id-match": "off",
"max-len": "off",
"no-underscore-dangle": "off",
"valid-typeof": "error",
"@typescript-eslint/member-ordering": "warn",
"@typescript-eslint/consistent-type-assertions": "warn",
"@typescript-eslint/type-annotation-spacing": "warn",
"@typescript-eslint/naming-convention": "warn",
"@typescript-eslint/quotes": "warn",
"@typescript-eslint/no-inferrable-types": "warn",
"@typescript-eslint/semi": "warn",
"@typescript-eslint/member-delimiter-style": "off",
"@typescript-eslint/no-unused-expressions": "warn",
"arrow-body-style": "warn",
"arrow-spacing": "warn",
"curly": "warn",
"eqeqeq": "warn",
"indent": ["warn", 2],
"max-line-length": "off",
"member-access": "off",
"no-bitwise": "warn",
"no-console": [
"warn",
{ "allow": ["info", "warn", "error", "time", "timeEnd", "trace"] }
],
"no-debugger": "warn",
"no-empty": "off",
"no-eval": "warn",
"no-shadow": "warn",
"no-string-literal": "off",
"no-trailing-spaces": "warn",
"no-var": "warn",
"object-literal-sort-keys": "off",
"prefer-const": "warn",
"quote-props": "warn",
"radix": "warn",
"space-before-blocks": "warn",
"space-infix-ops": "warn",
"space-in-parens": "warn",
"no-multi-spaces": "warn",
"comma-dangle": "warn",
"default-case": "warn",
"eol-last": "warn",
"guard-for-in": "warn",
"key-spacing": "warn",
"keyword-spacing": "warn",
"no-extra-parens": "warn",
"no-extra-semi": "warn",
"no-multiple-empty-lines": "warn",
"no-unused-expressions": "warn",
"variable-name": "off"
}
},
{
"files": ["*.html"],
"extends": ["plugin:@angular-eslint/template/recommended"],
"rules": {
"eqeqeq": "warn",
"indent": ["warn", 2],
}
}
]
}
package.json
{
"name": "cat",
"version": "1.0.1",
"license": "MIT",
"scripts": {
"build-high": "node --max_old_space_size=7000 ./node_modules/@angular/cli/bin/ng build --prod --output-hashing=all",
"ng": "ng",
"start": "ng serve --host 0.0.0.0",
"serve": "set NODE_OPTIONS=--max_old_space_size=8192 & ng serve --open",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"build-prod": "node ./replace.build.js && ng build --prod --aot=false",
"bundle-analyze": "node --max_old_space_size=7000 ./node_modules/@angular/cli/bin/ng build --prod --stats-json && webpack-bundle-analyzer dist/stats-es2015.json"
},
"private": true,
"dependencies": {
"@agm/core": "^1.1.0",
"@amcharts/amcharts3-angular": "^2.2.4",
"@amcharts/amcharts4": "^4.10.21",
"@angular/animations": "^8.2.0",
"@angular/common": "^8.2.0",
"@angular/compiler": "^8.2.0",
"@angular/core": "^8.2.0",
"@angular/forms": "^8.2.0",
"@angular/platform-browser": "^8.2.0",
"@angular/platform-browser-dynamic": "^8.2.0",
"@angular/router": "^8.2.0",
"@angular/service-worker": "^8.2.0",
"@types/lodash": "^4.14.104",
"ag-grid-angular": "^25.2.0",
"ag-grid-community": "^25.2.0",
"angular-font-awesome": "^3.0.3",
"angular2-counto": "^1.2.5",
"angular2-text-mask": "^8.0.4",
"angular2-tinymce": "^2.1.2",
"auth0-js": "^9.15.0",
"auth0-lock": "^11.29.0",
"d3": "^4.12.2",
"d3-scale-chromatic": "^1.3.3",
"dom-autoscroller": "^2.3.4",
"file-saver": "^2.0.5",
"font-awesome": "^4.7.0",
"html2canvas": "^1.0.0-rc.7",
"jspdf": "^2.3.1",
"lodash": "^4.17.21",
"moment": "^2.29.1",
"ng2-dragula": "^2.1.1",
"ng2-pdf-viewer": "^6.4.1",
"radial-progress-chart": "0.0.4",
"rxjs": "^6.6.7",
"rxjs-compat": "^6.6.7",
"signalr-no-jquery": "^0.2.0",
"tslib": "^2.2.0",
"underscore.deepclone": "^0.1.3",
"webpack-bundle-analyzer": "^3.9.0",
"xlsx": "^0.16.9",
"zone.js": "^0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.803.20",
"@angular-eslint/builder": "1.2.0",
"@angular-eslint/eslint-plugin": "1.2.0",
"@angular-eslint/eslint-plugin-template": "1.2.0",
"@angular-eslint/schematics": "1.2.0",
"@angular-eslint/template-parser": "1.2.0",
"@angular/cdk": "^8.2.3",
"@angular/cli": "^8.2.0",
"@angular/compiler-cli": "^8.2.0",
"@angular/language-service": "^8.2.0",
"@types/googlemaps": "^3.43.3",
"@types/jasmine": "^3.7.0",
"@types/jasminewd2": "^2.0.9",
"@types/node": "^15.0.2",
"@typescript-eslint/eslint-plugin": "4.3.0",
"@typescript-eslint/parser": "4.3.0",
"codelyzer": "^6.0.1",
"eslint": "^7.6.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsdoc": "30.7.6",
"eslint-plugin-prefer-arrow": "1.2.2",
"jasmine-core": "^3.7.1",
"jasmine-spec-reporter": "^7.0.0",
"karma": "^6.3.2",
"karma-chrome-launcher": "^3.1.0",
"karma-cli": "^2.0.0",
"karma-coverage-istanbul-reporter": "^3.0.3",
"karma-jasmine": "^4.0.1",
"karma-jasmine-html-reporter": "^1.6.0",
"protractor": "^7.0.0",
"replace-in-file": "^6.2.0",
"ts-node": "^9.1.1",
"typescript": "^3.5.3",
"webpack": "^4.46.0"
}
}
angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"cat": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"tsConfig": "src/tsconfig.app.json",
"polyfills": "src/polyfills.ts",
"assets": [
"src/assets",
"src/favicon.ico",
"src/Web.config"
],
"styles": [
"src/styles.scss",
"node_modules/font-awesome/scss/font-awesome.scss",
"node_modules/ag-grid-community/dist/styles/ag-grid.css",
"node_modules/ag-grid-community/dist/styles/ag-theme-balham.css"
],
"scripts": []
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"serviceWorker": true,
"ngswConfigPath": "src/ngsw-config.json",
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "cat:build"
},
"configurations": {
"production": {
"browserTarget": "cat:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "cat:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"karmaConfig": "./karma.conf.js",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"scripts": [],
"styles": [
"src/styles.scss",
"node_modules/font-awesome/scss/font-awesome.scss",
"node_modules/ag-grid-community/dist/styles/ag-grid.css",
"node_modules/ag-grid-community/dist/styles/ag-theme-balham.css"
],
"assets": [
"src/assets",
"src/favicon.ico",
"src/Web.config"
]
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
}
}
},
"cat-e2e": {
"root": "e2e",
"sourceRoot": "e2e",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "./protractor.conf.js",
"devServerTarget": "cat:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"e2e/tsconfig.e2e.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "cat",
"schematics": {
"@schematics/angular:component": {
"prefix": "app",
"styleext": "scss"
},
"@schematics/angular:directive": {
"prefix": "app"
}
}
}
I tried writing rules for html files. You can find 2 rules, "eqeqeq" and "indent" at the bottom of my eslintre.json file. And my expectations were that it would start linting html files just like I it is linting all typescript files of my project.
You are trying to apply rules which are designed to run on JavaScript code on your Angular templates. This does not work, the rules understand JavaScript syntax but don't understand Angular's template syntax.
For the
eqeqeq
rule, luckily the Angular ESLint template plugin contains an equivalent rule@angular-eslint/template/eqeqeq
. You can set up the rule like the following:For the
indent
rule there is no equivalent rule in Angular ESLint. They will never add such rule, because it's formatting related and they decided to stop implementation of formatting related rules. You would need to implement a custom ESLint rule. For easier implementation you can use Angular ESLint's template parser.