angular-eslint: Crash when running ng lint

version: “0.0.1-alpha.23”

> cat /private/var/folders/qx/l6dzbht15fj_s89bxrv7x7740000gp/T/ng-JaEvnr/angular-errors.log

[error] TypeError: Cannot read property 'range' of undefined
    at /path/to/angular_project/node_modules/@angular-eslint/eslint-plugin-template/dist/index.js:1:1353
    at Array.map (<anonymous>)
    at postprocess (/path/to/angular_project/node_modules/@angular-eslint/eslint-plugin-template/dist/index.js:1:1156)
    at Linter._verifyWithProcessor (/path/to/angular_project/node_modules/eslint/lib/linter/linter.js:1311:16)
    at Linter._verifyWithConfigArray (/path/to/angular_project/node_modules/eslint/lib/linter/linter.js:1248:25)
    at Linter.verify (/path/to/angular_project/node_modules/eslint/lib/linter/linter.js:1210:25)
    at Linter.verifyAndFix (/path/to/angular_project/node_modules/eslint/lib/linter/linter.js:1400:29)
    at verifyText (/path/to/angular_project/node_modules/eslint/lib/cli-engine/cli-engine.js:230:48)
    at CLIEngine.executeOnFiles (/path/to/angular_project/node_modules/eslint/lib/cli-engine/cli-engine.js:798:28)
    at _lint (/path/to/angular_project/node_modules/@angular-eslint/builder/dist/index.js:1:4477)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 18 (8 by maintainers)

Most upvoted comments

Ha I always knew that quick prototyping work I did would stay in until it caused an actual issue. I’ll try and take a look later on, will likely make it AST based instead of string manipulation

I’m getting a similar error, eslint crashes on a component template. This is my .eslintrc.js:

// https://github.com/angular/angular-cli/issues/13732
// https://github.com/angular-eslint/angular-eslint
// https://github.com/angular-eslint/angular-eslint/blob/master/packages/integration-tests/fixtures/angular-cli-workspace/.eslintrc.js
// https://code.visualstudio.com/api/advanced-topics/tslint-eslint-migration

