There are many powerful tools and technologies surrounding the Web, and we can reuse them to develop cross platform mobile and desktop apps, especially in light of installable apps appearing on platforms such as Firefox OS. This article looks at the best way to do this, and presents Webapplate, a powerful new template to help facilitate this.

Why invent the wheel (for the new frontier)

As is the nature of the whole web, web apps are simple to write but hard to get done right. Even though the Web doesn’t provide an SDK or simple ready-to-use templates like other mobile platforms, you can still come out with a workable web app from candidates like Mozilla Open Web Apps, Chrome Apps, or Apache Cordova. But developers who want to quickly build a web app usually take longer time than say, an iOS developer.

Here is the state of web app support by those candidates:

Firefox (desktop), Firefox OS, Firefox for Android support hosted web apps. Those web apps could be hosted on a static or dynamic web server just like normal web sites. Hosted web apps don’t allow some certified web APIs such as the TCP socket API because of security concerns.

Firefox OS and Chrome (desktop) support packaged web apps with different APIs for different purposes, because currently they focus on different types of devices.

Cordova provides device adapters for many platforms, including Android, iOS and Firefox OS.

Google has its Cordova variant to adapt Chrome App’s specific APIs to run on Android devices.

In quick summary, the web app concept is not totally unified yet, but powerful enough to compete with native apps. Currently packaged web apps are mainstream because of the security concerns with new web API’s. Mozilla is mainly focusing on exposing new web APIs to mobile devices, Google is developing new web APIs for desktop. Apache Cordova is a good container to expose web APIs to different platforms.

To make things harder, provided examples are often focused on teaching you how to pick up new web APIs rather than utilizing proper web app concepts with your development process.

I’ve had the chance to join the development of an evolving web app project called Gaia, the Firefox OS user interface. The Gaia project contains the very first Mozilla installable web app implementation, including apps for music, photo gallery, e-mail, calendar and much more. According to GitHub’s pulse monthly, there are about 850 commits per month to the Gaia web apps. In the Gaia project, Mozilla developers and community members devoted lots of time and effort to bring it from the prototype stage to a shippable product within 2 years, and iteratively make it a competitive option for smartphone consumers. As a living large web app project, there are many lessons that can be learned from it, and applied to general web app development.

Introducing webapplate

Like other software projects, there are many things beside commiting code to develop a web app, such as:

How to organize the source code

How to handle library dependencies

How to keep the coding style in convention

How to optimize web app load performance

How to unit/integrate test your web app

How to localize your web app

How to automate those processes

Those are topics that need to be resolved to develop a quality web app. In Gaia we have addressed these issues by utilizing a bunch of build scripts (Makefiles).

You may wonder why we didn’t use Grunt or gulp for building? The answer: at the time Firefox OS was started, these tools didn’t exist. And the module owner wanted to make the core build process run in a Firefox extension one day.

For general web app development, we didn’t have to follow those constraints. And we could do some experiments rapidly by reusing 3rd-party tools and libraries. From 2013, I’ve initiated a side project called webapplate, the open-sourced web app template that attempts to make Gaia’s solutions compatible with emerging toolkits like npm, Grunt and Bower. It also tries to transport good practices from Gaia to make new web apps more maintainable.

How to setup webapplate

Webapplate utilizes many powerful tools. With node.js, Grunt, Bower, Karma, Mocha and l20n, we come out with a maintainable full stack and self-contained web app template with JavaScript. So you could just copy or download the webapplate from Github, and develop and deploy to a hosting server or correspondent web app store.

You need to install node.js in your desktop first. With Node.js installed, you’ll have the npm tool to manage Node.js modules. Now run this command:

$ npm install-g grunt-cli bower karma

$ npm install -g grunt-cli bower karma

to install the primary tools.

Grunt is a JavaScript task runner tool (like Make) and grunt-cli is its command interface. Gruntfile.js file is similar to Makefile, but written in Javascript.

