Pluggable components


I want to be able to drop in Ember components using a package manager (e.g. bower) and have them ‘just work’. There’s two challenges that currently prevent this:

  1. Several files need to be copied/link into the appropriate locations for the Ember resolver to find them
  2. What namespace should the component be attached to? i.e. App.FooComponent may not be the correct namespace
  3. This namespace object needs to have been created before the component is loaded, and third-party code is usually included before the app code that would create this object

I can see several simple solutions to the first problem:

  1. Allow Components to inform the resolver that its templates can be found at a given path
  2. If a component’s templates isn’t found in components/ then it is looked for in the same directory as the component itself

Option 2, obviously presents some challenges because the resolver would need to track the path (URI or module path) that each component was loaded from. However it also provides a nice extension point for modifying the presentation of components: if you want to make changes to the way a component is presented then you can simply copy its template into components/ and make your changes.

We could also provide this using Option 1, because users could use the same API to tell the resolver to get the template from some path that they specify.

Regarding the namespace problem, I think we need a registerComponent() method, maybe something like:

var EmFooComponent = Em.Component.extend({foo: 'bar'});
  name: "em-foo-component",
  initialize: function(container, application) {
    container.registerComponent('em-foo', EmFooComponent);

I suggest that this would add component:em-foo to the resolver, and {{em-foo}} would work in the same way as App.EmFooComponent. This is a bit too much ceremony though, so I think the following should have the same effect:


Anybody got thoughts on how to proceed with this?

Combining Component Logic and Template together in single file?


I’m sorry for the brevity, but I just wanted to put down my initial thoughts about this. I have also been pondering some of this issues (I already have ember-float-label-component on the oven), and am looking forward to establishing best practices.

If we’re going to provide component via bower, maybe we could make some tools to pre-compile the template and insert it into the component’s template property.

I attached mine to EmberComponent, thus EmberComponent.MyComponent because I was following in the lead of ember-component-library-template and I basically treated it as you would an Objective-C namespace, if you will. This doesn’t seem the best of ideas, especially in light of the recent development of ember-app-kit (EAK), namely its transition to ES6 modules. I think this is the answer to this problem, avoiding the need for a namespace since we just export the component itself.

This is related to the ES6 modules I mentioned above as well. If I understood correctly some conversations, EAK already has an ES6 module-aware resolver which could make this step trivial. I’m sure @machty, @rwjblue, @bcardarella or @stefan can correct me where I’m wrong, and speak better to this.

I’m all for using bower and I volunteer to make a yeoman generator. Opinions might differ O:)


Can anybody who’s familiar with the resolver/container comment on the feasibility of these options? @stefan do you know who might be able to comment on this?

The advantage here would be having the component contained in a single file, but I prefer the approach of not using a build step and being able to tell the resolver where to find the templates.

I think we’re moving away from using global namespace objects, so using the container is a better solution.

Regarding ES6 modules, I’m using EAK’s ES6-style resolver and I don’t think it changes the correct way to solve the problem. However we include the code (either through a <script> tag or an import EmFooComponent from 'path/to/file'), the resolver still needs to work out where to find its template.