Overriding plugin javascript in a theme component

Continuing the discussion from Splitting up theme Javascript into multiple files:

There was a discussion from someone a while back about developing in a theme vs a plugin. The Rails part of https://www.pfaffmanager.com/ is starting to be fairly stable, and what I’d like to do is move development of the rails part into a theme component. This is working pretty well, and changes in templates and initializers in the theme component are overriding the plugin as expected. But, changes to javascripts/discourse/components/server-item.js.es6 in the theme are not overriding those same files in the plugin.

I suppose I could remove entirely the ember stuff from the plugin and have it exist only in the theme, but that sounds like a day’s work to get all of those pieces moved around tested and pushed to the server. Might I be missing something silly? Should I suck it up and completely remove the stuff I’d like in the theme component from the plugin? Should I just keep it all in the plugin?

Having the same code in both the theme component and the plugin seems a little weird to me - IMO it would be better to decide between theme-component/plugin, and then go all-in. Overriding entire files isn’t something we do ourselves, and it’s not something we recommend. To override core/plugin behaviour, your theme component should use methods like api.modifyClass.

I suspect the root cause here is that plugin ES6 modules are prefixed differently from core/theme modules. Running this on your site, I see the modules are prefixed with plugin. I suspect if you enabled the theme component, we’d see another entry, but with a different prefix.

1 Like

Well, all of Ember still seems weird to me. :man_shrugging:

Cool. I’ll stick with the single plugin that has all the javascript in it.

And that Object.keys magic is very cool and I’d never have figured that out. I can’t thank you enough for that. And you’re right:

(4) ['discourse/plugins/Pfaffmanager/discourse/components/compact-server-item', 
'discourse/plugins/Pfaffmanager/discourse/components/server-item', 
'discourse/theme-11/components/server-item', 
'discourse/theme-11/components/compact-server-item']
1 Like

I agree in general, however, there are some edge cases:

  1. Where the volume of changes to the javascript far outweighs the changes to the back-end, in which case Theme Components are a great way to deploy and test-deploy code FAST.

  2. Where most of the functionality can be delivered in the base Theme Component but adding a complementary plugin can add additional features not possible in Javascript alone. I employ this technique in Topic List Previews, where the Component does 90% of what the add-on is capable of, but if you also add in the plugin, you get some additional cool stuff.

That said, packaging everything in a plugin makes sense as there is less confusion on configuration & installation and everything is always kept in step.

3 Likes

But even in your plugin+theme scenario, I’d not duplicate the Ember code in both the plugin and the theme. So I’d need to yank at least most of the templates, initializers, components, out of the plugin and have them only in the theme component.

Since I’m the only one who’s going to be confused about the configuration, that’s not a huge deal. I really like the idea of being able to test some new front end stuff on the live site by switching to the beta version of the theme.

2 Likes

Having server-side stuff in a plugin, and client-side stuff in a theme makes a lot of sense - we do that ourselves :+1:

My objection was to defining the same JavaScript file in a theme and a plugin simultaneously.

2 Likes

Yep so all on same page :+1:t2:

3 Likes

I appreciate you guys helping me out with this.

The other issue that I see is doing qunit tests. (I’ll pretend that I can figure out how to add any, which is another issue entirely; I think my problem is that I don’t know how to seed the tests with data for the stuff to display…). I think that if I have quinit tests in my plugin then they’ll get run when I push to gitihub (because I’m pretty sure I’ve seen my broken ones fail).

Can I get a theme component to do the same?

1 Like

Technically it should be possible, but I don’t think we have any ready-made GitHub actions workflows for themes yet. Theme testing is getting a bit of an overhaul currently (for the ember-cli transition), but after that, maybe we’ll be able to add some theme-testing workflow templates to GitHub - discourse/.github

2 Likes