Modularization of large Ember application

We are considering to use EmberJS for a large project. We are in early stage of proof-of-concepts, but we like the core concepts of Ember so far. However, we are little bit lost regarding how to structure and modularize our project.

We have started with ember-cli (based on broccoli) that provides simple project structure and basically compiles all assets into few files that are all served right away to the client. We would like to do two things:

  1. Split project into two layers:

  • Company-wide foundation of UI components, that can be reused in our other projects. This layer may basically contain anything that we consider reusable and not product specific. Components, templates, utility helpers, mixins, reusable views and controllers, perhaps user management and other common stuff.

  • Product application layer built on top of previous layer. This will contain actual screens, routes, application logic and product-specific components and views.

It would be very helpful if the two layers could be in two separate repositories, but still could be easily developed and managed at once. I like a concept of git submodules for dealing with multiple repositories in one project during a development. It would be great if we could build, test and pack the first layer separately and once built, use it as a dependency for the final product built on top of it.

  1. Build separate packages and load them dynamically by client

We would like to avoid building whole application into one big app.js file and load it on client every time. Instead we would like to split application during build into several smaller packages that are loaded on client by demand.

There are several reasons for this:

  • We have different kinds of users that work with the application based on their role and permissions. While some users may only use few screens, others may use much more screens or a different set of screens based on their permissions. For example there’s no need to load administration part of the application if the client has permission only to access basic functionality of the application. This is mainly for optimization but also for security. I think we can draw lines between modules mostly on URL / routes.

  • We will offer different licenses for the product. We don’t want to ship parts of application that the customer has not a license for. Again I think we can split modules by URL / routes in this case.

  • We would be very happy if we could build a small package that contains all necessary components to let user launch the application and log in, then load the rest of the application once the user logs in.

To summarize, there are two things that we need to solve:

  1. Split an application into multiple packages during a build
  2. Dynamically load demanded packages on a client

I have no idea how to adapt build process (currently ember-cli and broccoli) to our needs. I can imagine how to deal with dynamic loading on a client though. I think we could use promises in route’s “model” hook to asynchronously load required module that contains all required resources and inject them into Ember DI container. I’m not sure if Ember contains any logic (other than route’s model hook) that would support such a dynamic loading. To my current knowledge, Ember just throws exception if it cannot find requested resource (like controller, view, template etc.) in its container. That would mean that we have to make sure that the package that we load for the route contains everything that can be possibly needed inside the route and manually inject it into the container. I’m fine with that approach if we have tool that tells us all dependencies for any given route, which I guess isn’t easy. That dependency tree would have to be used in the build process as well.

Guys, any idea? :slight_smile:

17 Likes

This is actually how we (www.prosperworks.com) are structured.

We have a “common” package which contains all shared components, views, controllers, mixins, utils and etc.

And every app has its own folder which references “common”. And we compiled different javascripts for different clients. E.g., web app, gmail gadget and etc …

We have used namespace extensively. But what I found very annoying is that so far I have not found a way to make off-the-shelf component working with namespace. So I hacked up a solution which is not very desirable.

I would suggest to the core team to think more about namespacing as this is a MUST for big teams.

3 Likes

Thanks for reply. Can you please outline how you structured you project? What build setup do you use? Do you use ember-cli or ember-appkit, or did you roll your own build setup? Do you then compile all your source files into one big app that is loaded to client, or do you use any form of dynamic loading on client?

A agree with the need of namespaces. Currently we use ES6 imports/exports provided by ember-cli. It is definitely step forward from polluting window object, but requires one global modulePrefix.

I’ve just came across an interesting issue on ember-cli https://github.com/stefanpenner/ember-cli/issues/402

1 Like

We started mid last year and did not use ES6 modules. :slight_smile:

Maybe we should migrate.

Yep, this is the place to keep your eye on!

I’m keeping my eye also on https://github.com/rjackson/container-resolver-namespaces Looks good!

Hi. I’m new here and just starting with Ember, straight into a big application. Saying BIG might be pretty subjective, but I’ll save you all the details :smile: Thankfully I came across this thread… with the same issues and similar questions.

@stepan how did you get on with your project? Have you found something for the timebeing?

My general question is whether it is worth starting investigating structure for a big app at this point or wait until ember and ember-cli is more stable and up for the job.

I’m in the same boat. Our application is currently composed of 7 “modules” and is currently sitting at ~2.1MB in minified resources and we’re not even 50% done with the project. We’ve had discussions about splitting each module up into it’s own application with a common “core” lib shared between modules but haven’t come up with a solid plan yet. The biggest problems we face are session management/sharing across modules, resource sharing across modules (several of the modules will interact with each other), and maintaining a seamless transition between modules if a user has rights to access multiple modules.

Would love to hear what the community has done/is doing to address situations like this!

5 Likes

I saw this pop up on Twitter a few days ago and it seems like a good approach to modularizing large applications. The basic idea is to extract all of your shared assets into ember-cli addons and then include those addons in your various modules. I haven’t tried it yet but it sounds nice in theory and seemed to work well for the author

http://drive.secondstreet.com/extracting-an-ember-cli-addon-from-your-application/

2 Likes

I was ready to post the same question right now.

Here in our company we are considering to use Ember for a big project and we have almost the same use case scenario.

Any news on this scenarios? @stepan @WooDzu

For my project I figured keeping admin and front-end subprojects as separate Ember-cli projects that land in subfolders on build eg. /admin /app1 /app2 /app3 etc… A lot of duplicated models, serializers but it does the job. All this with a view that one day Engines https://github.com/emberjs/rfcs/pull/10 will become available so I don’t need to update each ember-cli app separately. Please share your finding or alternative approach.

I second this. This is the approach I adopted in one of the project, where I had to separate public and private part of the application as separate independent Ember apps build separately using ember-cli. But for another use case, this seems to be not an ideal solution.