Archive for the ‘Uncategorized’ Category

Introducing Jake: A Build Tool for JavaScript

Wednesday, April 28th, 2010

Now that we’ve shipped Cappuccino 0.8, I wanted to take some time to describe in more detail what might be one of the most exciting new features our users may not even notice: Jake. Jake is a new build tool built entirely in JavaScript that runs on top of the CommonJS standard. As its name suggests, it is based on the existing and already popular Rake tool and benefits from the same simplicity.

Since when does JavaScript need to be built?

Well, JavaScript doesn’t need to be built, but if you look at almost every major library, you’ll notice all of them ship in some sort of built or “compiled” state. That’s because despite being an interpreted language, there is still plenty JavaScript can gain in the form of optimizations from a build phase. You can concatenate all your code into one file, minimize it, remove dead code, sprite the images associated with the code, and do all sorts of other interesting things that at the end of the day result in a faster web site for your users.

So the concept of building JavaScript is not new in any way. Jake is just a new tool that can help you do all this in a language that’s probably already familiar to you. But before I get into how to use Jake, I’d like to explain the need for such a tool when clearly people are already doing this with non-JavaScript alternatives.

A brief history of build tools used by Cappuccino

Jake is actually the third build tool we’ve used for Cappuccino since we started the project. Like many current JavaScript projects, Cappuccino used to use tools borrowed from other environments.

When we originally shipped Cappuccino, we used a combination of Apache Ant and some custom built JavaScript tools. Our goal has always been to minimize the friction a user experienced when trying to build Cappuccino from scratch, and thus at the time Ant seemed like a good solution since it is cross platform and many people already have it installed with their Java distributions. Ant also let us call into JavaScript with a little bit of legwork. However, the problems with using Ant soon outweighed the benefits. Ant may be a great fit for Java projects since it was designed for that purpose and many of the build commands are tailored specifically for Java, but using it to build non-Java projects can sometimes be an incredibly frustrating ordeal. For starters, Ant uses XML configuration files, which means that performing simple logic can sometimes be quite a daunting task. Java programmers probably don’t notice this because Ant is smart enough to “understand” Java dependencies out of the box, but it had no idea how to deal with our JS files in anything but the most rudimentary way. The solutions usually involved using custom-built extensions which somewhat defeated the purpose of using Ant for its existing install base and portability.

As we tried to do increasingly complex operations during our build process, it became evident that Ant was no longer going to cut it, and so I set out to search for a new tool to replace it. I looked at a number of different options (even briefly trying make — bad idea), but one tool really stood out for me: Rake.

I think Rake is quite possibly the first build tool that I haven’t ended up hating. In fact, I really like Rake. One of the best parts about Rake is its simplicity: it chose to use Ruby itself instead of defining a configuration file format. That means that there’s really no “build” mindset you have to get into, and at the end of the day you’re just writing a really simple program. If at any point you need to do something out of the ordinary in your build process, you can always just code it. There’s no need to invent a new configuration property or hassle with trying to find some obscure “right” way to do things: you can just code it. Strangely enough, Rake also has the most intuitive built-in commands I have ever used. Creating dependencies is a breeze, and it is smart enough to handle things like cleaning a project very elegantly for you. If you’ve never tried Rake, you really should.

So why not stick with Rake?

Moving to Rake was a really great decision at the time, but Rake unfortunately had one problem that eventually got to us: it had to be written in Ruby. This is not a problem per se of course, and the truth is that Ruby is one of the reasons Rake shines. The DSL Ruby allows in Rake makes it truly a joy to use, but the unfortunate fact is that many our users simply don’t know Ruby, so interacting with the build system could prove difficult to them. This resulted in a number of problems:

  1. Users didn’t like having to install Ruby gems to build Cappuccino from scratch.
  2. On top of the occasional Rhino bug, we now had to deal with Ruby incompatibilities across distributions and versions which were very difficult for us to deal with effectively as this was not our native environment.
  3. Users were afraid to submit patches to the build scripts because they weren’t as knowledgable in Ruby.
  4. Users were afraid to innovate in the build space for the same reason.
  5. Users were less likely to use our optimization tools, because again, it required using the Ruby build process, installing gems, etc.
  6. Since our product and our build tools were written in different languages, we were incapable of easily sharing code between the two. We had to jump through a lot of hoops to call JavaScript from Ruby (usually through Rhino), which resulted in pretty slow builds.

