David, are there plans to cease support for “split” components and “non .gjs” at some stage?
Probably yes. It looks like separate js/hbs will be supported by ember for the foreseeable future, but it may make sense for us to make a move earlier to simplify our theme/plugin build systems.
If we do decide to deprecate hbs, we’ll go through all the normal deprecation cycle and announcements, so it won’t come as a surprise.
For themes/plugins using our standard linting config, .hbs
files are already banned, and we have an automated tool to move to gjs. We’ve almost finished updating all CDCK-owned themes/plugins with that tooling.
So just to confirm (so that I can edit my js/hbs components), hbs components are not supported in the theme skeleton, and is strongly recommended to be moved to gjs?
Hbs files continue to be “supported” (i.e. they’ll work, and we won’t change that without a deprecation cycle)
But yes, it’s strongly recommended to use .gjs
for new code, and to start migrating existing themes & plugins. The most up-to-date linting config in the skeletons will enforce that recommendation unless you deliberately opt-out of the ‘require-strict-mode’ ember-template-lint rule.
Ah, got it now. Thanks for clarifying!
I believe in any case Glimmer Components can be anywhere between 3 to 5 times faster, so definitely good practice? (so long as you don’t burden them with lots of additional tracking)
Glimmer components are significantly faster than classic components, yup!
But the .gjs
file format does not necessarily mean it’s a glimmer component. We still have hundreds of classic components in core, which are now all converted to the .gjs
file format. (naming is confusing, I know )
The codemod we’re running only does the file format conversion from js
/hbs
→ .gjs
. It doesn’t change the component type - that would be almost impossible to perfectly automate.
Fair enough, but often worth making the effort if you happen to be in the middle of a manual refactor.
OMG. Just when I thought I was starting to understand.
So it’s not just me!
Does this make it be a glimmer component?
And if that’s the case; even if it’s just a template, adding the class makes it run faster than if it’s a .gjs
that has just <template>My important words</template>
?
export default class MyCoolComponent extends Component {
It’s this:
import Component from "@glimmer/component";
(and subsequent conformance to Glimmer norms like getters)
this is just a “Native class declaration” I believe.
Aha! So you’d still need to declare the class to use the imported component part.
Thanks very much!
My main issue here is that in a hbs
I can simply reference a component from another theme component since I don’t need that explicit import. But in a gjs
I need to import
it and I have no idea how to reference a component defined in another theme component.
All the existing implementations I have looked at are either a) still using hbs
or b) using Javascript based injection.
How do I do this?
In that case I get this eslint recommendation:
Which suggests you should only add the class when you need it as otherwise it would actually be slower.
In ascending order of performance:
-
Classic component:
import Component from "@ember/component"; export default class Blah extends Component {
-
Glimmer component:
import Component from "@glimmer/component"; export default class Blah extends Component {
-
Template-only glimmer component:
export default <template> ... </template>
exactly
Themes cannot currently import from other themes. The fact it was possible to have inter-theme dependencies via the magic name-based-resolution wasn’t really intentional
Could you expand on your use-case, perhaps in another topic? It isn’t something we’ve come across (yet) for any of our own themes.
I think you have… (right-sidebar-blocks).
Last week my main use case was to force an order for multiple theme components that used the same plugin outlet. While CSS files are loaded in alphabetic order, the theme components JS is loaded in numerical order, so I ended up removing theme components and adding them back in the order I needed and trying to avoid all the CSS problems that this caused at the same time.
Then I figured I could just remove the connector in each of them and create a new theme component that had this in a single connector for that plugin outlet:
<ComponentFromTC1 />
<ComponentFromTC4 />
<ComponentFromTC3 />
<ComponentFromTC2 />
which works really well. And then I was like 'oh, I need this to be a gjs
to avoid having to redo this in a few months. And then
You have a customer that wanted to do this as they were moving to you. I can’t remember the details.
I just forked this for a current customer that just launched. They wanted to add a couple of other kinds of blocks. I tried having a sister theme that did just some CSS stuff but in the end had to give up and fork it. I’m not quite sure if there could have been another way.
But…
That is great news, except that I didn’t understand sooner. I sort of remember seeing that and also remember discussing the issue and someone suggested I need to fork, but now I’m pretty sure that I don’t.
Hmmm … Discourse Bars 🍻 🍸 (a sidebar framework) … uses the same system and I’ve not had issues.
The whole point of it is you can use Components from other Theme Components or Plugins (and it works)