JavaScript

Micro Talk: Organizing and Packaging Rich Javascript Apps with Ruby

Micro Talk: Organizing and Packaging Rich Javascript Apps with Ruby

by Luke Melia

In the micro-talk titled "Organizing and Packaging Rich Javascript Apps with Ruby," delivered by Luke Melia at the GoRuCo 2012 event, the speaker addresses the growing challenge developers face with organizing and deploying complex client-side JavaScript applications. Melia shares insights drawn from his experience managing JavaScript applications at Yapp and proposes solutions from the Ruby ecosystem.

The discussion highlights several key points:

- Historical Context: Melia begins with an analogy comparing past solutions for managing freight train hazards to modern practices in JavaScript app organization, signaling a need for systematic approaches.

- Software Engineering Principles: As JavaScript applications become larger, applying established software engineering principles becomes crucial. This includes the adoption of MVC frameworks and testing frameworks to improve code organization and maintainability.

- JavaScript Build Systems: The focus of the talk is the JavaScript build system, which must support both iterative development and efficient deployment of JavaScript assets. Key problems addressed by build systems include:

- Concatenation of JavaScript files into a single HTTP payload

- Minification to reduce file sizes

- Supporting authoring in different languages like CoffeeScript

- Rake Pipeline: Melia explains Rake Pipeline, a tool derived from Rake, which simplifies the build process by creating a dynamic pipeline that captures the incremental build speed for JavaScript applications. This initiative was inspired by the need for effective build tools when developing with Ember.js and showcases the benefits of Ruby in building such solutions.

- DSL and Filter Mechanism: A major innovation within Rake Pipeline is its domain-specific language (DSL) for managing filters. Filters allow developers to perform transformations on input files, such as wrapping in closures or minifying content. This operational model provides a user-friendly experience for defining how files are processed.

- Integration and Commands: Melia demonstrates that executing builds with Rake Pipeline is straightforward, as commands like 'rake p' automate the build and cleanup process while allowing a development server to preview changes in real-time.

In conclusion, Melia emphasizes the joy of working with Ruby to express complex ideas with elegance and simplicity. The talk advocates using modern tools like Rake Pipeline to tackle the intricacies of large-scale JavaScript applications effectively.

Takeaways from this session include:

- The importance of implementing structured build systems for JavaScript applications

- The advantages of using Ruby-based tools for enhancing productivity and code clarity

- Encouragement to embrace modern programming techniques to facilitate the development process.