Bower is a management tool for the front-end libraries. It helps developer manage different library versions. In webapplate, Bower will download client side libraries into the public/vendor folder when you run

$ bower install

$ bower install

command.

Karma is the test runner that runs test code for each of the browsers. karma.conf.js defines the detail settings to specify how the test runner goes.

Next, enter the webapplate folder and run:

$ npm install

$ npm install

npm will reference package.json to install all dependent node modules. The command will trigger Bower to install client-side library dependencies as well.

Then you are all set! What you get is:

Pre-commit lint checking

Firefox and Chrome web app-compatible templates

Library dependency management

Client-side localization framework

Unit test and mock framework

Deployable web server

If you use Firefox nightly, you could open the webapplate/public folder as a packaged app in the WebIDE developer tool.

WebIDE allows you to edit, debug or execute your web app in the Simulator or on the device, with your favorite Firefox Developer Tools.

Pre-commit lint checking

The very first good practice that Gaia and webapplate provide is git pre-commit lint checking.

Since in Gaia every commit needs to get reviewed and verified by the module owner before the code is checked in, we have followed the Google JavaScript style conventions. At that time we used gjslint to test it. It sounds good but actually forcing people to follow the exact same discipline manually is hard; asking the reviewer to pick through those style errors is another waste of time. So some genius introduced a git pre-commit hook to check several kinds of lint errors when the developer tries to commit their code, and provide a whitelist for the code that isn’t fully lint-free but should be allowed. Currently in Gaia we have pre-commit checks for JavaScript, CSS and JSON! This is a big relief.

It has exactly the same settings as Gaia for JSHint and also comes with the whitelist. Gaia is also planning to migrate to jscs to replace gjslint. If you use git for version control, run:

$ grunt githooks

$ grunt githooks

to bind the git pre-commit code style check to your development process.

Firefox OS- and Chrome App- compatible templates

Webapplate uses HTML5 mobile boilerplate as the template base, and adds web app install helpers, icon links and usemin annotation for web app optimization on top. The main web app source is located in the public/ folder. You could check the webapplate wiki to see the full webapplate structure.

Currently, Firefox web apps use manifest.webapp and Chrome Apps use manifest.json as the manifest file. The syntaxes are mutually compatible, except the localization part (we’ll address this issue later).

After you edit one of these files, use:

# firefox to chrome
$ grunt f2c

# firefox to chrome
$ grunt f2c

or

# chrome to firefox
$ grunt c2f

# chrome to firefox
$ grunt c2f

to overwrite manifest.webapp with manifest.json, or viceversa.

To generate a Firefox OS packaged app or Chrome App, run this command:

$ grunt pack

$ grunt pack

to package your web app to an uploadable zip file. With the default settings, webapplate-generated packaged web apps could be uploaded to the Firefox Marketplace and the Chrome App store.

Library dependency management

For Gaia we manage development tools via npm and generally don’t use many 3rd-party client side libraries. We host commonly-used libraries between apps in a shared/ folder, and then copy them in at build time via a build script.

webapplate defines these libraries in package.json, uses npm to require build tools, and doesn’t assume any app framework (e.g. Backbone or Angular.js, or a UI framework such as Bootstrap.) Client-side libraries could be managed via Bower in bower.json.

Client side localization framework

Since web apps might be run without an Internet connection, we can’t count on the server to detect multiple languages. Currently Firefox OS uses navigator.mozL10n and Chrome Apps uses chrome.i18n for localization. Both of them are non-standard.

In webapplate we take the l20n library to address the client-side localization issue. l20n is crafted by Mozilla and the developers are currently working on enhancing the Firefox OS localization framework as well.

Check out index.html; the localization syntax looks exactly like what we used in Gaia:

Unit test and mock framework

Webapplate uses the above unit test libraries plus the Karma test runner to run unit tests on all mainstream browsers.

Deployable web server