So all in all, while Rake provided a pretty good “out of the box” experience for our users and contributors, it meant they were really stuck when something went wrong, and that they were not as capable of fixing or improving it. This is a pretty general problem in the JavaScript space I feel. You’ll notice that a lot of the work of “optimizing” and deploying JavaScript usually takes place in a different language. For example, most JavaScript compressors are written in Java. This is really unfortunate, because it creates an artificial rift between JavaScript programmers and the people trying to make their JavaScript really fast. One of our goals for Cappuccino 0.8 was to remedy this because we felt that there was still a tremendous amount left to be done in the JavaScript and web application optimizations, and we wanted all the help we could get.

Jake

Luckily for us, things had really changed since we originally shipped Cappuccino. Most importantly, there is now a real standard for running JavaScript on the command line: CommonJS. Recall for a moment that when we originally shipped Cappuccino, doing something a simple as reading a file in JavaScript was still an open question! At the time the best solution was to use Rhino and drop down to Java APIs. Not only was this slow, it was completely unportable to the other JavaScript engines that would come along like JavaScriptCore and V8. But with CommonJS around, it was now finally viable to write command line scripts in JavaScript.

So with these tools in hand we set out to write Jake: a JavaScript port of Rake. Again, we really liked Rake, so the goal was simply to expose the functionality of this tool to JavaScript. This ended up turning out quite well for us, because we didn’t have to worry about inventing a new build tool. The result is that most Rakefiles can be trivially “ported” to Jake, so a lot of the existing JavaScript projects that currently use Rake can quickly transition over.

Let’s quickly take a look at how to create build tasks with Jake:

var task = require("jake").task; task ("log", function() { print("hey there!"); });

That’s all there is to it. You simply call the task function, give it a name, and a closure that contains task’s instructions. If you want to set up a dependency, say on two other tasks, you can do so as well:

task ("log", ["task-one", "task-two"], function() { print("hey there!"); });

Now, log will first make sure to execute task-one and task-two before executing. If you’ve used Rake, this should look really familiar. Here is the same task in Rake for comparison:

task :log => [:task-one, :task-two] do echo "hey there!" end

Jake also includes a host of tools to make dealing with files super easy. This is how you would make sure to generate a new concatenated and compressed file every time you edit one of your original source files:

var shrinksafe = require("minify/shrinksafe"), read = require("file").read, write = require("file").write, filedir = require("jake").filedir, FileList = require("jake").FileList; filedir ("build/compressed.js", new FileList("*.js"), function() { var result = ""; (new FileList("*.js")).forEach(function(filename) { result += shrinksafe.compress(read(filename)); }); write("build/compressed.js", result); });

So what we’re doing here is creating a task for our “build/compressed.js” file. The filedir task is nice enough to create the intermediate “build” directory for us (if you don’t want this behavior, you can use the file task instead). This task will only run any time one of the files in our project with the “.js” extension changes. So, if you don’t change any code, this task is skipped. The FileList object takes globs and is iterable, so when this task is called, it simply iterates over each of these files, reads them, compresses them, and writes out the concatenated result. Pretty easy. The best part is that since CommonJS supports a bunch of compressors, its really easy to write a task that uses whichever one generates the smallest file size:

filedir ("build/compressed.js", new FileList("*.js"), function() { var smallest = null, compressors = ["minify/shrinksafe", "minify/closure-compiler"]; compressors.forEach(function(compressor) { var result = ""; (new FileList("*.js")).forEach(function(filename) { result += require(compressor).compress(read(filename)); }); if (!smallest || result.length < smallest.length) smallest = result; }); write("build/compressed.js", smallest); });

Already in use

This isn’t a toy, we are actively using this as our only build system in Cappuccino. That means you can check out some pretty sophisticated examples by taking a look at the Cappuccino source code, or by talking to anyone who has shipped a Cappuccino project. Just ask to see their Jakefiles. If you already have a CommonJS platform installed, you can get jake by just using the tusk package manager:

