Creating Asha Web Apps with Brunch and Jade

Asha web apps?

Asha web apps are a lightweight application development framework for creating apps for low end Nokia devices (Asha series and earlier). While JME is the most popular technology for creating apps for Asha, web apps are a reasonably quick and convenient way to expose content on the web - basically, your garden variety front ends for restful services, spiced by some simple navigation.

Since Asha devices don't have local javascript execution, javascript is executed on proxy server. "Normal" web pages execute all javascript on the proxy, but Asha web apps provide some "shortcuts" for doing simple DOM manipulation (add/remove css classes, set values in input fields) without the proxy roundtrip. Check out "MWL" library for details.

Standard workflow

Normally, you use Eclipse to develop and test Asha web apps. Nokia provides the "Nokia Web Tools" IDE for this; it's a rather mainstream Eclipse based IDE, spiced with webkit based "local" simulator (that runs javascript locally), and the "cloud" simulator that runs Javacript on the real Nokia proxy servers (but still renders the DOM on the webkit based simulator).

While this is fine for most web developers, there are lots of us relentlessly looking to optimize our workflows, to make it little more efficient, little more fun (or more tolerable, depending how bad an aversion you have for Javascript and HTML) and little more readable and maintainable.

For this kind of developer, there are tools like CoffeeScript, Brunch, Jade, SASS, LESS, HAML. In this exposition we'll use CoffeeScript, Brunch and Jade.

CoffeeScript is a language that compiles to idiomatic and readable/debuggable JavaScript. It makes producing JavaScript more tolerable for people used to modern languages without semicolons, function keywords and a selection of other nastiness that plagues JavaScript.

JADE in a language that compiles to HTML.

This Jade:

doctype 5
html(lang="en")
  head
    title= pageTitle
  body
    h1 Jade - node template engine
    #container
      if youAreUsingJade
        p You are amazing
      else
        p Get on it!

Compiles to this html:

<!DOCTYPE html>
<html lang="en">
  <head><!DOCTYPE html>
<html lang="en">
  <head>
    <title>Jade</title>
  </head>
  <body>
    <h1>Jade - node template engine</h1>
    <div id="container">
      <p>You are amazing</p>
    </div>
  </body>
</html>

As you can see, this makes it easier to "see forest from the trees", as the eye is not misdirected by stream of redundant characters and endless <div>'s.

Brunch is an "assembler" for HTML5 applications. It picks up all the pieces you have (CoffeeScript files, JADE templates, etc.) and produces a runnable web application out of that. It can watch the files on the background, compiling CoffeeScript files to JavaScript the second you save them, running unit tests immediately, refreshing the browser in real time etc.

We use Brunch as the "skeleton" of our Asha web application.

Getting started

Prerequisites: This flow has been tested on Linux and Windows. Have to install Node.js, git, the usual stuff every self respecting web developer has set up on day one. Anecdotal evidence suggests it's a good idea to compile Node.js from source instead of using the packaged versions, if you are lucky enough to be on Linux.

We clone the basic scaffolding from github and install the dependencies:

$ git clone git@github.com:vivainio/awa-brunch.git awa-helloworld
$ cd awa-helloworld/
$ npm install
npm http GET https://registry.npmjs.org/javascript-brunch
npm http GET https://registry.npmjs.org/css-brunch
npm http GET https://registry.npmjs.org/uglify-js-brunch
npm http GET https://registry.npmjs.org/clean-css-brunc
.. etc ..

This install Brunch, CoffeeScript compile and lots of other packages with npm.

Let's take a look at the project structure:

