Skip to content

Commit 55b987c

Browse files
authored
Account for only having template tag in no-empty-glimmer-component-classes rule (#1866)
1 parent a8efed7 commit 55b987c

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

docs/rules/no-empty-glimmer-component-classes.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This rule will catch and prevent the use of empty backing classes for Glimmer co
88

99
## Rule Details
1010

11-
This rule aims to disallow the use of empty backing classes for Glimmer components when possible. Template-only Glimmer components where there is no backing class are much faster and lighter-weight than Glimmer components with backing classes, which are much lighter-weight than Ember components. Therefore, you should only have a backing class for a Glimmer component when absolutely necessary.
11+
This rule aims to disallow the use of empty backing classes for Glimmer components when possible including only using ember template tags in your Glimmer component. Template-only Glimmer components where there is no backing class are much faster and lighter-weight than Glimmer components with backing classes, which are much lighter-weight than Ember components. Therefore, you should only have a backing class for a Glimmer component when absolutely necessary.
1212

1313
To fix violations of this rule:
1414

@@ -26,6 +26,15 @@ import Component from '@glimmer/component';
2626
class MyComponent extends Component {}
2727
```
2828

29+
<!-- markdownlint-disable-next-line MD040 -->
30+
```
31+
import Component from '@glimmer/component';
32+
33+
export default class MyComponent extends Component {
34+
<template>Hello World!</template>
35+
}
36+
```
37+
2938
Examples of **correct** code for this rule:
3039

3140
```js
@@ -54,7 +63,21 @@ import MyDecorator from 'my-decorator';
5463
class MyComponent extends Component {}
5564
```
5665

66+
<!-- markdownlint-disable-next-line MD040 -->
67+
```
68+
import Component from '@glimmer/component';
69+
70+
export default class MyComponent extends Component {
71+
foo() {
72+
return this.args.bar + this.args.baz;
73+
}
74+
75+
<template>Hello World!</template>
76+
}
77+
```
78+
5779
## References
5880

5981
- [Glimmer Components - Octane Upgrade Guide](https://guides.emberjs.com/release/upgrading/current-edition/glimmer-components/)
6082
- [Glimmer Components RFC](https://emberjs.github.io/rfcs/0416-glimmer-components.html)
83+
- [First-Class Component Templates RFC](https://rfcs.emberjs.com/id/0779-first-class-component-templates/)

lib/rules/no-empty-glimmer-component-classes.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
'use strict';
22

33
const { isGlimmerComponent } = require('../utils/ember');
4+
const { isClassPropertyOrPropertyDefinition } = require('../utils/types');
45

56
const ERROR_MESSAGE = 'Do not create empty backing classes for Glimmer components.';
7+
const ERROR_MESSAGE_TEMPLATE_TAG =
8+
'Do not create empty backing classes for Glimmer template tag only components.';
69

710
//------------------------------------------------------------------------------
811
// Rule Definition
@@ -23,12 +26,21 @@ module.exports = {
2326
},
2427

2528
ERROR_MESSAGE,
29+
ERROR_MESSAGE_TEMPLATE_TAG,
2630

2731
create(context) {
2832
return {
2933
ClassDeclaration(node) {
30-
if (isGlimmerComponent(context, node) && !node.decorators && node.body.body.length === 0) {
34+
const nodeIsGlimmerComponent = isGlimmerComponent(context, node);
35+
if (nodeIsGlimmerComponent && !node.decorators && node.body.body.length === 0) {
3136
context.report({ node, message: ERROR_MESSAGE });
37+
} else if (
38+
nodeIsGlimmerComponent &&
39+
node.body.body.length === 1 &&
40+
isClassPropertyOrPropertyDefinition(node.body.body[0]) &&
41+
node.body.body[0].key?.callee?.name === '__GLIMMER_TEMPLATE'
42+
) {
43+
context.report({ node, message: ERROR_MESSAGE_TEMPLATE_TAG });
3244
}
3345
},
3446
};

tests/lib/rules-preprocessor/gjs-gts-processor-test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ const valid = [
8686
</template>
8787
`,
8888
},
89+
{
90+
filename: 'my-component.gjs',
91+
code: `
92+
import Component from '@glimmer/component';
93+
export default class MyComponent extends Component {
94+
foo() {
95+
return this.args.bar + this.args.baz;
96+
}
97+
98+
<template>Hello World!</template>
99+
}
100+
`,
101+
},
89102
/**
90103
* TODO: SKIP this scenario. Tracked in https://github.com/ember-cli/eslint-plugin-ember/issues/1685
91104
{
@@ -102,6 +115,21 @@ const valid = [
102115
];
103116

104117
const invalid = [
118+
{
119+
filename: 'my-component.gjs',
120+
code: `import Component from '@glimmer/component';
121+
export default class Chris extends Component {
122+
<template>Hello!</template>
123+
}`,
124+
errors: [
125+
{
126+
message: 'Do not create empty backing classes for Glimmer template tag only components.',
127+
line: 2,
128+
column: 20,
129+
endColumn: 6,
130+
},
131+
],
132+
},
105133
{
106134
filename: 'my-component.gjs',
107135
code: `

0 commit comments

Comments
 (0)