You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0779-first-class-component-templates.md
+38-36Lines changed: 38 additions & 36 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1057,7 +1057,7 @@ The imports-only design borrows the idea of “front-matter” from many text au
1057
1057
1058
1058
</details>
1059
1059
1060
-
The major upside to this is that it is the smallest possible delta over today’s implementation. However, it has a number of significant downsides
1060
+
The major upside to this is that it is the smallest possible delta over today’s implementation. However, it has a number of significant downsides which render it much worse than the first-class component templates proposal, and in some cases worse than the _status quo_.
1061
1061
1062
1062
First, as with today’s _status quo_, it does not allow locally-scoped JavaScript values (including helpers and modifiers but also ecosystem tooling like GraphQL values, CSS-in-JS tooling, etc.) even when that is a perfectly reasonable design decision.
1063
1063
@@ -1084,46 +1084,48 @@ import { isBirthday } from './my-component';
1084
1084
1085
1085
While a colocated template (the default since Octane) is part of the same module as the backing class, this does technically work![^recursive-module] However, it’s the kind of extremely surprising and weird thing we would generally try to avoid pedagogically—it requires us to explain that these two separate files (`.js` and `.hbs`) are combined into a single module at build time… and that we have nonetheless kept them separate at authoring time, requiring these kinds of workarounds.[^recursive-import-perf]
1086
1086
1087
-
Perhaps most critically, this is **much worse than the _status quo_ for tests**. It requires that we do one of the following:
1087
+
Perhaps most critically, this is **much worse than the _status quo_ for tests**.
1088
1088
1089
-
- Require people’s test authoring format to become *massively* more verbose and less useful, with imports in every single test `hbs` string, to support strict mode for tests:
1089
+
If we support strict mode for tests, then out of the box we require people’s test authoring format to become *massively* more verbose and less useful, with imports in every single test `hbs` string, to support strict mode for tests:
1090
1090
1091
-
```js
1092
-
import { module, test } from'qunit';
1093
-
import { hbs } from'ember-cli-htmlbars';
1094
-
import { setupRenderingTest } from'ember-qunit';
1095
-
import { render } from'@ember/test-helpers';
1096
-
1097
-
module('demonstrates the problem', function (hooks) {
1098
-
setupRenderingTest(hooks);
1099
-
1100
-
test('by rendering an imported component', asyncfunction (assert) {
1101
-
awaitrender(hbs`
1102
-
---
1103
-
import ComponentToTest from 'my-app/components/component-to-test';
1104
-
---
1105
-
1106
-
<ComponentToTest />
1107
-
`);
1108
-
});
1109
-
1110
-
test('then again with an argument', asyncfunction (assert) {
1111
-
awaitrender(hbs`
1112
-
---
1113
-
import ComponentToTest from 'my-app/components/component-to-test';
1114
-
---
1115
-
1116
-
<ComponentToTest @anArg= />
1117
-
`);
1118
-
});
1119
-
});
1120
-
```
1091
+
```js
1092
+
import { module, test } from'qunit';
1093
+
import { hbs } from'ember-cli-htmlbars';
1094
+
import { setupRenderingTest } from'ember-qunit';
1095
+
import { render } from'@ember/test-helpers';
1096
+
1097
+
module('demonstrates the problem', function (hooks) {
1098
+
setupRenderingTest(hooks);
1099
+
1100
+
test('by rendering an imported component', asyncfunction (assert) {
1101
+
awaitrender(hbs`
1102
+
---
1103
+
import ComponentToTest from 'my-app/components/component-to-test';
1104
+
---
1105
+
1106
+
<ComponentToTest />
1107
+
`);
1108
+
});
1109
+
1110
+
test('then again with an argument', asyncfunction (assert) {
1111
+
awaitrender(hbs`
1112
+
---
1113
+
import ComponentToTest from 'my-app/components/component-to-test';
1114
+
---
1115
+
1116
+
<ComponentToTest @anArg= />
1117
+
`);
1118
+
});
1119
+
});
1120
+
```
1121
+
1122
+
There are two major problems to notice here:
1121
1123
1122
-
The first thing to notice is that there is no way to import `ComponentToTest` here just once. This overhead will multiply across the number of items to reference in a given test—every component, every helper, every modifier!—as well as across the number of tests. This is a *large* increase in the burden of testing compared to today.
1124
+
1. There is no way to import `ComponentToTest` here just once. This overhead will multiply across the number of items to reference in a given test—every component, every helper, every modifier!—as well as across the number of tests. This is a *large* increase in the burden of testing compared to today.
1123
1125
1124
-
The second thing to notice is that this also requires us to maintain, *and to teach*, the `hbs` handling for tests (or to design some replacement for it), on top of the “regular” template handling for components. This is the same situation as in Ember apps today—but since first-class component templates allow us to *improve* the consistency between app code and test code, this counts as a negative by comparison!
1126
+
2. This also requires us to maintain, *and to teach*, the `hbs` handling for tests (or to design some replacement for it), on top of the “regular” template handling for components. This is the same situation as in Ember apps today—but since first-class component templates allow us to *improve* the consistency between app code and test code, this counts as a negative by comparison!
1125
1127
1126
-
- Continue to support a completely separate design for testing than for app code. In that case, though, supporting strict mode templates in tests *and* avoiding the verbosity of the first option means we need a separate authoring format for tests—in fact, it basically requires that we fully implement something like the first-class component templates design!
1128
+
To get around this, we could continue to support a completely separate design for testing than for app code. In that case, though, if we want to support strict mode templates in tests, we need a separate authoring format for tests from app code. In fact, it basically requires that we fully implement something like the first-class component templates design!
1127
1129
1128
1130
[^recursive-module]: To see this for yourself, follow the instructions in [this gist](https://gist.github.com/chriskrycho/dc5adabd80c04d405c7a4894c0ffb99e). I had to test this out myself, and while it’s actually *very good* that modules work this way, I was initially surprised by it! If you’re curious: imports and exports are *static* and so are analyzed before the module is executed.
0 commit comments