tusk install jake

If not, you can head on over to narwhaljs.org and download narwhal to get started writing JavaScript on the server and command line. Alternatively, you can download the Cappuccino source code and run our bootstrap script, which not only installs narwhal for you, but also custom tailors your installation to use the fastest JavaScript engine available for your machine that narwhal supports (this means that if you’re on a Mac you’ll get the super fast JavaScriptCore engine instead of the quite slow default Rhino one):

$ git clone git://github.com/280north/cappuccino.git cappuccino $ cd cappuccino $ ./bootstrap.sh

If you do this you’ll also be able to checkout out some of the cool extensions to Jake specifically for Cappuccino projects. We’ve created the bundle, framework, and app tasks that completely put together your project for you (similar to the gem tasks in Rake). These tasks implement some pretty cool optimizations, like our automagic image spriting. If you’re having any trouble, feel free to jump in our IRC room so we can answer your questions or comments on how to get set up building your projects with jake.

You can of course also get the source code as well and submit patches or file bugs:

$ git clone git://github.com/280north/jake.git

Perhaps one of the coolest results of this is that Cappuccino is really now self-hosting: the entire stack is finally JavaScript and easily accessible for hacking.

Cappuccino 0.8

Wednesday, April 7th, 2010

Cappuccino 0.8 is now available on the downloads page. This release has a ton of new features and fixes, and I’d like to thank everyone in the community that meticulously checked their existing software against the Release Candidates in the last few weeks.

10,000 Foot View

Cappuccino 0.8 includes close to 100,000 lines of changes from our last formal release, 0.7.1 (check out the Github compare view for this release). This ranges from new tests to brand new features to optimizing existing ones. And yet, despite this tremendous amount of change, we have almost no API differences (aside from API additions of course). The very few changes we do have are simply deprecated, not removed. This means that it will be incredibly easy to drop in the new version of Cappuccino and get all the benefits without spending a ridiculous amount of time changing your own code. This is of course the benefit of implementing an existing and proven spec. In fact, most the public Cappuccino projects are already running this code.

Now that that’s out of the way, lets get to the good stuff: what’s new?

CPTableView and CPOutlineView

Table views have been one of our most requested features since we launched Cappuccino about a year ago, and I’m happy to say that I think we have one of the best table view implementations out there with 0.8. Randy, our latest committer, has spearheaded this feature for his own TimeTable project and with help from a number other folks in the community it has become a truly awesome component, supporting immense amounts of rows, column sorting, drag and drop, and much more while still remaining incredibly performant. But don’t take my word for it, check it out yourself:

Automagic Image Spriting

We alluded to this feature a little while ago when we first announced it at JSConf EU, and now you can finally take it for a spin: automatic image spriting. Yes you read correctly, no more having to manually decide which images to sprite, or how to sprite. The brand new Cappuccino build tools are smart enough to sprite all your images together into one file (not several based on orientation), and of course works in all browsers including IE. You can find out more about the thinking behind this feature here.

nib2cib Updates

Along with all the new components we’ve added to Cappuccino, we’ve been keeping nib2cib up to date to allow you to use them in the easiest way possible. Most importantly, table views can now be created with simple drag and drop!

The Whole Stack with CommonJS and Jake

Although this isn’t necessarily a feature in Cappuccino itself, a lot of our users will be thrilled to know that getting and building Cappuccino from the repo (or building and optimizing your own Cappuccino apps) no longer has any external dependencies. In previous releases we relied on a combination of our own tools and a few Ruby tools like Rake. However, with the advent of the CommonJS standard (which our own team member Tom has been working on diligently), we’ve been able to move our entire development stack to JavaScript and Objective-J. That means that our community members will have an easier time writing tests, fixing bugs in the build process, and writing server side JS and Objective-J. Making this change has also allowed us to put a greater focus on the tools side of things and provide a host of improved applications like press and flatten to better optimize deploying your Cappuccino applications. We’ll be posting soon with more details about these.

