How does one utilize the i18n template for eslint in Angular?

Viewed 939

I would like to be able to utilize the eslint angular template that checks for i18n tags as shown here https://github.com/angular-eslint/angular-eslint/blob/master/packages/eslint-plugin-template/src/rules/i18n.ts and listed here https://github.com/angular-eslint/angular-eslint#readme, but there isn't really any helpful instruction on how to activate it or what needs to be put in the config to make it work. I just need to know how to turn it "on" to start checking. Any help would be appreciated.

Update:

Here is an example of what I am trying (and failing) at doing:

In .eslintrc.json, I am trying to add @angular-eslint/template/i18n:

{
  "root": true,
  "ignorePatterns": [
    "projects/**/*"
  ],
  "overrides": [
    {
      "files": [
        "*.ts"
      ],
      "parserOptions": {
        "project": [
          "tsconfig.json"        ],
        "createDefaultProgram": true,
        "tsconfigRootDir": "",
        "ecmaVersion": 2017
      },
        "env": {
            "es6": 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": {
        "arrow-body-style": 0,
        "@typescript-eslint/naming-convention": [
            "error",
            {
                "selector": "enumMember",
                "format": [
                    "camelCase",
                    "UPPER_CASE"
                ]
            }
        ],
        "@typescript-eslint/consistent-type-definitions": "error",
        "@typescript-eslint/dot-notation": "off",
        "@typescript-eslint/explicit-member-accessibility": [
          "off",
          {
            "accessibility": "explicit"
          }
        ],
        "@typescript-eslint/no-non-null-assertion": "off",
        "brace-style": [
          "error",
          "1tbs"
        ],
        // note you must disable the base rule as it can report incorrect errors
        "no-shadow": "off",
        "@typescript-eslint/no-shadow": [
            "error"
        ]
      }
    },
    {
      "files": [
        "*.html"
      ],
      "extends": [
        "plugin:@angular-eslint/template/recommended"
      ],
      "rules": {
        "@angular-eslint/template/i18n": [
            "warn",
            { "items": ["check-id", "check-text"] }
        ]
      }
    }
  ]
}

When I do this, I get the error:

An unhandled exception occurred: .eslintrc.json#overrides[1]:
        Configuration for rule "@angular-eslint/template/i18n" is invalid:
        Value {"items":["check-id","check-text"],"checkId":true,"checkText":true,"checkAttributes":true,"ignoreAttributes":["charset","class","color","colspan","fill","formControlName","height","href","id","lang","src","stroke","stroke-width","style","svgIcon","tabindex","target","type","viewBox","width","xmlns"]} should NOT have additional properties.

If I change the name from @angular-eslint/template/i18n to template-i18n, it runs and scans all of my .html files, but returns an error for each one that says 1:1 error Definition for rule 'template-i18n' was not found template-i18n

2 Answers

Hello I updated per maplion's comments

Assuming its the i18n build and try to help you setup the build for localization i.e. i18n. Try these two options, the first is to configure your build with the i18n build. Second, is use another lib i18n-Lint which is easier IMHO. Short answer this enables the template you want to use "template-i18n": [true, "check-id", "check-text"]


First setup you schema on what you want to check, i.e. just id, strings or both in .eslintrc.json:

 // per MapLions feedback, i updated the full section, mine is different
 { 
 //  1 - tell it which files you want
  "files": [
    "*.html"
  ],
  // 2 - include this plugin
  "extends": [
    "plugin:@angular-eslint/template/recommended"
  ],
  "rules": {
    "@angular-eslint/template/i18n": [
        "warn",
        { // 3 - setup your rules here
            "checkId": true,
            "checkText": true,
            "checkAttributes": true
        }
    ]
  }
 }
  ...

Then enable it like so.

"template-i18n": [true, "check-id", "check-text"]
  • check-id Makes sure i18n attributes have ID specified
  • check-text Makes sure there are no elements with text content but no i18n attribute

