The typical development toolchain in a modern Titanium project involves many tools:
- Titanium itself;
- the Alloy framework;
- TiShadow, for faster development deployments/tests;
- one or several pre-processors (Coffeescript, Jade, STSS, ticons, etc.) and their Grunt bindings;
- Grunt and grunt-contrib-watch to wrap it all.
While TiShadow is a very good way of improving your production rate with Titanium and Alloy, it can be limited with large Alloy projects. We recently had the case with a huge codebase, where even using TiShadow wasn’t a sufficient improvement to make the developer’s life “easy”.
With our classical Titanium development environment, each and every file change launches the following steps:
- a file gets change (coffeescript, stss, etc.)
- grunt-coffescript compiles it from the
coffeedirectory to the
- grunt-tishadow runs the
By default, in an Alloy project, the
tishadow run command runs a complete Alloy compilation, which means that every js, XML or tss file in the
app folder will be processed to create their equivalent in the
Resources folder. With a project large of 1000+ files, the Alloy compilation is slow (which means 5–15 seconds on a performant Macbook pro) and can be a pain for the developer, annihilating all the ease introduced by TiShadow.
TiShadow lately introduced the
-s switch, which allows to bypass the Alloy compilation, and therefore directly runs the code available in the
Resources directory. When developing an Alloy app, this won’t however match the requirements of the Titanium developer, who wants to be able to test the very last modifications made in the coffee or stss files.
We lately digged into Alloy’s compiler code and found it could be optimized to allow only process the compilation path of a single file. The pull request ALOY-620 – #625 introduces a new “file” option, which allows to tell the compile command which file was changed and which compilation path has to be worked out by the compiler.
When changing one single file in an Alloy project, there’s no more need for a complete Alloy rebuild: simply launch the
compile command with the
$ alloy compile --config platform=ios,file=app/controllers/index.js
Depending on the filetype (controller, stylesheet, view, theme, library, alloy.js, etc.), this will only re-generate the required files, not the whole bunch of Titanium Classic files it used to build. And the result is blazing fast:
$ time alloy compile --config platform=ios ... [INFO] Alloy compiled in 9.64312s $ time alloy compile --config platform=ios,file=app/controllers/index.js ... [INFO] Alloy compiled in 0.40075s
Instead of waiting for almost 10 seconds, the Titanium developer will be able to observe the changes in a couple of seconds. Automating this flow with
grunt-tishadow isn’t an immediate task though. It requires several steps:
- watch for changes made in the
grunt-contrib-watch. Listen for the
changeevent and, for each file modified, change the configuration of
grunt-alloyto pass the name of the file to be changed ;
grunt-tishadow, disable Alloy’s automatic compilation (
true). A recently merged pull-request has made it possible and only listen changed on
- instead of developping in
Resources, the developer now writes code in the
srcfolder. As a convenience, a
copytask copies everything (apart from ltss and coffee files) from
- several instances of grunt-contrib-watch must be run simultaneously and, hence, are watching through grunt-concurrent.
I forked the Alloy Bootstrap project made by my colleague Vincent to wrap all the required tools together. If you have a look at it, pay attention to the Gruntfile’s
watch event manager. Most of the magic is made inside this listener, which drastically restricts the (pre-) compilation operations.
Developing for native targets can be painful and slow. TiShadow helped a lot in this sake, let’s make it a bit even faster!
Code Strong !