wroc_love.rb 2014

Frontend Choices

This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!

Alex Coles with FRONTEND CHOICES

Rails was born in 2004, the time of the "Ajax revolution". With the help of a little bit of prototype, scriptaculous and RJS, Rails made its mark in part because it facilitated creating beautiful and highly interactive web user interfaces in no time at all.
Fast forward to 2013. Frameworks like Meteor and Hoodie are capturing increasing mindshare. Are we now in the decade of JavaScript? Is the "Rails Way" still relevant to the Front End?

wroc_love.rb 2014

00:00:14.480 We've reached the end of the conference. Last night was probably a very long night for some of you, and it's been a long day and a long weekend. Frontend talks might not usually be the ones you go to; they might be talks you skip to go to the hallway track instead, or perhaps to grab a beer. I'm speaking from experience here, but I will try to make this interesting.
00:00:27.439 I know you all want to go home, and maybe I will encourage you to go home faster, but this should be fun. Unfortunately, some of the participants earlier today stole my thunder a little bit, so some of these topics have already been discussed. If we're going over old territory, then I'm sorry. I also feel like I might be preaching to the choir on many of these issues.
00:00:56.719 First things first: Does 'frontend' have a space in it? Raise your hand if it does. Okay, unanimity, just like the election in Crimea. Anyway, despite the title, this talk is not really about choice. I did a talk a few years ago about choice, which was probably the wrong word. The title should have been 'I'm a Backend Guy Living in a Frontend World,' inspired by the Billy Joel lyrics, 'I'm an Uptown Girl.' I won't sing that. I'm sure a lot of you identify with that sentiment.
00:01:43.560 I'm actually a full-stack developer, but I prefer backend development. A little bit about me: this is a horrible picture of me taken by a 13-year-old. I live in Berlin and have hacked in the past on projects like Data Mappa and Refinery CMS. As of last Monday, I'm working on an open-source project called OpenProject, which is a fork of Redmine, which in turn was a fork of ChiliProject, that was originally a fork of Redmine. We're currently refactoring it and building an Angular-based user interface on top of it. It's no small feat, so I'm learning a lot along the way.
00:02:56.840 My Twitter handle is 'my abc is my ABC,' easy as 1, 2, 3. I'm going to repeat my counting throughout this talk. Speaking of 1, 2, 3, here is the requisite publicity that comes with any talk. On the 1st, 2nd, and 3rd of August, I am organizing a conference along with a couple of people in this room who might want to stand up. I founded this conference a few years ago, and we've brought a contingent from Berlin to Rosloff. We're very much inspired by the folks in Rosloff and would love to have you come to Berlin and join us. Our call for proposals has just opened; please consider submitting.
00:03:12.760 Conveniently, this talk is divided into three parts. The first part will provide a bit of background; the second will discuss where we are now, and the third will go into more practical implementation details. Now, let's start with part one: background. We need to discuss single-page applications (SPAs) versus traditional HTML. When would you even choose a single-page application in the first place? Obviously, it depends on your content and your use case.
00:04:21.600 So what is your content? Is it some sort of closed system where you need to log in to view all information? Maybe it's a dashboard or an administrative interface. In my opinion, that’s a good candidate for a single-page application approach. Is it somewhere in the middle? Is it a membership site? You may have some things you'd want to cache, some static pages, and candidates for static pages. There are some use cases for having very responsive and real-time information, or is it something like Wikipedia, where you have a lot of information?
00:05:35.240 The criteria for considering your approach could include issues like authentication, caching, and whether the content itself needs to be indexed. That horrible acronym, SEO, is important; that content needs to be indexable for many sites. The fourth item I added concerns curated content versus dynamic content, which is a bit ambiguous. In my mind, this is about how many particular combinations we need to generate from specific data or content. If there's a page in a CMS, that's a particular combination of different sections or blocks of text. This is a brief overview, but it summarizes some criteria for why you might want to pick a single-page application or why you might prefer the traditional approach.
00:07:02.759 So where are we now? Let's find out. To understand where we are, we need to go back in history. Rails is so 2005. Someone in the audience might not know what that means. Back in 2005, the 'Rails Way' relied primarily on server-generated HTML, possibly using ERB and the fantastic Prototype and Scriptaculous libraries. Hands up who actually used RJS? I'm really shocked; I have never heard anything good about it and am surprised that so many of you have used it.
00:08:41.680 Now, if we compare the Rails Way to what we have now, it doesn't look terribly different. We can remove Scriptaculous and Prototype and replace them with jQuery, but it is still the Rails Way. David Heinemeier Hansson published an article which I can link or retweet later. Critically, server-generated JavaScript responses are still preferred; that's the way David DHH espouses. Now, JavaScript has somehow become huge, and I'm not sure why, but we have to accept it. We can't live in denial. Someone took V8 and did something with it.
00:09:41.640 In reality, there are people advocating a no backend approach. I recommend you check out noackend.org; it's a manifesto for scrapping your backend or beginning with frontend development. It’s somewhat of a misnomer because it doesn’t necessarily mean getting rid of your backend altogether but rather espouses providing an API or abstractions for the backend so you could authenticate or log in from your frontend. Some excellent examples of no backend frameworks are Hoodie, which promotes an offline-first approach very suitable for certain applications, and is tightly bound to CouchDB.
00:10:48.080 Has anyone used Hoodie here? Two? Cool! Meteor probably has the most mindshare, though; it captured significant media attention among the tech world when it came out last year. It also embraces an offline-first approach and critically allows sharing of code between the server and the backend, which has its merits. But, I love Ruby and don’t want to live in a JavaScript-only world. I find it strange that a few years ago the trend was advocating polyglotism—picking the right language for each layer of your application—and now the push is for JavaScript only! Polyglotism has its place, both in spoken languages and in programming.
00:11:56.040 Let's address the critical question: Is there room for Rails? What does the 'Rails Way' have to say? Actually, who cares? This was a great quote from the other night, from Friday. Now, let's look at a few frontend frameworks; there are many more than the ones I'll list here. The ones I will focus on are Angular, Ember, and KnockoutJS. They are all broadly browser MV* frameworks and support a variety of bindings, which is essential, reflecting the direction of modern browser development.
00:12:53.000 Let's explore these frameworks further. Angular, created by a team from Google, isn’t promoted as heavily as GWT but I assume people at Google use it. AngularJS allows you to use plain JavaScript objects in your models, but it works via 'dirty checking.' When a browser event fires, it recalculates return values from all functions running on your page, which can get complicated with numerous bindings. Ember originated from SproutCore, is now maintained by a team from Tilda.io, and is a full-featured framework, which can be a heavy download.
00:14:07.760 To gain binding support in Ember, you need to inherit from the Ember Object. If you're a Rails developer and haven't touched a frontend MVC framework before, you might ask what is most like Rails? The simple answer is Ember, because it was created by Yehuda Katz, who significantly refined Rails. But, why is Ember more like Rails than Angular? Everything in Ember must inherit from Ember Object, similar to how Rails models often inherit from ActiveRecord Base. Ember's routing DSL will be very familiar if you're a Rails developer, and the jargon creates a big learning curve.
00:15:14.760 As a Rails developer, when dealing with templates in Ember, they feel very similar to partials you learn about early in your Rails experience. What’s most interesting is how we can put this into practice; let's talk about asset pipelines and Sprockets. While Sprockets is a misunderstood technology, it’s worth examining its internals. Understanding the load path can help if you stick to development in a monolithic Rails application. But what many may not know is that you can use Bower with Sprockets.
00:16:05.720 Bower, a package manager for JavaScript frameworks, fetches the latest versions of the scripts you want to run in your browser. It’s a lightweight version of npm. Using Sprockets with Bower is surprisingly easy and there's a plugin available called B-rails that sets everything up for you. Alternatively, you have a bunch of rake tasks available in B-rails to assist you. If you're on an older version of Rails, you'll need to configure your asset paths, but there is a backport available for Bower support with Rails 3.2, though it’s poorly documented.
00:17:57.680 Now, if you decide to go the Ember route, I recommend using Ember Rails API. This overlays your JavaScript application with a directory structure similar to your Rails application. In this way, just like Meteor eliminates the artificial distinction between your server-side and client-side applications, Ember does similarly. You'll find the front-endcontrollers and Rails controllers all in the same place. This familiarity makes it easier for Rails developers. Initializers should go in an initializers folder, and your application.js will set basic application configurations. There is also an Ember Rails gem, but there are a few bugs with it.
00:19:57.480 For now, if you're starting out, using the directory structure I mentioned is a good approach to get up and running quickly. However, long term, if you're working on anything other than a trivial application, what’s the best way forward? I would suggest splitting the application entirely: one API with Rails or Sinatra for the backend, and a front end that uses an AngularJS workflow. I'm disappointed that Rails has not emphasized this transition more; they haven’t provided significant tools to work with current JavaScript tools.
00:21:24.480 Why should you consider this separation? One significant reason, in my opinion, is testability. I've used tools like Teaspoon for unit testing Angular and Ember applications, and it can be frustrating to boot the entire Rails application for unit tests. Architecturally, it doesn't sit well with me either; I should run end-to-end JavaScript tests without having the backend running. Thus, I'm moving towards a Grunt-based workflow. Karma is popular for testing right now, and it's very fast, allowing for proper unit testing of your JavaScript code.
00:23:14.440 There’s plenty of time for questions, which means I might not have provided enough content. Thank you very much! Now feel free to ask me anything or buy me drinks, or something. I have a question: if you divide your application into two apps—one with JavaScript and the other with the frontend—what about the full-stack testing of both of them? There’s nothing that stops you from doing full-stack testing; you can use Capybara for that. I believe you can test PHP applications with it just the same.
00:25:05.000 Although I recommend decoupling your feature testing and your end-to-end testing to speed up the process. I wouldn’t do all my testing with the Rails backend running; I prefer to use fixtures or mock Ajax requests instead. So my question relates to the other one discussed: Idealistically, I want to split into two applications, but there are things I don’t grasp yet, like how to deal with indexing for a public site if my application is a single-page application built completely in HTML5 and JavaScript.
00:26:05.039 If you look back at the beginning of my talk, first ask yourself if this is indeed a candidate for a single-page application; maybe it is, and perhaps something you can explore deeper. There are tools that can generate static pages for every view within your application that should be indexed. I know some tools exist but I can't think of any specific examples right now. Hence, I haven’t needed to do that yet. My work has primarily been on closed systems requiring authentication, which doesn’t need indexing by search engines. There are services that crawl your application, follow links, and use something like PhantomJS to serialize generated views.
00:28:40.559 I argue that for applications requiring heavy indexing, you might reconsider that single-page approach and instead utilize progressive enhancement or TurboLinks. My opinion on nested data in the client is based on the prevailing advice against it from Backbone and Active Model Serializers about keeping flat data for performance reasons. The concern is that embedded data in documents needs to be rebuilt, making retrieval expensive compared to using IDs. However, many dismiss embedded data, but it can be beneficial in certain situations.
00:30:50.678 Over the past two years, I participated in one of the largest single-page applications I’ve seen, which was a CRM built with Ember. Personally, I concluded that the JavaScript ecosystem and development tools aren't yet capable of supporting the same level we achieve with Ruby on the backend. Perhaps it's improved in recent months, but I haven't seen significant advancements. Do you share the opinion that developing large JavaScript applications is not as enjoyable as working on the backend in Ruby? Well, first of all, it's not displeasant, just different from Ruby.
00:34:32.839 The tools for JavaScript development are clearly less mature, and issues arise from the build tools and package management, which are still not fully adequate. Part of the problem lies with JavaScript itself—not being well-suited for many tasks, particularly when we are developing within a browser that lacks a proper development environment. I am more optimistic; I believe things will improve. It's certainly less mature than the Ruby ecosystem, although some issues persist, I feel a bit more patience is required.
00:36:05.360 My go-to stack right now includes Grunt and Karma, combined with tools like Jasmine for testing. I've experimented with the three main JavaScript testing frameworks and would generally recommend using Jasmine for its utility in practice. Finally, the consensus seems to be that two-way binding is critical for maintaining data consistency on the frontend. It can be error-prone to handle events manually, so the built-in consistency and updates when you change objects in one place have compelling advantages.