eslint-plugin-ember
v13.3.0
Published
ESLint plugin for Ember.js apps
Downloads
921,116
Readme
eslint-plugin-ember
An ESLint plugin that provides a set of rules for Ember applications based on commonly known good practices.
❗️Requirements
🚀 Usage
1. Install plugin
npm install --save-dev eslint-plugin-ember2. Update your config
// eslint.config.js (flat config)
const eslintPluginEmberRecommended = require('eslint-plugin-ember/configs/recommended');
module.exports = [
...eslintPluginEmberRecommended,
];or
// .eslintrc.js (legacy config)
module.exports = {
plugins: ['ember'],
extends: [
'eslint:recommended',
'plugin:ember/recommended' // or other configuration
],
rules: {
// override / enable optional rules
'ember/no-replace-test-comments': 'error'
}
};gts/gjs
lint files having First-Class Component Templates (fcct)
learn more at ember-template-imports
[!NOTE] special care should be used when setting up parsers, since they cannot be overwritten. thus they should be used in override only and specific to file types
gjs/gts support is provided by the ember-eslint-parser
[!NOTE] if you import .gts files in .ts files, then
ember-eslint-parseris required for .ts as well to enable typed linting
// .eslintrc.js
module.exports = {
overrides: [
{
files: ['**/*.{js,ts}'],
plugins: ['ember'],
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:ember/recommended', // or other configuration
],
rules: {
// override / enable optional rules
'ember/no-replace-test-comments': 'error'
}
},
{
files: ['**/*.gts'],
parser: 'ember-eslint-parser',
plugins: ['ember'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:ember/recommended',
'plugin:ember/recommended-gts',
],
},
{
files: ['**/*.gjs'],
parser: 'ember-eslint-parser',
plugins: ['ember'],
extends: [
'eslint:recommended',
'plugin:ember/recommended',
'plugin:ember/recommended-gjs',
],
},
{
files: ['tests/**/*.{js,ts,gjs,gts}'],
rules: {
// override / enable optional rules
'ember/no-replace-test-comments': 'error'
}
},
],
};rules applied to fcct templates
- semi rule, same as prettier plugin
- no-undef rule will take effect for template vars (includes js scope)
- no-unused rule will take effect for template block params
rules in templates can be disabled with eslint directives with mustache or html comments:
<template>
<div>
{{!eslint-disable-next-line}}
{{test}}
</div>
<div>
{{!--eslint-disable--}}
{{test}}
{{test}}
{{test}}
{{!--eslint-enable--}}
</div>
</template><template>
<div>
<!--eslint-disable-next-line-->
{{test}}
</div>
<div>
<!-- eslint-disable -->
{{test}}
{{test}}
{{test}}
<!-- eslint-enable -->
</div>
</template>Migrating from ember-template-lint
If you are replacing ember-template-lint with this plugin, use the template-lint-migration config to get the equivalent set of rules:
// eslint.config.js (flat config)
import eslintPluginEmberRecommended from 'eslint-plugin-ember/configs/recommended';
import eslintPluginEmberTemplateLintMigration from 'eslint-plugin-ember/configs/template-lint-migration';
export default [
...eslintPluginEmberRecommended,
...eslintPluginEmberTemplateLintMigration,
{
rules: {
// Migrate custom overrides from your .template-lintrc.*:
'ember/template-no-bare-strings': ['error', { allowlist: ['×'] }],
'ember/template-no-inline-styles': 'off',
},
},
];template-lint-migration mirrors the ember-template-lint recommended preset.
Linting .hbs files
ESLint flat config only picks up .hbs files when a files glob names them. Add a dedicated block so they route to the Handlebars parser:
// eslint.config.mjs
import { hbsParser, plugin as emberPlugin } from 'eslint-plugin-ember/recommended';
export default [
// ...other blocks...
{
files: ['app/**/*.hbs'],
languageOptions: { parser: hbsParser },
plugins: { ember: emberPlugin },
rules: {
'ember/template-no-bare-strings': 'error',
// ...other template rules...
},
},
];Make sure no earlier @typescript-eslint/parser block's files glob reaches .hbs — narrow it to ['**/*.{js,ts,gjs,gts}'] (or similar). Flat config merges rules across every matching block, so even if our HBS block overrides the parser, type-info rules from a matching TS block still layer on and fail with errors like:
Parsing error:
…was not found by the project service because the extension for the file (.hbs) is non-standard.
or
Error while loading rule
@typescript-eslint/await-thenable: You have used a rule which requires type information.
Replacing template-lint-disable comments
Inline disable directives need to be rewritten to ESLint's syntax, prefixed with ember/template-. For now, only two scopes are supported: the next line, or the rest of the file. For example, replace:
{{!template-lint-disable no-invalid-role}}with:
{{!eslint-disable-next-line ember/template-no-invalid-role}}The template-no-template-lint-directives rule (enabled by the template-lint-migration config) does this rewrite for you: run eslint --fix once and it converts every template-lint-disable / template-lint-enable comment in your templates.
To disable a rule for an entire .gjs/.gts file, use a regular ESLint file-level directive in the JS region — it applies to the <template> contents as well:
/* eslint-disable ember/template-no-invalid-role */
<template>
<div role="range"></div>
</template>🧰 Configurations
| | Name |
| :------------------------------ | :------------------------ |
| | base |
| ✅ | recommended |
| |
recommended-gjs |
| |
recommended-gts |
| 📋 | template-lint-migration |
🍟 Rules
💼 Configurations enabled in.
✅ Set in the recommended configuration. Set in the
recommended-gjs configuration. Set in the
recommended-gts configuration.
📋 Set in the template-lint-migration configuration.
🔧 Automatically fixable by the --fix CLI option.
💡 Manually fixable by editor suggestions.
Accessibility
| Name | Description | 💼 | 🔧 | 💡 | | :--------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------- | :- | :- | :- | | template-link-href-attributes | require href attribute on link elements | 📋 | | | | template-no-abstract-roles | disallow abstract ARIA roles | 📋 | | | | template-no-accesskey-attribute | disallow accesskey attribute | 📋 | 🔧 | | | template-no-aria-hidden-body | disallow aria-hidden on body element | 📋 | 🔧 | | | template-no-aria-unsupported-elements | disallow ARIA roles, states, and properties on elements that do not support them | 📋 | | | | template-no-autofocus-attribute | disallow autofocus attribute | 📋 | 🔧 | | | template-no-duplicate-landmark-elements | disallow duplicate landmark elements without unique labels | 📋 | | | | template-no-empty-headings | disallow empty heading elements | 📋 | | | | template-no-heading-inside-button | disallow heading elements inside button elements | 📋 | | | | template-no-invalid-aria-attributes | disallow invalid aria-* attributes | 📋 | | | | template-no-invalid-interactive | disallow non-interactive elements with interactive handlers | 📋 | | | | template-no-invalid-link-text | disallow invalid or uninformative link text content | 📋 | | | | template-no-invalid-link-title | disallow invalid title attributes on link elements | 📋 | | | | template-no-invalid-role | disallow invalid ARIA roles | 📋 | | | | template-no-nested-interactive | disallow nested interactive elements | 📋 | | | | template-no-nested-landmark | disallow nested landmark elements | 📋 | | | | template-no-pointer-down-event-binding | disallow pointer down event bindings | 📋 | | | | template-no-positive-tabindex | disallow positive tabindex values | 📋 | | | | template-no-redundant-role | disallow redundant role attributes | 📋 | 🔧 | | | template-no-unsupported-role-attributes | disallow ARIA attributes that are not supported by the element role | 📋 | 🔧 | | | template-no-whitespace-within-word | disallow excess whitespace within words (e.g. "W e l c o m e") | 📋 | | | | template-require-aria-activedescendant-tabindex | require non-interactive elements with aria-activedescendant to have tabindex | 📋 | 🔧 | | | template-require-context-role | require ARIA roles to be used in appropriate context | 📋 | | | | template-require-iframe-title | require iframe elements to have a title attribute | 📋 | | | | template-require-input-label | require label for form input elements | 📋 | | | | template-require-lang-attribute | require lang attribute on html element | 📋 | | | | template-require-mandatory-role-attributes | require mandatory ARIA attributes for ARIA roles | 📋 | | | | template-require-media-caption | require captions for audio and video elements | 📋 | | | | template-require-presentational-children | require presentational elements to only contain presentational children | 📋 | | | | template-require-valid-alt-text | require valid alt text for images and other elements | 📋 | | | | template-require-valid-form-groups | require grouped form controls to have fieldset/legend or WAI-ARIA group labeling | | | | | template-table-groups | require table elements to use table grouping elements | 📋 | | |
Best Practices
| Name | Description | 💼 | 🔧 | 💡 |
| :----------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------- | :- | :- | :- |
| template-builtin-component-arguments | disallow setting certain attributes on builtin components | 📋 | | |
| template-no-action-modifiers | disallow usage of {{action}} modifiers | | 🔧 | |
| template-no-action-on-submit-button | disallow action attribute on submit buttons | 📋 | | |
| template-no-args-paths | disallow args.foo paths in templates, use @foo instead | 📋 | 🔧 | |
| template-no-arguments-for-html-elements | disallow @arguments on HTML elements | 📋 | | |
| template-no-array-prototype-extensions | disallow usage of Ember Array prototype extensions | 📋 | 🔧 | |
| template-no-at-ember-render-modifiers | disallow usage of @ember/render-modifiers | 📋 | | |
| template-no-bare-strings | disallow bare strings in templates (require translation/localization) | | | |
| template-no-bare-yield | disallow templates whose only meaningful content is a bare {{yield}} | | | |
| template-no-block-params-for-html-elements | disallow block params on HTML elements | 📋 | | |
| template-no-builtin-form-components | disallow usage of built-in form components | 📋 | | |
| template-no-capital-arguments | disallow capital arguments (use lowercase @arg instead of @Arg) | 📋 | | |
| template-no-chained-this | disallow redundant this.this in templates | | 🔧 | |
| template-no-class-bindings | disallow passing classBinding or classNameBindings as arguments in templates | 📋 | | |
| template-no-curly-component-invocation | disallow curly component invocation, use angle bracket syntax instead | 📋 | 🔧 | |
| template-no-debugger | disallow {{debugger}} in templates | 📋 | | |
| template-no-duplicate-attributes | disallow duplicate attribute names in templates | 📋 | 🔧 | |
| template-no-duplicate-id | disallow duplicate id attributes | 📋 | | |
| template-no-dynamic-subexpression-invocations | disallow dynamic subexpression invocations | | | |
| template-no-element-event-actions | disallow element event actions (use {{on}} modifier instead) | | | |
| template-no-forbidden-elements | disallow specific HTML elements | 📋 | | |
| template-no-html-comments | disallow HTML comments in templates | 📋 | 🔧 | |
| template-no-implicit-this | require explicit this in property access | 📋 | | |
| template-no-index-component-invocation | disallow index component invocations | 📋 | | |
| template-no-inline-event-handlers | disallow DOM event handler attributes | | | |
| template-no-inline-linkto | disallow inline form of LinkTo component | | 🔧 | |
| template-no-inline-styles | disallow inline styles | 📋 | | |
| template-no-input-block | disallow block usage of {{input}} helper | 📋 | | |
| template-no-input-tagname | disallow tagName attribute on {{input}} helper | 📋 | | |
| template-no-invalid-meta | disallow invalid meta tags | 📋 | | |
| template-no-log | disallow {{log}} in templates | 📋 | | |
| template-no-model-argument-in-route-templates | disallow @model argument in route templates | | 🔧 | |
| template-no-multiple-empty-lines | disallow multiple consecutive empty lines in templates | | 🔧 | |
| template-no-mut-helper | disallow usage of (mut) helper | | | |
| template-no-negated-condition | disallow negated conditions in if/unless | 📋 | 🔧 | |
| template-no-nested-splattributes | disallow nested ...attributes usage | 📋 | | |
| template-no-obscure-array-access | disallow obscure array access patterns like [email protected] | 📋 | 🔧 | |
| template-no-obsolete-elements | disallow obsolete HTML elements | 📋 | | |
| template-no-outlet-outside-routes | disallow {{outlet}} outside of route templates | 📋 | | |
| template-no-page-title-component | disallow usage of ember-page-title component | | | |
| template-no-passed-in-event-handlers | disallow passing event handlers directly as component arguments | 📋 | | |
| template-no-positional-data-test-selectors | disallow positional data-test-* params in curly invocations | 📋 | 🔧 | |
| template-no-potential-path-strings | disallow potential path strings in attribute values | 📋 | | |
| template-no-redundant-fn | disallow unnecessary usage of (fn) helper | 📋 | 🔧 | |
| template-no-restricted-invocations | disallow certain components, helpers or modifiers from being used | | | |
| template-no-splattributes-with-class | disallow splattributes with class attribute | | | |
| template-no-template-lint-directives | disallow {{! template-lint-* }} directives (use the {{! eslint-* }} equivalents) | 📋 | 🔧 | |
| template-no-this-in-template-only-components | disallow this in template-only components | | 🔧 | |
| template-no-trailing-spaces | disallow trailing whitespace at the end of lines in templates | | 🔧 | |
| template-no-unavailable-this | disallow this in templates that are not inside a class or function | | | |
| template-no-unnecessary-component-helper | disallow unnecessary component helper | 📋 | 🔧 | |
| template-no-unnecessary-concat | disallow unnecessary string concatenation | | 🔧 | |
| template-no-unnecessary-curly-parens | disallow unnecessary parentheses enclosing statements in curlies | 📋 | 🔧 | |
| template-no-unused-block-params | disallow unused block parameters in templates | 📋 | | |
| template-no-valueless-arguments | disallow valueless named arguments | 📋 | | |
| template-no-whitespace-for-layout | disallow using whitespace for layout purposes | 📋 | | |
| template-no-yield-block-params-to-else-inverse | disallow yielding block params to else or inverse block | | | |
| template-no-yield-only | disallow components that only yield | 📋 | | |
| template-no-yield-to-default | disallow yield to default block | 📋 | | |
| template-require-button-type | require button elements to have a valid type attribute | 📋 | 🔧 | |
| template-require-each-key | require key attribute in {{#each}} loops | | 🔧 | |
| template-require-form-method | require form method attribute | | 🔧 | |
| template-require-has-block-helper | require (has-block) helper usage instead of hasBlock property | 📋 | 🔧 | |
| template-require-iframe-src-attribute | require iframe elements to have src attribute | | 🔧 | |
| template-require-input-type | require input elements to have a valid type attribute | | 🔧 | |
| template-require-splattributes | require splattributes usage in component templates | | | |
| template-require-strict-mode | require templates to be in strict mode | | | |
| template-require-valid-named-block-naming-format | require valid named block naming format | 📋 | 🔧 | |
| template-self-closing-void-elements | require self-closing on void elements | | 🔧 | |
| template-simple-modifiers | require simple modifier syntax | 📋 | | |
| template-simple-unless | require simple conditions in unless blocks | 📋 | 🔧 | |
| template-sort-invocations | require sorted attributes and modifiers | | 🔧 | |
| template-splat-attributes-only | disallow ...spread other than ...attributes | 📋 | | |
| template-style-concatenation | disallow string concatenation in inline styles | 📋 | | |
Components
| Name | Description | 💼 | 🔧 | 💡 |
| :------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------- | :- | :- | :- |
| no-attrs-in-components | disallow usage of this.attrs in components | ✅ | | |
| no-attrs-snapshot | disallow use of attrs snapshot in the didReceiveAttrs and didUpdateAttrs component hooks | ✅ | | |
| no-builtin-form-components | disallow usage of built-in form components | | | |
| no-classic-components | enforce using Glimmer components | ✅ | | |
| no-component-lifecycle-hooks | disallow usage of "classic" ember component lifecycle hooks. Render modifiers or custom functional modifiers should be used instead. | ✅ | | |
| no-on-calls-in-components | disallow usage of on to call lifecycle hooks in components | ✅ | | |
| require-tagless-components | disallow using the wrapper element of a component | ✅ | | |
Computed Properties
| Name | Description | 💼 | 🔧 | 💡 |
| :----------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------ | :- | :- | :- |
| computed-property-getters | enforce the consistent use of getters in computed properties | | | |
| no-arrow-function-computed-properties | disallow arrow functions in computed properties | ✅ | | |
| no-assignment-of-untracked-properties-used-in-tracking-contexts | disallow assignment of untracked properties that are used as computed property dependencies | ✅ | 🔧 | |
| no-computed-properties-in-native-classes | disallow using computed properties in native classes | ✅ | | |
| no-deeply-nested-dependent-keys-with-each | disallow usage of deeply-nested computed property dependent keys with @each | ✅ | | |
| no-duplicate-dependent-keys | disallow repeating computed property dependent keys | ✅ | 🔧 | |
| no-incorrect-computed-macros | disallow incorrect usage of computed property macros | ✅ | 🔧 | |
| no-invalid-dependent-keys | disallow invalid dependent keys in computed properties | ✅ | 🔧 | |
| no-side-effects | disallow unexpected side effects in computed properties | ✅ | | |
| no-volatile-computed-properties | disallow volatile computed properties | ✅ | | |
| require-computed-macros | require using computed property macros when possible | ✅ | 🔧 | |
| require-computed-property-dependencies | require dependencies to be declared statically in computed properties | ✅ | 🔧 | |
| require-return-from-computed | disallow missing return statements in computed properties | ✅ | | |
| use-brace-expansion | enforce usage of brace expansion in computed property dependent keys | ✅ | | |
Controllers
| Name | Description | 💼 | 🔧 | 💡 |
| :--------------------------------------------------------------------------------- | :------------------------------------ | :- | :- | :- |
| alias-model-in-controller | enforce aliasing model in controllers | | | |
| avoid-using-needs-in-controllers | disallow using needs in controllers | ✅ | | |
| no-controllers | disallow non-essential controllers | | | |
Deprecations
| Name | Description | 💼 | 🔧 | 💡 |
| :----------------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :- | :- | :- |
| closure-actions | enforce usage of closure actions | ✅ | | |
| new-module-imports | enforce using "New Module Imports" from Ember RFC #176 | ✅ | | |
| no-array-prototype-extensions | disallow usage of Ember's Array prototype extensions | | 🔧 | |
| no-at-ember-render-modifiers | disallow importing from @ember/render-modifiers | ✅ | | |
| no-deprecated-router-transition-methods | enforce usage of router service transition methods | ✅ | 🔧 | |
| no-function-prototype-extensions | disallow usage of Ember's function prototype extensions | ✅ | | |
| no-implicit-injections | enforce usage of implicit service injections | ✅ | 🔧 | |
| no-mixins | disallow the usage of mixins | ✅ | | |
| no-new-mixins | disallow the creation of new mixins | ✅ | | |
| no-observers | disallow usage of observers | ✅ | | |
| no-old-shims | disallow usage of old shims for modules | ✅ | 🔧 | |
| no-string-prototype-extensions | disallow usage of String prototype extensions | ✅ | | |
| template-deprecated-inline-view-helper | disallow inline {{view}} helper | 📋 | 🔧 | |
| template-deprecated-render-helper | disallow {{render}} helper | 📋 | 🔧 | |
| template-no-action | disallow {{action}} helper | 📋 | | |
| template-no-attrs-in-components | disallow attrs in component templates | 📋 | | |
| template-no-link-to-positional-params | disallow positional params in LinkTo component | 📋 | | |
| template-no-link-to-tagname | disallow tagName attribute on LinkTo component | 📋 | | |
| template-no-route-action | disallow usage of route-action helper | 📋 | | |
| template-no-unbound | disallow {{unbound}} helper | 📋 | | |
| template-no-with | disallow {{with}} helper | 📋 | | |
Ember Data
| Name | Description | 💼 | 🔧 | 💡 |
| :------------------------------------------------------------------------------------- | :-------------------------------------------------------------------- | :- | :- | :- |
| no-empty-attrs | disallow usage of empty attributes in Ember Data models | | | |
| require-async-inverse-relationship | require inverse to be specified in @belongsTo and @hasMany decorators | | | |
| use-ember-data-rfc-395-imports | enforce usage of @ember-data/ package imports instead ember-data | ✅ | 🔧 | |
Ember Object
| Name | Description | 💼 | 🔧 | 💡 |
| :----------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------- | :- | :- | :- |
| avoid-leaking-state-in-ember-objects | disallow state leakage | ✅ | | |
| no-get | require using ES5 getters instead of Ember's get / getProperties functions | ✅ | 🔧 | |
| no-get-with-default | disallow usage of the Ember's getWithDefault function | ✅ | 🔧 | |
| no-modifier-argument-destructuring | disallow destructuring of modifier arguments to avoid consuming tracked data too early | | | |
| no-proxies | disallow using array or object proxies | | | |
| no-try-invoke | disallow usage of the Ember's tryInvoke util | ✅ | | |
| require-super-in-lifecycle-hooks | require super to be called in lifecycle hooks | ✅ | 🔧 | |
| use-ember-get-and-set | enforce usage of Ember.get and Ember.set | | 🔧 | |
Ember Octane
| Name | Description | 💼 | 🔧 | 💡 |
| :----------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------- | :- | :- |
| classic-decorator-hooks | enforce using correct hooks for both classic and non-classic classes | ✅ | | |
| classic-decorator-no-classic-methods | disallow usage of classic APIs such as get/set in classes that aren't explicitly decorated with @classic | ✅ | | |
| no-actions-hash | disallow the actions hash in components, controllers, and routes | ✅ | | |
| no-classic-classes | disallow "classic" classes in favor of native JS classes | ✅ | | |
| no-ember-super-in-es-classes | disallow use of this._super in ES class methods | ✅ | 🔧 | |
| no-empty-glimmer-component-classes | disallow empty backing classes for Glimmer components | ✅ | | |
| no-tracked-built-ins | enforce usage of @ember/reactive/collections imports instead of tracked-built-ins | | 🔧 | |
| no-tracked-properties-from-args | disallow creating @tracked properties from this.args | ✅ | | |
| template-no-deprecated | disallow using deprecated Glimmer components, helpers, and modifiers in templates | | | |
| template-no-let-reference | disallow referencing let variables in <template> |
| | |
jQuery
| Name | Description | 💼 | 🔧 | 💡 | | :------------------------------------------------- | :------------------------------------------------- | :- | :- | :- | | jquery-ember-run | disallow usage of jQuery without an Ember run loop | ✅ | | | | no-global-jquery | disallow usage of global jQuery object | ✅ | | | | no-jquery | disallow any usage of jQuery | ✅ | | |
Miscellaneous
| Name | Description | 💼 | 🔧 | 💡 |
| :--------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------- | :- | :- | :- |
| named-functions-in-promises | enforce usage of named functions in promises | | | |
| no-html-safe | disallow the use of htmlSafe | | | |
| no-incorrect-calls-with-inline-anonymous-functions | disallow inline anonymous functions as arguments to debounce, once, and scheduleOnce | ✅ | | |
| no-invalid-debug-function-arguments | disallow usages of Ember's assert() / warn() / deprecate() functions that have the arguments passed in the wrong order. | ✅ | | |
| no-restricted-property-modifications | disallow modifying the specified properties | | 🔧 | |
| no-runloop | disallow usage of @ember/runloop functions | ✅ | | |
| require-fetch-import | enforce explicit import for fetch() | | | |
Possible Errors
| Name | Description | 💼 | 🔧 | 💡 | | :------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------- | :- | :- | :- | | template-no-extra-mut-helper-argument | disallow passing more than one argument to the mut helper | 📋 | | | | template-no-jsx-attributes | disallow JSX-style camelCase attributes | | 🔧 | | | template-no-scope-outside-table-headings | disallow scope attribute outside th elements | 📋 | | | | template-no-shadowed-elements | disallow ambiguity with block param names shadowing HTML elements | 📋 | | | | template-no-unbalanced-curlies | disallow unbalanced mustache curlies | 📋 | | | | template-no-unknown-arguments-for-builtin-components | disallow unknown arguments for built-in components | 📋 | 🔧 | |
Routes
| Name | Description | 💼 | 🔧 | 💡 |
| :--------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------- | :- | :- | :- |
| no-capital-letters-in-routes | disallow routes with uppercased letters in router.js | ✅ | | |
| no-controller-access-in-routes | disallow routes from accessing the controller outside of setupController/resetController | ✅ | | |
| no-private-routing-service | disallow injecting the private routing service | ✅ | | |
| no-shadow-route-definition | enforce no route path definition shadowing | ✅ | | |
| no-unnecessary-index-route | disallow unnecessary index route definition | | | |
| no-unnecessary-route-path-option | disallow unnecessary usage of the route path option | ✅ | 🔧 | |
| route-path-style | enforce usage of kebab-case (instead of snake_case or camelCase) in route paths | | | 💡 |
| routes-segments-snake-case | enforce usage of snake_cased dynamic segments in routes | ✅ | | |
Security
| Name | Description | 💼 | 🔧 | 💡 | | :--------------------------------------------------------------------- | :-------------------------------------------------------------- | :- | :- | :- | | template-link-rel-noopener | require rel="noopener noreferrer" on links with target="_blank" | 📋 | 🔧 | | | template-no-triple-curlies | disallow usage of triple curly brackets (unescaped variables) | 📋 | | |
Services
| Name | Description | 💼 | 🔧 | 💡 | | :--------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------- | :- | :- | :- | | no-implicit-service-injection-argument | disallow omitting the injected service name argument | | 🔧 | | | no-restricted-service-injections | disallow injecting certain services under certain paths | | | | | no-unnecessary-service-injection-argument | disallow unnecessary argument when injecting services | | 🔧 | | | no-unused-services | disallow unused service injections (see rule doc for limitations) | | | 💡 |
Style
| Name | Description | 💼 | 🔧 | 💡 | | :------------------------------------------------------------------------------------------- | :--------------------------------------------------------- | :- | :- | :- | | template-no-quoteless-attributes | require quotes on all attribute values | 📋 | 🔧 | | | template-no-unnecessary-curly-strings | disallow unnecessary curly braces in string interpolations | 📋 | 🔧 | |
Stylistic Issues
| Name | Description | 💼 | 🔧 | 💡 | | :----------------------------------------------------------------------------- | :----------------------------------------------------------------------------- | :- | :- | :- | | order-in-components | enforce proper order of properties in components | | 🔧 | | | order-in-controllers | enforce proper order of properties in controllers | | 🔧 | | | order-in-models | enforce proper order of properties in models | | 🔧 | | | order-in-routes | enforce proper order of properties in routes | | 🔧 | | | template-attribute-indentation | enforce proper indentation of attributes and arguments in multi-line templates | | | | | template-attribute-order | enforce consistent ordering of attributes in template elements | | 🔧 | | | template-block-indentation | enforce consistent indentation for block statements and their children | | 🔧 | | | template-eol-last | require or disallow newline at the end of template files | | 🔧 | | | template-linebreak-style | enforce consistent linebreaks in templates | | 🔧 | | | template-modifier-name-case | require dasherized names for modifiers | | 🔧 | | | template-no-only-default-slot | disallow using only the default slot | | 🔧 | | | template-quotes | enforce consistent quote style in templates | | 🔧 | | | template-template-length | enforce template size constraints | | | |
Testing
| Name | Description | 💼 | 🔧 | 💡 |
| :----------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------- | :- | :- | :- |
| no-current-route-name | disallow usage of the currentRouteName() test helper | | | |
| no-ember-testing-in-module-scope | disallow use of Ember.testing in module scope | ✅ | | |
| no-invalid-test-waiters | disallow incorrect usage of test waiter APIs | ✅ | | |
| no-legacy-test-waiters | disallow the use of the legacy test waiter APIs | ✅ | | |
| no-noop-setup-on-error-in-before | disallows using no-op setupOnerror in before or beforeEach | ✅ | 🔧 | |
| no-pause-test | disallow usage of the pauseTest helper in tests | ✅ | | |
| no-replace-test-comments | disallow 'Replace this with your real tests' comments in test files | | | |
| no-restricted-resolver-tests | disallow the use of patterns that use the restricted resolver in tests | ✅ | | |
| no-settled-after-test-helper | disallow usage of await settled() right after test helper that calls it internally | ✅ | 🔧 | |
| no-test-and-then | disallow usage of the andThen test wait helper | ✅ | | |
| no-test-import-export | disallow importing of "-test.js" in a test file and exporting from a test file | ✅ | | |
| no-test-module-for | disallow usage of moduleFor, moduleForComponent, etc | ✅ | | |
| no-test-support-import | disallow importing of "test-support" files in production code. | ✅ | | |
| no-test-this-render | disallow usage of the this.render in tests, recommending to use @ember/test-helpers' render instead. | ✅ | | |
| prefer-ember-test-helpers | enforce usage of @ember/test-helpers methods over native window methods | ✅ | | |
| require-valid-css-selector-in-test-helpers | disallow using invalid CSS selectors in test helpers | ✅ | 🔧 | |
🍻 Contribution Guide
If you have any suggestions, ideas, or problems, feel free to [create an issue](https://github.com/ember-cli/eslint-plugin-e