in your rules setup up "@angular-eslint/template/i18n": "warn", then in your build you can setup the extract or tests

  {
    "name": myapp...",
    "version": "..",
    "angular-cli": {},
    "scripts": {
        "------------- your app -----------": "",
        "start": "ng serve --configuration=test --proxy-config proxy.conf.json --live-reload false",
./node_modules/@angular/cli/bin/ng build --configuration=prod-en-us",
        "build:prod:fr-ca": "node --max_old_space_size=10240 ./node_modules/@angular/cli/bin/ng build --configuration=prod-fr-ca",
        "build:prod:multilang": "npm run build:prod:en-us & npm run build:prod:fr-ca",
        "build:debug": "node --max_old_space_size=10240 ./node_modules/@angular/cli/bin/ng build --configuration=prod-en-us --verbose",

        
        "extract-i18n-html": "ng xi18n --output-path locale",
        "extract-i18n-ts": "ngx-extractor --input src/**/*.ts --format=xlf --out-file=src/locale/messages.xlf",
        "extract-i18n": "npm run extract-i18n-html & npm run extract-i18n-ts",
        "merge-i18n": "xliffmerge --profile xliffmerge.json -v",
        "i18n": "./node_modules/.bin/ng-xi18n --i18nFormat=xlf",
        "lint": "tslint \"src/**/*.ts",

        ....
        "------------- setup build for yourComponents -----------": "",
        "start:...",
        "build:...",
        "build:myComponents:prod:multilang": "npm run build:myComponents:prod:en-us & npm run build:myComponents:prod:fr-ca",
        "extract-i18n-html:myComponents": "ng xi18n myComponents --output-path src/locale",
        "extract-i18n-ts:myComponents": "ngx-extractor --input projects/myComponents/**/*.ts --format=xlf --out-file=projects/myComponents/src/locale/messages.xlf",
        "extract-i18n:myComponents": "npm run extract-i18n-html:myComponents & npm run extract-i18n-ts:myComponents",
        "merge-i18n:myComponents": "xliffmerge --profile projects/myComponents/xliffmerge.json -v",

        ...
        "------------- your  tests -----------": "",
        "test": "ng test",
        ...
    },
    "private": true,
    "dependencies": {
        "@angular/animations": "7.0.2",
        ...
        "@ngx-translate/i18n-polyfill": "0.2.0",
        ...
    },
    "devDependencies": {
        "@angular-devkit/build-angular": "0.10.3",
        ...
        "ngx-i18nsupport": "0.16.2",
        ....
    }
}

Option 2: i18n-lint

Use https://www.npmjs.com/package/i18n-lint

i18n--lint for linting angular typescript internationalization or localization

CLI
Installing i18n-lint globally via npm gives you the i18n-lint binary.

        $ npm install -g jwarby/i18n-lint
        
        $ i18n-lint --help

Usage: i18n-lint [OPTIONS] <file ...>

  Options:

    -h, --help                              output usage information
    -V, --version                           output the version number
    -a, --attributes <attributes>           Comma-separated list of HTML attributes to lint (default: 'alt,title')
    -i, --ignore-tags <tags>                Comma-separated list of names of tags to ignore whilst linting (default: 'script,style')
    -t, --template-delimiters <delimiters>  Template delimiters used in source files.  For example, Mustache-like templating languages should use ''
    -r, --reporter <reporter>               Specify which reporter to output results with
    --exclude <exclusion patterns>          Comma-separated list of glob patterns to ignore,  e.g. "/test_subdir/,ignored.html"
    --color                                 Force colored output
    --no-color                              Disable colored output

  Use `man i18n-lint` for more information
API
i18n-lint can be used in other projects as a library. After installing, simply require the module.

        $ npm install --save jwarby/i18n-lint
        
        var i18nlint = require('i18n-lint');

// Lint a file
var errors = i18nlint('myfile.html', {
  // ... options ...
});

// Lint a string
var errors = i18nlint.scan('<div>Untranslated String!</div>', {
  // ...options...

You can then use it

CLI
After installing, you should be able to type i18n-lint into a terminal.
# Display version and exit
$ i18n-lint --version

# Lint myfile.html
$ i18n-lint myfile.html

# Lint all HTML files using a glob pattern
$ i18n-lint views/**/*.html

# Set options using --<option name> <optionValue>
$ i18n-lint --some-option "someValue" views/**/*.html
      

Mr. Transformer set me on the right track and I was able to get his Option 1 to work with the following in .eslintrc.json:

      ...
      "rules": {
        "@angular-eslint/template/i18n": [
            "warn",
            { 
                "checkId": true,
                "checkText": true,
                "checkAttributes": true
            }
        ]
      }
      ...

Here's the full .eslintrc.json for reference:

{
  "root": true,
  "ignorePatterns": [
    "projects/**/*"
  ],
  "overrides": [
    {
      "files": [
        "*.ts"
      ],
      "parserOptions": {
        "project": [
          "tsconfig.json"        ],
        "createDefaultProgram": true,
        "tsconfigRootDir": "",
        "ecmaVersion": 2017
      },
        "env": {
            "es6": 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": {
        "arrow-body-style": 0,
        "@typescript-eslint/naming-convention": [
            "error",
            {
                "selector": "enumMember",
                "format": [
                    "camelCase",
                    "UPPER_CASE"
                ]
            }
        ],
        "@typescript-eslint/consistent-type-definitions": "error",
        "@typescript-eslint/dot-notation": "off",
        "@typescript-eslint/explicit-member-accessibility": [
          "off",
          {
            "accessibility": "explicit"
          }
        ],
        "@typescript-eslint/no-non-null-assertion": "off",
        "brace-style": [
          "error",
          "1tbs"
        ],
        // note you must disable the base rule as it can report incorrect errors
        "no-shadow": "off",
        "@typescript-eslint/no-shadow": [
            "error"
        ]
      }
    },
    {
      "files": [
        "*.html"
      ],
      "extends": [
        "plugin:@angular-eslint/template/recommended"
      ],
      "rules": {
        "@angular-eslint/template/i18n": [
            "warn",
            { 
                "checkId": true,
                "checkText": true,
                "checkAttributes": true
            }
        ]
      }
    }
  ]
}

Related