Two Techniques for Keeping Your Ember.js Project Clean

I’ve had the opportunity to work on an Ember.js application for the better half of the last year. During that time, I’ve learned a ton about the Ember framework and web development in general. I’ve also seen how an Ember app can transform as it continues to grow. If I could start all over, these are the choices I would make to keep my Ember project clean.

Organize with Pods

The default organizational structure for an Ember project is by type. For example, a student resource would have the following file structure:

  • app/controllers/student.js
  • app/templates/student.hbs
  • app/routes/student.js
  • app/models/student.js

As your app gets larger, more and more files go into these four folders until they become unwieldly.

With pods, you can organize your application by feature. Using pods, the example above would translate into this:

  • app/student/controller.js
  • app/student/template.hbs
  • app/student/route.js
  • app/student/model.js

There are a couple of benefits to doing this. For starters, it separates your application into more logical groupings. Instead of flooding a controllers directory with unrelated parts of your application, you can keep your files neatly organized into resources.

This structure also makes fuzzy finding easier. For example, if I want to find the student controller in the default structure, I need to preface what I actually want (student) with the type (controllers). However, with pods, I can fuzzy-find the same controller by simply looking up “student.”

Use Template Helpers

One of the features I like the most about Ember is data binding. It allows you to transform and manipulate your data so easily. However, sometimes it can be too easy, and you fall into a trap of creating computed properties for very small amounts of work. This creates bloated and unreadable controllers.

One common example involves transforming dates into strings. At first, you only need to do this in one place, so you use a library like Moment.js and do the conversion in place. Then, you need it in a couple of other places, so you create a date formatting helper and use that in your controllers. Before you know it, you’ve imported that helper into several controllers.

I fell into this same trap until I learned about template helpers. You can use these helpers to create a function that is bound to a property, similar to computed properties. Let’s go back to the date example. We can write a simple helper that takes a date property and turns it into a string.


// In app/helpers/date-string.js

export default Ember.HTMLBars.makeBoundHelper( function(value, options) {
  return moment(value).format(options["format"]);
});

{{date-string date format="D MMMM YYYY"}}

Much cleaner, don’t you agree? By keeping these tips in mind, along with following Ember’s philosophy of data down, actions up, it’s easier to create and maintain a clean Ember project. What other sorts of things do you do to keep your Ember project clean?

Conversation
  • Jason says:

    I disagree with the pods suggestion. At LinkedIn, we tried to give pods a go, but it turned out to be a gigantic pain so we went back to the initial structure and it’s working pretty well. When you have your code editor up and you have 10 files all named “template.hbs” or “route.js”, it’s impossible to find the one you’re looking for. Much easier to find “student.hbs”.

    • Ryan Abel Ryan Abel says:

      Thanks for the comment, Jason.

      It’s interesting that you found the pod file structure to be unhelpful. It feels more natural to me to search for “studentcontroller” as opposed to “controllerstudent”. Maybe that feeling is just a result of my Rails background.

      Also, I can’t say I’ve felt the pain of having a lot of files named “template.hbs”. I tend to keep only 3 or 4 files open in Vim at a time and use a fuzzy finder to switch to new files. However, I can see how results would vary across text editors. I would be interested to hear of any other pains you’ve felt working with pods.

      Thanks again for the comment!

    • purna says:

      after pods we need to search by folder name instead of file thats it.
      /podname/ not an issue , just need to add ‘slash’

  • Jason really echoes my fears with pod structure. From an initial development standpoint it makes a lot of sense to develop a feature and put all the files in the same “pod”. From a maintenance standpoint and apply code changes across multiple features/routes, it seems like an organizational nightmare. I regularly have 10+ files open in my IDE, and having them all be named the same would be a nightmare. That said, Jason, in my IDE (Webstorm) at least, when you have multiple files with the same name open, it shows the directory name in the tab as well so you can distinguish them (ie student/controller instead of just controller). So maybe the problem is not so much that pods is a nightmare, but that you were not using tools with the right feature set to support such an organizational structure?

    Disclaimer: I haven’t used pods yet, but I’m considering it. The above is just speculation.

    • Ryan Abel Ryan Abel says:

      Interesting perspective, Jordan. One of the reasons I like the pod structure, even on long running projects, is because the organization allows you to explore features easily. This is beneficial when you are ramping another developer into the project. You can explain the flow of an entire feature without navigating out of a directory. I also like the pod structure from a maintenance perspective. When I’m working on an application and changing a behavior of that application, it is more likely that change affects a feature, not a file type, like controllers. In that case, I have a good idea of exactly what files I’ll need to make changes to.

  • +1 for pods! In my experience it has made getting familiar with, maintaining and working on large projects and large teams much easier. That being said and trying to put my personal bias for pods aside, one of the BEST things about pod structure is that you can use it where it makes sense for your project and team and use the standard structure otherwise and the two can co-exist nicely. That also make migrating existing projects to a pod structure much more easy to tackle since you can complete the migration incrementally and verify changes as you go without having to do it all in one big push.

    In my opinion the pod structure is a more logical approach to organizing files in a file system by grouping files together based on content and context as opposed to their type or other “meta” property. If you’re organizing a large music library, you’re likely to group song files into folders based on artist and album, not genre or audio format.

    The first ~30mins of this presentation from Boston Ember give a pretty good overview of pods for those looking to dig a bit deeper.

  • Mike North says:

    For readers of this blog – please be advised that pods are not supported, and if you use pods, it’s likely you’ll run into problems once your project grows in size and complexity.

    There’s a new project organization scheme in the works, but it has not landed yet. Please use the “classic” project structure for now, and a nice migration path will be provided once the “Grand Unified Modules” (new approach) is finalized and officially supported.

    • Iorrah Gonzalez says:

      Hi Mike, thanks for clarifying.

      A great advantage for this recent work would be deliver a native pod concept that also allows we to organize the SCSS files alongside its respective modules.

      So using Ryan’s structure, we would have something similar to:

      – app/student/controller.js
      – app/student/template.hbs
      – app/student/route.js
      – app/student/model.js
      – app/student/style.scss *

      Additionally, we could keep a app/scss folder in which the general style rules would rely on.

    • Roger Studner says:

      What exactly do you mean by “please be advised that pods are not supported” (I see it in the official 2.8.0 docs)

      I’ve been away from Ember for awhile in ReactLand and have been drifting back as a new project opportunity is on the horizon and I sure would like to use PODS :)

      Thanks!

  • Ezra says:

    It seems the naming problem would be solved by adjusting the pod naming convention in the generator:

    app/feature/feature_template.hbs
    app/feature/feature_controller.js
    app/feature/feature_route.js
    app/feature/feature_model.js

    • Sibi John says:

      How exactly can we change the naming convention in the generator?

  • Matthew Lee says:

    +1 for pods.

    We use Atom. There are plugins which help with the ‘everything is named template’ issue where if there are more than one file open with the same name, the IDE prepends the path. Works well enough

    As far as searching, if you are looking for the ‘sales template’ you can search for ‘sales/tem’ with ctrl + t (again in Atom) and it finds the file you are looking for without an issue.

  • Nikos says:

    Why do pod files even need to have the same generic names?

  • Comments are closed.