For developing Firefox OS hosted web apps, we need a working web server and maybe some dynamic web server support. Now that’s what we call the 21st century: it is possible to write server-side code in JavaScript as well.

Running the command:

$ grunt server

$ grunt server

will trigger the Express-powered server with django-like Swig template support. It’s been pre-configured for performance. Measure with YSlow and you’ll get a pretty good grade for your web site.

Webapplate has been tested on some free dynamic web page hosting providers such as openshift, heroku and appfog. Check the deployment section to find out more details.

If you like to host your web apps on a static web server, run:

$ grunt static

$ grunt static

to generate optimized web pages for hosting.

If you want to deploy your web app on a GitHub page (as a free static hosting server), run:

$ grunt github

$ grunt github

Start your new web app project with webapplate!

Webapplate is the web app template that borrows good practices for web app maintenance from the Gaia project. It provides ready-to-use Firefox OS and Chrome App support, an integrated toolbox to optimize your web app and maintain quality, and uses JavaScript through client/server side build/test frameworks. If you are about to make a web app or want to see how to maintain a web app, webapplate is a good start.

References

Fred Yu-Min Lin, a.k.a. "gasolin", is a front-end web developer working on "Gaia", the user interface for Firefox OS. He is also the book author of Android and FIrefox OS Gaia development. He regularly blogs at http://blog.gasolin.idv.tw and gives presentations to share open web and mobile technologies.

Technical Evangelist & Editor of Mozilla Hacks. Gives talks & blogs about HTML5, JavaScript & the Open Web. Robert is a strong believer in HTML5 and the Open Web and has been working since 1999 with Front End development for the web - in Sweden and in New York City.
He regularly also blogs at http://robertnyman.com and loves to travel and meet people.

Like states addressed in ‘Why invent the wheel’ section, for single web app, you could start with any existing webapp generator to come out with a workable webapp in little time. So does webapplate.

This article contains more tech sharing so it mentioned lots of details.
Things like Karma, Mocha are for unit test purpose, they need to be installed in development but you can use Webapplate without them.
Because those mentioned tools are well integrated in webapplate, you don’t need to know every detail of them.

The key webapplate differentiate from others is `maintenance`.
Once you released your web app, going to the maintain state and get headache about the code quality, those tools are integrated for you. You can hack them later when you need it.

Yeah it will be helpful. I think its doable once web app developer follow similar conventions such as same app folder structure, so tools could use those convention to apply some capabilities to existing project.

At this time I encourage you to check how webapplate integrate those capabilities and port it to your existing project.

I was playing around with this a bit last night. I managed to get it working and get the “Hello World” app to talk to the Firefox OS simulator via Nightly. But it seems like there’s a piece missing – the CSS and JavaScript for actually building a Gaia-like app. Is there any plan to merge in Mozilla Brick or the Gaia Building blocks so we can just write little chunks of HTML and JavaScript to make apps, or do we need to do that on a project-by-project basis?

The required components are pre-fetched by bower. You could uncomment the web component part in `webapplate/public/index.html` and use it now. The app-main component is defined in `webapplate/public/parts/app-main.html`. The limit (for 1.7) is the code optimization process is not ready for web component yet, and web component platform.js shim(both polymer/brick use this) has CSP violation issue for packaged webapp. So you may need to take care your own if you want to use web component for packaged app now.

Note that Gaia Building blocks is being deprecated (but still works) and will be replaced by gaia-elements in the future release. Sadly gaia-elements has no plan for cross platform support yet.

I’m not sure whether I’ll do a packaged app or a hosted app at this point. Given that the only way I can get wide distribution in the USA is to put it in the Marketplace for free, I have plenty of options. I’m leaning towards the OpenShift Online deployment since I have an account there and am an ecstatically happy Fedora Linux users. ;-)

This is a followup to one I posted on Github about a year ago – http://repres4fxos.github.io. It probably does have to be able to go out to the web but the rest of the requirements are quite modest. I just need it to have an app-like style rather than a slide show.