UNPKG

20.5 kBMarkdownView Raw
1# ember-template-lint
2
3[![npm version](https://badge.fury.io/js/ember-template-lint.svg)](https://badge.fury.io/js/ember-template-lint)
4[![Build Status](https://github.com/ember-template-lint/ember-template-lint/workflows/CI/badge.svg)](https://github.com/ember-template-lint/ember-template-lint/actions?query=workflow%3ACI)
5
6ember-template-lint will lint your handlebars template and return error results.
7
8For example, given the rule [`no-bare-strings`](docs/rule/no-bare-strings.md) is enabled, this template would be
9in violation:
10
11```hbs
12{{!-- app/components/my-thing/template.hbs --}}
13<div>A bare string</div>
14```
15
16When the `ember-template-lint` executable is run, we would have a single result indicating that
17the `no-bare-strings` rule found an error.
18
19## Installation
20
21This addon is installed by default with new Ember apps, so check your package.json before installing to see if you need to install it.
22
23To install ember-template-lint
24
25With npm:
26
27```bash
28npm install --save-dev ember-template-lint
29```
30
31With yarn:
32
33```bash
34yarn add ember-template-lint --dev
35```
36
37Node.js `10 || >=12` is required.
38
39## Usage
40
41While `ember-template-lint` does have a [Node API](docs/node-api.md), the main way to use it is through its executable, which is intended to be installed locally within a project.
42
43Basic usage is as straightforward as
44
45```bash
46ember-template-lint .
47```
48
49### Workflow Examples
50
51Basic usage with a single file
52
53```bash
54ember-template-lint "app/templates/application.hbs"
55```
56
57Output errors with source description
58
59```bash
60ember-template-lint "app/templates/application.hbs" --verbose
61```
62
63Multiple file/directory/wildcard paths are accepted
64
65```bash
66ember-template-lint "app/templates/components/**/*" "app/templates/application.hbs"
67```
68
69Output errors as pretty-printed JSON string
70
71```bash
72ember-template-lint "app/templates/application.hbs" --json
73```
74
75Ignore warnings / only report errors
76
77```bash
78ember-template-lint "app/templates/application.hbs" --quiet
79```
80
81Define custom config path
82
83```bash
84ember-template-lint "app/templates/application.hbs" --config-path .my-template-lintrc.js
85```
86
87Read from stdin
88
89```bash
90ember-template-lint --filename app/templates/application.hbs < app/templates/application.hbs
91```
92
93Print list of formatted rules for use with `pending` in config file
94
95```bash
96ember-template-lint "app/templates/application.hbs" --print-pending
97```
98
99Specify custom ignore pattern `['**/dist/**', '**/tmp/**', '**/node_modules/**']` by default
100
101```bash
102ember-template-lint "/tmp/template.hbs" --ignore-pattern "**/foo/**" --ignore-pattern "**/bar/**"
103```
104
105Disable ignore pattern entirely
106
107```bash
108ember-template-lint "/tmp/template.hbs" --no-ignore-pattern
109```
110
111Running a single rule without options
112
113```bash
114ember-template-lint --no-config-path app/templates --rule 'no-implicit-this:error'
115```
116
117Running a single rule with options
118
119```bash
120ember-template-lint --no-config-path app/templates --rule 'no-implicit-this:["error", { "allow": ["some-helper"] }]'
121```
122
123Running a single rule, disabling inline configuration
124
125```bash
126ember-template-lint --no-config-path app/templates --rule 'no-implicit-this:error' --no-inline-config
127```
128
129Specify a config object to use instead of what exists locally
130
131```bash
132ember-template-lint --config '{ "rules": { "no-implicit-this": { "severity": 2, "config": true } } }' test/fixtures/no-implicit-this-allow-with-regexp/app/templates
133```
134
135:bulb: Ensure you wrap all glob patterns in quotes so that it won't be interpreted by the CLI. `ember-template-lint app/templates/**` (this will expand all paths in app/templates) and `ember-template-lint "app/templates/**"` (this will pass the glob to ember-template-lint and not interpret the glob).
136
137## Configuration
138
139### Project Wide
140
141You can turn on specific rules by toggling them in a
142`.template-lintrc.js` file at the base of your project, or at a custom relative
143path which may be identified using the CLI:
144
145```javascript
146module.exports = {
147 extends: 'recommended',
148
149 rules: {
150 'no-bare-strings': true,
151 },
152};
153```
154
155For more detailed information see [configuration](docs/configuration.md).
156
157### Presets
158
159| | Name | Description |
160| :----------------- | :--------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
161| :white_check_mark: | [recommended](lib/config/recommended.js) | enables the recommended rules |
162| :car: | [octane](lib/config/octane.js) | extends the `recommended` preset by enabling Ember Octane rules |
163| :nail_care: | [stylistic](lib/config/stylistic.js) | enables stylistic rules for those who aren't ready to adopt [ember-template-lint-plugin-prettier](https://github.com/ember-template-lint/ember-template-lint-plugin-prettier) (including stylistic rules that were previously in the `recommended` preset in ember-template-lint v1) |
164
165## Rules
166
167Each rule has emojis denoting:
168
169- what configuration it belongs to
170- :wrench: if some problems reported by the rule are automatically fixable by the `--fix` command line option
171
172<!--RULES_TABLE_START-->
173
174| | Rule ID |
175| :------------------------- | :-------------------------------------------------------------------------------------------------------- |
176| | [attribute-indentation](./docs/rule/attribute-indentation.md) |
177| :nail_care: | [block-indentation](./docs/rule/block-indentation.md) |
178| | [builtin-component-arguments](./docs/rule/builtin-component-arguments.md) |
179| | [deprecated-each-syntax](./docs/rule/deprecated-each-syntax.md) |
180| | [deprecated-inline-view-helper](./docs/rule/deprecated-inline-view-helper.md) |
181| :white_check_mark: | [deprecated-render-helper](./docs/rule/deprecated-render-helper.md) |
182| :nail_care: | [eol-last](./docs/rule/eol-last.md) |
183| :wrench: | [inline-link-to](./docs/rule/inline-link-to.md) |
184| :nail_care: | [linebreak-style](./docs/rule/linebreak-style.md) |
185| :white_check_mark: | [link-href-attributes](./docs/rule/link-href-attributes.md) |
186| :white_check_mark::wrench: | [link-rel-noopener](./docs/rule/link-rel-noopener.md) |
187| | [modifier-name-case](./docs/rule/modifier-name-case.md) |
188| :white_check_mark: | [no-abstract-roles](./docs/rule/no-abstract-roles.md) |
189| :wrench: | [no-accesskey-attribute](./docs/rule/no-accesskey-attribute.md) |
190| :car: | [no-action](./docs/rule/no-action.md) |
191| | [no-action-modifiers](./docs/rule/no-action-modifiers.md) |
192| :white_check_mark: | [no-args-paths](./docs/rule/no-args-paths.md) |
193| | [no-arguments-for-html-elements](./docs/rule/no-arguments-for-html-elements.md) |
194| :wrench: | [no-aria-hidden-body](./docs/rule/no-aria-hidden-body.md) |
195| :white_check_mark: | [no-attrs-in-components](./docs/rule/no-attrs-in-components.md) |
196| | [no-bare-strings](./docs/rule/no-bare-strings.md) |
197| | [no-block-params-for-html-elements](./docs/rule/no-block-params-for-html-elements.md) |
198| | [no-capital-arguments](./docs/rule/no-capital-arguments.md) |
199| :car: | [no-curly-component-invocation](./docs/rule/no-curly-component-invocation.md) |
200| :white_check_mark: | [no-debugger](./docs/rule/no-debugger.md) |
201| | [no-down-event-binding](./docs/rule/no-down-event-binding.md) |
202| :white_check_mark: | [no-duplicate-attributes](./docs/rule/no-duplicate-attributes.md) |
203| | [no-duplicate-id](./docs/rule/no-duplicate-id.md) |
204| | [no-duplicate-landmark-elements](./docs/rule/no-duplicate-landmark-elements.md) |
205| | [no-dynamic-subexpression-invocations](./docs/rule/no-dynamic-subexpression-invocations.md) |
206| | [no-element-event-actions](./docs/rule/no-element-event-actions.md) |
207| :white_check_mark: | [no-extra-mut-helper-argument](./docs/rule/no-extra-mut-helper-argument.md) |
208| | [no-forbidden-elements](./docs/rule/no-forbidden-elements.md) |
209| | [no-heading-inside-button](./docs/rule/no-heading-inside-button.md) |
210| :white_check_mark: | [no-html-comments](./docs/rule/no-html-comments.md) |
211| :car: | [no-implicit-this](./docs/rule/no-implicit-this.md) |
212| :white_check_mark: | [no-index-component-invocation](./docs/rule/no-index-component-invocation.md) |
213| :white_check_mark: | [no-inline-styles](./docs/rule/no-inline-styles.md) |
214| :white_check_mark: | [no-input-block](./docs/rule/no-input-block.md) |
215| :white_check_mark: | [no-input-tagname](./docs/rule/no-input-tagname.md) |
216| | [no-invalid-block-param-definition](./docs/rule/no-invalid-block-param-definition.md) |
217| :white_check_mark: | [no-invalid-interactive](./docs/rule/no-invalid-interactive.md) |
218| :white_check_mark: | [no-invalid-link-text](./docs/rule/no-invalid-link-text.md) |
219| | [no-invalid-link-title](./docs/rule/no-invalid-link-title.md) |
220| :white_check_mark: | [no-invalid-meta](./docs/rule/no-invalid-meta.md) |
221| :white_check_mark: | [no-invalid-role](./docs/rule/no-invalid-role.md) |
222| | [no-link-to-tagname](./docs/rule/no-link-to-tagname.md) |
223| :white_check_mark: | [no-log](./docs/rule/no-log.md) |
224| :wrench: | [no-model-argument-in-route-templates](./docs/rule/no-model-argument-in-route-templates.md) |
225| :nail_care: | [no-multiple-empty-lines](./docs/rule/no-multiple-empty-lines.md) |
226| | [no-mut-helper](./docs/rule/no-mut-helper.md) |
227| :white_check_mark: | [no-negated-condition](./docs/rule/no-negated-condition.md) |
228| :white_check_mark: | [no-nested-interactive](./docs/rule/no-nested-interactive.md) |
229| | [no-nested-landmark](./docs/rule/no-nested-landmark.md) |
230| | [no-nested-splattributes](./docs/rule/no-nested-splattributes.md) |
231| :white_check_mark: | [no-obsolete-elements](./docs/rule/no-obsolete-elements.md) |
232| :white_check_mark: | [no-outlet-outside-routes](./docs/rule/no-outlet-outside-routes.md) |
233| :white_check_mark: | [no-partial](./docs/rule/no-partial.md) |
234| | [no-passed-in-event-handlers](./docs/rule/no-passed-in-event-handlers.md) |
235| :wrench: | [no-positional-data-test-selectors](./docs/rule/no-positional-data-test-selectors.md) |
236| :white_check_mark: | [no-positive-tabindex](./docs/rule/no-positive-tabindex.md) |
237| | [no-potential-path-strings](./docs/rule/no-potential-path-strings.md) |
238| :white_check_mark: | [no-quoteless-attributes](./docs/rule/no-quoteless-attributes.md) |
239| :wrench: | [no-redundant-fn](./docs/rule/no-redundant-fn.md) |
240| :wrench: | [no-redundant-landmark-role](./docs/rule/no-redundant-landmark-role.md) |
241| | [no-restricted-invocations](./docs/rule/no-restricted-invocations.md) |
242| :white_check_mark: | [no-shadowed-elements](./docs/rule/no-shadowed-elements.md) |
243| :wrench: | [no-this-in-template-only-components](./docs/rule/no-this-in-template-only-components.md) |
244| :nail_care: | [no-trailing-spaces](./docs/rule/no-trailing-spaces.md) |
245| :white_check_mark: | [no-triple-curlies](./docs/rule/no-triple-curlies.md) |
246| | [no-unbalanced-curlies](./docs/rule/no-unbalanced-curlies.md) |
247| :white_check_mark: | [no-unbound](./docs/rule/no-unbound.md) |
248| | [no-unknown-arguments-for-builtin-components](./docs/rule/no-unknown-arguments-for-builtin-components.md) |
249| :white_check_mark: | [no-unnecessary-component-helper](./docs/rule/no-unnecessary-component-helper.md) |
250| :nail_care: | [no-unnecessary-concat](./docs/rule/no-unnecessary-concat.md) |
251| :white_check_mark: | [no-unused-block-params](./docs/rule/no-unused-block-params.md) |
252| | [no-whitespace-for-layout](./docs/rule/no-whitespace-for-layout.md) |
253| | [no-whitespace-within-word](./docs/rule/no-whitespace-within-word.md) |
254| | [no-yield-only](./docs/rule/no-yield-only.md) |
255| | [no-yield-to-default](./docs/rule/no-yield-to-default.md) |
256| :nail_care: | [quotes](./docs/rule/quotes.md) |
257| :white_check_mark::wrench: | [require-button-type](./docs/rule/require-button-type.md) |
258| | [require-each-key](./docs/rule/require-each-key.md) |
259| | [require-form-method](./docs/rule/require-form-method.md) |
260| :wrench: | [require-has-block-helper](./docs/rule/require-has-block-helper.md) |
261| :white_check_mark: | [require-iframe-title](./docs/rule/require-iframe-title.md) |
262| | [require-input-label](./docs/rule/require-input-label.md) |
263| | [require-lang-attribute](./docs/rule/require-lang-attribute.md) |
264| | [require-splattributes](./docs/rule/require-splattributes.md) |
265| :white_check_mark: | [require-valid-alt-text](./docs/rule/require-valid-alt-text.md) |
266| :nail_care: | [self-closing-void-elements](./docs/rule/self-closing-void-elements.md) |
267| :white_check_mark: | [simple-unless](./docs/rule/simple-unless.md) |
268| | [splat-attributes-only](./docs/rule/splat-attributes-only.md) |
269| :white_check_mark: | [style-concatenation](./docs/rule/style-concatenation.md) |
270| :white_check_mark: | [table-groups](./docs/rule/table-groups.md) |
271| | [template-length](./docs/rule/template-length.md) |
272
273<!--RULES_TABLE_END-->
274
275### Supporting the `--fix` option
276
277You can add a fixer to a rule. See [fixer documentation](docs/fixer.md) for more details.
278
279### Sharing configs
280
281It is possible to share a config (`extends`) or plugin (custom rules) across projects. See [ember-template-lint-plugin-peopleconnect](https://github.com/peopleconnectus/ember-template-lint-plugin-peopleconnect) for an example.
282
283## Defining your own rules
284
285You can define and use your own custom rules using the plugin system. See [plugin documentation](docs/plugins.md) for more details.
286
287## Semantic Versioning Policy
288
289The semver policy for this addon can be read here: [semver policy](dev/versioning.md).
290
291## Contributing
292
293See the [Contributing Guidelines](CONTRIBUTING.md) for information on how to help out.
294
295## License
296
297This project is licensed under the [MIT License](LICENSE.md).