module.exports = {
    "env": {
        "browser": true,
        "node": true
    },
    "overrides": [
        {
            "files": ["*.ts"],
            "parser": "@typescript-eslint/parser",
            "parserOptions": {
                "project": "tsconfig.json",
                "sourceType": "module",
                "ecmaVersion": 2020
            },
            "plugins": [
                "@typescript-eslint",
                "@angular-eslint",
                "import"
//              "deprecate"
            ],
            "rules": {
                // angular-eslint [start]
                "@typescript-eslint/array-type": "off",
                "arrow-parens": "off",
                "@angular-eslint/component-class-suffix": "error",
                "@angular-eslint/contextual-lifecycle": "error",
                "@angular-eslint/directive-selector": [
                    "error",
                    { type: "attribute", prefix: "agora", style: "camelCase" }
                ],
                "@angular-eslint/component-selector": [
                    "error",
                    { type: "element", prefix: "agora", style: "kebab-case" }
                ],        
                "@typescript-eslint/interface-name-prefix": "off",
                "max-classes-per-file": "off",
                "@typescript-eslint/member-ordering": [
                    "error",
                    {
                        default: [
                            "static-field",
                            "instance-field",
                            "static-method",
                            "instance-method",
                        ]
                    }
                ],
                "no-multiple-empty-lines": "off",
                "no-restricted-syntax": [
                    "error",
                    {
                        selector: "CallExpression[callee.object.name=\"console\"][callee.property.name=/^(debug|info|time|timeEnd|trace)$/]",
                        message: "Unexpected property on console object was called"
                    }
                ],
                "@typescript-eslint/no-inferrable-types": [
                    "error",
                    {
                        ignoreParameters: true
                    }
                ],        
                "@typescript-eslint/no-var-requires": "off",
                "quote-props": ["error", "as-needed"],
                "sort-keys": "off",
                "comma-dangle": "off",
                "@angular-eslint/no-conflicting-lifecycle": "error",
                "@angular-eslint/no-host-metadata-property": "error",
                "@angular-eslint/no-input-rename": "error",
                "@angular-eslint/no-inputs-metadata-property": "error",
                "@angular-eslint/no-output-native": "error",
                "@angular-eslint/no-output-on-prefix": "error",
                "@angular-eslint/no-output-rename": "error",
                "@angular-eslint/no-outputs-metadata-property": "error",
                "@angular-eslint/use-lifecycle-interface": "warn",
                "@angular-eslint/use-pipe-transform-interface": "error",
                // angular-eslint [end]
                "@typescript-eslint/class-name-casing": "error",
                "@typescript-eslint/consistent-type-definitions": "error",
                "@typescript-eslint/explicit-member-accessibility": [
                    "off",
                    {
                        "accessibility": "explicit"
                    }
                ],
                "@typescript-eslint/indent": [
                    "warn",
                    4,
                    {
                        "ignoreComments": true,
                        "ignoredNodes": ["TSTypeParameterInstantiation"],
                        "SwitchCase": 1,
                        "VariableDeclarator": 1,
                        "MemberExpression": 1,
                        "FunctionDeclaration": { "body": 1, "parameters": 1 },
                        "FunctionExpression":  { "body": 1, "parameters": 1 },
                        "ArrayExpression": 1,
                        "ObjectExpression": 1,
                        "ImportDeclaration": 1
                    }
                ],
                "@typescript-eslint/member-delimiter-style": [
                    "warn",
                    {
                        "multiline": {
                            "delimiter": "semi",
                            "requireLast": true
                        },
                        "singleline": {
                            "delimiter": "semi",
                            "requireLast": false
                        }
                    }
                ],
                "@typescript-eslint/no-empty-function": "off",
                "@typescript-eslint/no-empty-interface": "error",
                "@typescript-eslint/no-misused-new": "error",
                "@typescript-eslint/no-non-null-assertion": "error",
                "@typescript-eslint/prefer-function-type": "error",
                "@typescript-eslint/quotes": [
                    "warn",
                    "single"
                ],
                "@typescript-eslint/semi": [
                    "warn",
                    "always"
                ],
                "@typescript-eslint/type-annotation-spacing": "error",
                "@typescript-eslint/unified-signatures": "error",
                "arrow-body-style": "warn",
                "camelcase": "off",
                "constructor-super": "error",
                "curly": "error",
                "dot-notation": "off",
                "eol-last": "warn",
                "eqeqeq": [
                    "error",
                    "smart"
                ],
                "guard-for-in": "error",
                "id-blacklist": "off",
                "id-match": "off",
                "import/no-deprecated": "warn",
//              "deprecate/function": "warn",
//              "deprecate/import": "warn",
//              "deprecate/member-expression": "warn",
                "max-len": [
                    "error",
                    {
                        "ignoreRegExpLiterals": false,
                        "ignorePattern": "^import .*",
                        "code": 140
                    }
                ],
                "no-bitwise": "error",
                "no-caller": "error",
                "no-console": [
                    "error",
                    {
                        "allow": [
                            "log",
                            "dirxml",
                            "warn",
                            "error",
                            "dir",
                            "timeLog",
                            "assert",
                            "clear",
                            "count",
                            "countReset",
                            "group",
                            "groupCollapsed",
                            "groupEnd",
                            "table",
                            "Console",
                            "markTimeline",
                            "profile",
                            "profileEnd",
                            "timeline",
                            "timelineEnd",
                            "timeStamp",
                            "context"
                        ]
                    }
                ],
                "no-debugger": "error",
                "no-empty": "off",
                "no-eval": "error",
                "no-fallthrough": "error",
                "no-new-wrappers": "error",
                "no-restricted-imports": [
                    "error",
                    {
                        paths: [
                            {
                                name: "rxjs/Rx",
                                message: "Please import directly from 'rxjs' instead",
                            },
                        ],
                    }
                ],
                "no-shadow": [
                    "error",
                    {
                        "hoist": "all"
                    }
                ],
                "no-throw-literal": "error",
                "no-trailing-spaces": "warn",
                "no-undef-init": "error",
                "no-underscore-dangle": "off",
                "no-unused-expressions": "error",
                "no-unused-labels": "error",
                "no-var": "error",
                "prefer-const": "warn",
                "radix": "error",
                "spaced-comment": "error"
/*                
                "@typescript-eslint/tslint/config": [
                    "error",
                    {
                        "rules": {
                            "component-class-suffix": true,
                            "directive-class-suffix": true,
                            "import-spacing": true,
                            "no-host-metadata-property": true,
                            "no-input-rename": true,
                            "no-inputs-metadata-property": true,
                            "no-output-on-prefix": true,
                            "no-output-rename": true,
                            "no-outputs-metadata-property": true,
                            "one-line": [
                                true,
                                "check-open-brace",
                                "check-catch",
                                "check-else",
                                "check-whitespace"
                            ],
                            "use-life-cycle-interface": true,
                            "use-pipe-transform-interface": true,
                            "whitespace": [
                                true,
                                "check-branch",
                                "check-decl",
                                "check-operator",
                                "check-separator",
                                "check-type"
                            ]
                        }
                    }
                ]
*/                
            }
        },
        {
            files: ["*.component.html"],
            parser: "@angular-eslint/template-parser",
            plugins: ["@angular-eslint/template"],
            rules: {
                "@angular-eslint/template/banana-in-a-box": "error",
                "@angular-eslint/template/no-negated-async": "error",
            }
        }
    ]
};

@digeomel Thanks for sharing your config. I did not realize I needed to configure the .component.html rules separately from the .ts rules, nor did I see anything documenting the existence of overrides anywhere.

Additionally, the repo doesn’t explain that we need to use "@angular-eslint/template/banana-in-a-box" in order to use that rule - I was trying just banana-in-a-box and got nothing.

Also, I tried it as "@angular-eslint/template/banana-in-a-box" but didn’t realize we need to add the plugin ["@angular-eslint/template"] and the parser "@angular-eslint/template-parser". I didn’t know about the parser option at all!

A valid config object is almost always helpful! I suggest the readme could have some of these things updated to reflect these small little “gotchas”. 😄

Released v0.0.1-alpha.28

Thanks a lot for the detailed report! I did a quick investigation and looks like the issue happens due to “:”.

During the pre-processing of eslint-plugin-template the component decorator is parsed and the “:” is making the output of the parsing incomplete, triggering future errors.

The fix should be on this split (maybe use “String.prototype.match()” instead?): https://github.com/angular-eslint/angular-eslint/blob/266486e3c9870eb350aac9c7b41a7b8c7d9e5bbc/packages/eslint-plugin-template/src/processors.ts#L53

I don’t know if I will be able to work on it this weekend, so if anyone wants to take it, be free. If not I can check that later.