ville@ville-tp:~/p/awa-helloworld$ tree app
app
├── assets
│   ├── config.xml
│   ├── icon.png
│   ├── index.html
│   └── s40-theme
│       ├── css
│       │   ├── s40-theme.css
│       │   ├── single_landscape.css
│       │   └── single_portrait.css
│       ├── images
│       │   ├── arrow-close.png
│       │   ├── arrow-open.png
│       │   ├── back_40x40.png
│       │   ├── button-bg_40x40.png
│       │   ├── close_40x40.png
│       │   ├── grid_40x40.png
│       │   ├── option-menu_titlebar.png
│       │   ├── refresh_40x40.png
│       │   ├── search_40x40.png
│       │   ├── tab_bg.png
│       │   └── title-bar.png
│       └── js
│           ├── s40-theme.js
│           └── screensize.js
├── index.jade
├── README.md
├── templates
│   └── mainlist.jade
├── testCs.coffee
└── testJs.js

Now, we start "brunch watch" that compiles the application in real time as we edit the files, and for added convenience launches a webserver serving on :3333:

ville@ville-tp:~/p/awa-helloworld$ brunch watch --server
26 Apr 22:03:48 - info: application started on http://localhost:3333/
26 Apr 22:03:48 - info: compiled in 115ms
26 Apr 22:03:49 - info: compiled in 206ms

The resulting application that we can deploy, or preview in browser, gets generated in awa-helloworld/public directory:

ville@ville-tp:~/p/awa-helloworld$ tree public
public
├── config.xml
├── icon.png
├── index.html
├── javascripts
│   ├── app.js
│   ├── templates.js
│   └── vendor.js
├── js
│   └── templates.js
└── s40-theme
    ├── css
    │   ├── s40-theme.css
    │   ├── single_landscape.css
    │   └── single_portrait.css
    ├── images
    │   ├── arrow-close.png
    │   ├── arrow-open.png
    │   ├── back_40x40.png
    │   ├── button-bg_40x40.png
    │   ├── close_40x40.png
    │   ├── grid_40x40.png
    │   ├── option-menu_titlebar.png
    │   ├── refresh_40x40.png
    │   ├── search_40x40.png
    │   ├── tab_bg.png
    │   └── title-bar.png
    └── js
        ├── s40-theme.js
        └── screensize.js

"Sources" under app/ directory were processed to produce these files; .coffee files were compiled and concatenated to "app.js", index.jade was converted to index.html, and so on.

There is one extra directory we didn't show yet, the "vendor" directory:

ville@ville-tp:~/p/awa-helloworld$ tree vendor/
vendor/
├── jade_runtime.js
└── README.md

If you are using JavaScript libraries like jQuery, you would just copy it under vendor/ and all of them get automatically concatenated to vendor.js. This makes the app fast to load as it reduces the amount of separate files to download. For production, Brunch can also minify the Javascript files to further reduce page weight. jade_runtime.js is here to support precompiled Jade templates

Shut up and show it running

In the interest of making things as "familiar" and frictionless as possible, we will preview the application in standard Chrome browser instead of Nokia Web Tools. So we launch Chromium and disable web security to prevent CORS from cramping our style and killing our Ajax requests:

$ chromium-browser --disable-web-security http://localhost:3333

This doesn't look at all what you would expect on the phone screen, because we haven't specified a viewport size:

/static/images/awa_chrome_raw.png

Chromium inspector has a handy feature of overriding the viewport size (Settings -> Overrides -> Device Metrics), so we use it to set the resolution to match Asha Full Touch devices (240 x 400):

/static/images/awa_chrome_device_metrics.png

Now, we have a low-fidelity representation of the phone experience! While this certainly wouldn't satisfy an UI designer, it's sufficient for a busy software developer that mostly needs to focus on the "logic" side of the web app.

Launching in NWT

Now is the time to get this running with "real" IDE, i.e. Nokia Web Tools. Launch NWT, do File -> New -> Import web app, select public/config.xml and launch the application in local preview:

/static/images/awa_nwt_1.png

Is this it?

There is more to show: how to utilize precompiled templates, how to inject the MWL library, and how Jade can help you create MWL UI "components" with reusable, encapsulated logic. These, and other things to smoothen the development flow will be covered in another blog post, as this already got way too long.

blogroll

social