And there’s way more in there as well. We are incredibly proud of this release and think it makes Cappuccino more compelling than ever. We’ll be at JSConf showing some of this stuff off too, so if you’re attending, stop by and say hi!

- Francisco

New Cappuccino App: TimeTable

Wednesday, March 24th, 2010

After many months of development Randy Luecke has finally released version 1.0 of his new Cappuccino project, TimeTable! We’re proud to share in the excitement as yet another Cappuccino application is made commercially available. TimeTable is an application designed for freelancers to keep track of their projects and clients. TimeTable boasts a plethora of features including integration with web services like Google Maps, Gmail, Google Voice, and Skype.

Randy’s commitment to Cappuccino is obvious when you look at the development he has done on the new CPTableView component, which was developed in parallel with TimeTable. In addition to the work he has done on CPTableView, Randy has also open sourced different components used throughout TimeTable, the most notable of which is the date picker component. Randy has been no stranger to the community as he continues to lend a helping hand in the mailing list and IRC channel. We look forward to the things Randy has in the pipeline for Cappuccino!

We’d like to share in Randy’s success by sponsoring a give away of 25 TimeTable accounts. To enter simply tweet: “I would like to enter to win a @timetableapp account http://timetableapp.com/”! On March 30th, 25 twitter users will be chosen at random to receive their free TimeTable account! If you don’t win TimeTable is still more than affordable at its incredible introductory price of $34.99 a year!

Find out more about the TimeTable launch.

Cappuccino in Checkout 3

Tuesday, October 6th, 2009

Sofa just released the third version of their award winning point of sale software, Checkout. Chances are if you’ve ever seen a Mac behind the counter when you’ve made a purchase, it was running Checkout. Version 3 adds lots of new features, but what’s really cool is that they’ve added a new web component built on top of Cappuccino called Enstore that allows you to take your physical store and put it completely online. For Enstore, Sofa wanted a truly desktop like experience for managing and creating online stores, and you really have to try it yourself to see how amazing it feels.

From a technology perspective, Enstore is a real milestone as the UI was built almost entirely using nib2cib, showing that Cappuccino doesn’t just let you build apps faster, but also creates drop dead stunning results.

Klaas Pieter has written up an excellent blog post about his experiences creating Enstore at Sofa where you can learn more, and a special thanks to him as well for contributing a lot of bug fixes along the way!

Cappuccino 0.7.1 Released

Monday, July 6th, 2009

This is maintenance release for 0.7 and includes mainly bug fixes. You can see a complete list of changes in our release notes, or look at a quick summary here:

Summary

  • Improvements to the way nib2cib handles custom classes in nibs.
  • Improvements to menus and menu items in nib2cib
  • Added automatic drag and drop support to CPImageView
  • Better JSON support
  • Better UTF8 Support
  • Updated included version of Narwhal (http://narwhaljs.org/)

One completely new feature we added is an auto generated showcase app for the theming API we introduced in 0.7. This showcase allows you to better test your themes under a number of different conditions. You can check out the one for Aristo here.

Aristo Showcase

Downloading

As always you can download this release from our downloads page, or update your source.

Thanks for all the help on this release!

Better Objective-J Profiling with Cappuccino 0.7

Wednesday, April 29th, 2009

I’ve written pretty extensively on the changes we’ve been working on in the WebKit profiler to make for a much better experience when using Objective-J here, but long story short if you download the latest WebKit nightlies with Cappuccino 0.7 your profile should look like this:
Profiling Cappuccino 0.7 with WebKit nightlies
One of our main goals with Cappuccino 0.7 is to really make the entire development cycle shine. Part of this was focusing heavily on nib2cib so that developers can make their apps in a more visual way, but we also want to make it much easier to debug as well. Let us know if you have any particular suggestions for making debugging even better over at our new bug tracker hosted on github: http://github.com/280north/cappuccino/issues

Download

Cappuccino and Objective-J are licensed under the LGPL. For more information, see our licensing page.

Copyright © 2009 - 280 North, Inc. Cappuccino and Objective-J are registered Trademarks of 280 North. Logo by Sofa. Hosting by Slicehost.