Skip to content

Commit e575c19

Browse files
Merge pull request #2613 from NullVoxPopuli/nvp/template-lint-extract-rule-template-require-strict-mode
Extract rule: template-require-strict-mode
2 parents 6da1ed7 + 621c5f6 commit e575c19

4 files changed

Lines changed: 172 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ rules in templates can be disabled with eslint directives with mustache or html
247247
| [template-no-obsolete-elements](docs/rules/template-no-obsolete-elements.md) | disallow obsolete HTML elements | | | |
248248
| [template-no-outlet-outside-routes](docs/rules/template-no-outlet-outside-routes.md) | disallow {{outlet}} outside of route templates | | | |
249249
| [template-no-page-title-component](docs/rules/template-no-page-title-component.md) | disallow usage of ember-page-title component | | | |
250+
| [template-require-strict-mode](docs/rules/template-require-strict-mode.md) | require templates to be in strict mode | | | |
250251
| [template-require-valid-named-block-naming-format](docs/rules/template-require-valid-named-block-naming-format.md) | require valid named block naming format | | 🔧 | |
251252
| [template-self-closing-void-elements](docs/rules/template-self-closing-void-elements.md) | require self-closing on void elements | | 🔧 | |
252253
| [template-simple-modifiers](docs/rules/template-simple-modifiers.md) | require simple modifier syntax | | | |
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# ember/template-require-strict-mode
2+
3+
> **HBS Only**: This rule applies to classic `.hbs` template files only (loose mode). It is not relevant for `gjs`/`gts` files (strict mode), where these patterns cannot occur.
4+
5+
<!-- end auto-generated rule header -->
6+
7+
Require templates to be in strict mode.
8+
9+
Ember's Polaris edition component authoring format is template tag, which makes
10+
templates follow "strict mode" semantics.
11+
12+
This rule requires all templates to use strict mode (template tag). Effectively this
13+
means you may only have template content in `.gjs`/`.gts` files, not in `.hbs` or
14+
`.js`/`.ts`.
15+
16+
## Examples
17+
18+
This rule **forbids** the following:
19+
20+
```hbs
21+
// button.hbs
22+
<button>{{yield}}</button>
23+
```
24+
25+
```js
26+
// button-test.js
27+
import { hbs } from 'ember-cli-htmlbars';
28+
29+
test('it renders', async (assert) => {
30+
await render(hbs`<Button>Ok</Button>`);
31+
// ...
32+
});
33+
```
34+
35+
This rule **allows** the following:
36+
37+
```gjs
38+
// button.gjs
39+
<template>
40+
<button>{{yield}}</button>
41+
</template>
42+
```
43+
44+
```gjs
45+
// button-test.gjs
46+
import { Button } from 'ember-awesome-button';
47+
48+
test('it renders', async (assert) => {
49+
await render(<template><Button>Ok</Button></template>);
50+
// ..
51+
});
52+
```
53+
54+
## References
55+
56+
- [Template Tag Guide](https://guides.emberjs.com/release/components/template-tag-format/)
57+
- [Strict Mode RFC](https://rfcs.emberjs.com/id/0496-handlebars-strict-mode/)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const ERROR_MESSAGE =
2+
'Templates are required to be in strict mode. Consider refactoring to template tag format.';
3+
4+
function isStrictModeFile(filePath) {
5+
return filePath?.endsWith('.gjs') || filePath?.endsWith('.gts');
6+
}
7+
8+
/** @type {import('eslint').Rule.RuleModule} */
9+
module.exports = {
10+
meta: {
11+
type: 'suggestion',
12+
docs: {
13+
description: 'require templates to be in strict mode',
14+
category: 'Best Practices',
15+
recommended: false,
16+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-require-strict-mode.md',
17+
templateMode: 'loose',
18+
},
19+
fixable: null,
20+
schema: [],
21+
messages: {},
22+
originallyFrom: {
23+
name: 'ember-template-lint',
24+
rule: 'lib/rules/require-strict-mode.js',
25+
docs: 'docs/rule/require-strict-mode.md',
26+
tests: 'test/unit/rules/require-strict-mode-test.js',
27+
},
28+
},
29+
30+
create(context) {
31+
const filePath = context.getFilename ? context.getFilename() : context.filename;
32+
33+
return {
34+
'GlimmerTemplate:exit'(node) {
35+
if (!isStrictModeFile(filePath)) {
36+
context.report({
37+
node,
38+
message: ERROR_MESSAGE,
39+
});
40+
}
41+
},
42+
};
43+
},
44+
};
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
const rule = require('../../../lib/rules/template-require-strict-mode');
2+
const RuleTester = require('eslint').RuleTester;
3+
4+
const ruleTester = new RuleTester({
5+
parser: require.resolve('ember-eslint-parser'),
6+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
7+
});
8+
9+
ruleTester.run('template-require-strict-mode', rule, {
10+
valid: [
11+
{
12+
filename: 'hello.gjs',
13+
code: '<template>hello</template>',
14+
},
15+
{
16+
filename: 'hello.gts',
17+
code: '<template>hello</template>',
18+
},
19+
],
20+
invalid: [
21+
{
22+
filename: 'hello.hbs',
23+
code: '<template><div>hello</div></template>',
24+
output: null,
25+
errors: [
26+
{
27+
message:
28+
'Templates are required to be in strict mode. Consider refactoring to template tag format.',
29+
},
30+
],
31+
},
32+
{
33+
filename: 'hello.hbs',
34+
code: `<template><div>
35+
hello
36+
</div></template>`,
37+
output: null,
38+
errors: [
39+
{
40+
message:
41+
'Templates are required to be in strict mode. Consider refactoring to template tag format.',
42+
},
43+
],
44+
},
45+
],
46+
});
47+
48+
const hbsRuleTester = new RuleTester({
49+
parser: require.resolve('ember-eslint-parser/hbs'),
50+
parserOptions: {
51+
ecmaVersion: 2022,
52+
sourceType: 'module',
53+
},
54+
});
55+
56+
hbsRuleTester.run('template-require-strict-mode', rule, {
57+
valid: [],
58+
invalid: [
59+
{
60+
code: '<div>hello</div>',
61+
output: null,
62+
errors: [
63+
{
64+
message:
65+
'Templates are required to be in strict mode. Consider refactoring to template tag format.',
66+
},
67+
],
68+
},
69+
],
70+
});

0 commit comments

Comments
 (0)