00:00:16.560 Um, this is me. I live two blocks from here with my two kids. I have a company called Yapp where I write a lot of Ruby and JavaScript. When I'm not doing those things, I like to play beach volleyball. Our JavaScript apps are getting bigger.
00:00:29.519 There was a time when having a cowboy approach to managing these applications seemed like a good idea. Here's a little New York history: a few blocks over on 10th Avenue, there used to be a freight train running at street level in the mid-1800s. Unfortunately, many people got killed by that freight train, so they decided to do something about it. The solution was to hire the West Side Cowboys, who would ride their horses in front of the freight trains, waving red flags to alert people of their approach. At the time, it was a practical solution, but now I think we need to reassess how we're organizing and packaging our JavaScript applications.
00:01:03.680 As our JavaScript applications grow, we need to apply software engineering principles that we have learned in other environments. This shift is occurring with MVC frameworks and testing frameworks, which help us organize our code in more sensible ways, making it easier to find later. Today, I want to focus on the build system for JavaScript. This build system should support iterative development as well as the deployment process, allowing us to efficiently deliver JavaScript assets to their intended destinations, whether that be the browser or native wrappers.
00:01:27.200 In the real world, JavaScript build systems tackle several key problems: concatenation, which combines everything into one HTTP payload; minification, which compresses files to reduce their size; authoring in another language like CoffeeScript; and deferred parsing and template compilation. The tools we employ are fairly common and likely well-known to many of you.
00:02:02.960 When designing a build system, the approach is straightforward: it's a pipeline. We start with input at one end, and a series of filters transform that input until we reach output at the other end. For JavaScript, this process often involves taking a collection of JavaScript files, wrapping each file in a closure, minifying them, concatenating into a single file, and placing the result into an output directory.
00:02:30.080 There are several Rails-focused solutions available, the most well-known of which ships with Rails 3—the asset pipeline. Outside the Ruby community, developers use a diverse array of tools for similar purposes, including custom-built and generic tools such as Make. With all these options available, you might wonder why I am here talking about Rake pipeline today. There are two main reasons: first, it has pragmatically solved problems for us in my codebase; and second, this library exemplifies what I love about Ruby.
00:03:07.360 A little history for context: in October 2011, a company named LivingSocial needed tooling for an Ember.js app they were developing. They hired Yehuda Katz, who subsequently created Rake Pipeline. About a month later, at Yehuda's request, it was released as open source. The concept was to model this as a build system, allowing us to grow and compose it according to our needs.
00:03:43.680 If you're going to build a build system in Ruby, the first stop is likely Rake. However, I won't delve deeply into Rake because Jim Wyrick, who is here, will cover that better than I could ever explain. Nevertheless, one important aspect of Rake that you should understand is the file wrapper. This allows you to create files, and if the file you create is newer than its input files, the task is skipped. This mechanism enables incremental builds, which is crucial for achieving fast build times.
00:04:16.960 The foundational innovation of Rake Pipeline is that we can dynamically create file tasks from the filters that perform these transformations, capturing the benefits of this architecture with incremental build speed while leveraging Rake under the hood. This allows us to effectively manage our filter pipeline.
00:05:00.720 So what exactly is a filter in Rake Pipeline? It's a subclass of Rake Pipeline Filter that requires you to provide a 'generate_output' method, taking in input collections and generating output as a result. The file wrapper classes simplify the task of knowing where these files are located on disk, offering user-friendly methods for reading and writing them. This design not only makes it simple to write filters, but also encourages sharing them with others.
00:05:48.319 The next key component of Rake Pipeline is its DSL, which allows you to describe how to compose these filters. For example, if we want to use Rake Pipeline, we start by building the pipeline and creating an instance of the DSL class. We specify our inputs, usually JavaScript files ending in .js, and define the filters to be applied to them. Our first filter can be a closure filter, which wraps our input in an anonymous function to provide information hiding and keep the global scope clean.
00:06:28.320 Next, we can minify each file using a filter from the Rake Pipeline Web Filters project, such as the Uglify filter. The output will then be concatenated into a single file, say application.js, which is placed in the dist directory. Thus, we can express our transformation pipeline simply and intuitively.
00:07:11.040 The Rake Pipeline setup also allows for creating a module for shortcuts. For instance, we can define a method that calls the closure filter, then include this module in the DSL. This makes our transformation process even shorter and more readable.
00:07:55.680 The Rake Pipeline and its associated web filters project already provide helpers for minifying and concatenating files, simplifying the coding process further. I challenge anyone to express this transformation process as succinctly in any other programming language as we can do in Ruby.
00:08:39.360 Another significant aspect of the DSL is matchers, which allow you to restrict filters to particular types of files. For example, if we want to incorporate CoffeeScript into our project, we can specify that. The matcher will generate the input for the next step; in this case, the CoffeeScript files will produce JavaScript output. This way, we can seamlessly add another language to our stack with just a few lines of code.
00:09:30.399 Executing Rake Pipeline is straightforward, thanks to the executable provided with the gem. The 'rake p' command builds and generates the output as expected, while 'rake p clean' removes temporary and output files. The 'rake p server' command starts a development server, allowing real-time previews of changes. This server uses middleware that can be integrated into your own projects if needed.
00:10:07.360 In conclusion, I want to thank the event organizers, as well as Matt, who makes writing this type of code possible. Ruby enables us to express ourselves in ways that bring joy to our work. Thank you all.