Using two Ember apps in the same Rails project


#1

I need different Ember applications used in different parts of a Rails application. My plan is to define each app in a subdirectory of assets/javascripts, then deferReadiness() on each app so that only runs on views/pages where it is needed. Are there examples out there of people using multiple apps in the same site/project? Anyone found conflicts in trying to load two apps on the same page/window?

I’m also using Ember-Rails to precompile templates. Given this, it seems the two apps might get confused over which application template belongs to them. Any stories or experiences on this topic are appreciated! I’ll post my solutions as I get things working in my project…


#2

I’ve done this with on the old-router version of Ember (3 ember apps within the app/assets/javascripts directory in a single Rails app). Back then, you didn’t have much of a choice other than to define each view subclass that you were planning on using, so in one app’s view class I might have put templateName: "firstApp/templates/menu" and in another template: "secondApp/templates/menu", assuming firstApp and secondApp are folders in assets/javascripts.

Nowadays, there’s a lot more of this that’s generated for you based on naming conventions, and if you want to have this work for multiple Ember apps in a Rails app, you’ll have to do some tweaking.

Here’s snippet of the directory structure I used in this older Ember app:

image

Each Ember.Application had its own app name and namespace ContributorsWebapp, Receivers, and Landing. There was also an Ember.Namespace called Shared for model definitions, helpers, views, etc., shared between all the apps.

If I were to do this with the latest master, I think I would put the following in application.rb (assuming you’re using ember-rails):

  config.handlebars.templates_root = ["contributors_webapp/templates", "receivers/templates", "landing/templates", "shared/templates"]

The default value of templates_root is “templates”, but that won’t work for us since we have the multiple apps. The above configuration will compile the template at receivers/templates/foo.hbs into Ember.TEMPLATES["foo"]. Note that it would also compile the template at landing/templates/foo.hbs into Ember.TEMPLATES["foo"], resulting in a collision, but this is resolved by the fact that the giant receivers.js bundle wouldn’t include the templates from landing. The result of this is that regardless of which app you’re loading, your templates will be output according to Ember’s default naming conventions.

If for some reason this doesn’t work for you, there are things you could do within Ember to override the default naming conventions, specifically by overriding the DefaultResolver. Check out the documentation for that here.


#3

For what it’s worth, this PR, if it’s accepted, will allow for easier configuration on the client side if you don’t want to change ember-rails’ default output.


#4

Have you looked at how Discourse achieves something similar?

They have the admin side separated from the client side so they effectively work as separate applications.


#5

Good tip, although the “admin” project is just a bolt-on to the core Discourse app as far as I can tell. They are not creating two apps. The admin project just adds controllers and routes rather than creating a new default application template and app object.

It is helpful to see how the manage loading of multiple trees and order dependencies.


#6

Thanks for the tip! I had no problem once I updated to the latest version (1.0 rc). Before there was a problem with the “injection” of ‘store’ when using multiple apps.

I see what you’re saying about the templates_root. And, the template namespace from the PR is a handy way to avoid the name collision.


#7

Thanks for mentioning the DefaultResolver, it sure makes things like this much easier :slight_smile:

But that doesn’t mean I’m giving up on the PR :trollface:


#8

I’d like to know more about this. I’m thinking about embedding one ember app within another. The “parent” app shouldn’t know anything about the child. I’m not using Rails, so some of the challenges are opaque to me, but I’d appreciate any advice out there on how two apps can interact on the client side. I may or may not go this route, but I’m looking for the parent “app” to be agnostic of the child “app”, yet helpful… a framework into which child “apps” could be plugged and where the child “apps” get services from the parent. It seems doubtful that having two distinct apps is going to suit the needs, though, which is why I’m leaning toward just making sure to separate the parent-like functionality from the child-like functionality in other ways (packing, naming conventions, etc)…