A Pretty Cool Build Process with AppBuilder CLI

I had been a fan of the Telerik AppBuilder desktop client (formerly known as Graphite) for a while. However the one thing you could never do was use alternative languages, like CofeeScript, TypeScript, LESS, SASS, etc. Unit testing was also not possible.

With the release of the AppBuilder command line tools we can now use a more flexible javascript/node.js build environment.

I decided to create a template for the Kendo UI Mobile sample project (created by default when you init a new AppBuilder CLI project) and use:

  • Sublime Text
  • Grunt
  • CoffeeScript
  • LESS
  • Jade
  • Jasmine

You can find the appbuildet_grunt_template repo in my GitHub account. The README has instructions.

The rest of this post discusses the technical aspects of the template project.

Project Structure

The core of the project is split into 3 directories. These are app, src and tests.

The app directory is the actual AppBuilder CLI project. When you run the Grunt build process, generated content will be deleted out of this directory, and then CoffeeScript, LESS, and Jade files will be built into it. This is also the directory from which you will need to run most appbuilder commands, but more on that later.

The src directory is where the source code is kept. The reason for keeping this separate from the AppBuilder application is because when you ask AppBuilder to build your application into an installable file for a device, it includes every file in the project. If we were to put our source CoffeeScript files in the app directory, then they would get deployed with our app.

The tests directory is for the unit tests. I chose to use Jasmine.

Node, Grunt, and Sublime

If you have done much node.js or client side web development, you have probably come across these tools. I don’t want to discuss them in depth, as they are somewhat outside the scope of this post. If you aren’t familiar with them, then I encourage you to research them before moving on.

Sublime is my code editor of choice. The template repo contains a file named app.sublime-project that you can open from the Sublime “Project” menu. It will restrict the files shown in Sublime to just the src and tests folders, which makes it easier to search for things in files and not get hits in the generated content.

Grunt is a JavaScript based task runner (similar to Ant, Nant, MSBuild, Rake, etc) that runs on top of Node.js. This will run all the tasks of our build process, like compiling CoffeeScript files and running Jasmine tests.

The Actual Build Process

If you follow the directions in the README file of the template project, you will eventually run the default build task with the command grunt. So what exactly does this do?

If you are familiar with Grunt, you can look at gruntfile.js to see exactly what happens at every step of the process.

1. Clean Generated Code

Uses grunt-contrib-clean and is the same as running grunt clean.

Deletes a bunch of files from the app folder that we plan to regenerate. The reason for clearing out these files before each build is to ensure that old/deleted/renamed files aren’t left in the deployed package.

2. Compile CoffeeScript

Uses grunt-contrib-coffee and is the same as running grunt coffee.

The build process looks in src/scripts for any *.coffee files, and compiles them to app/scripts/app.js. Note that all the coffee files are combined into a single js file, so when the app starts, it doesn’t have to do as much file i/o to load all the individual files. I am also not doing any minification of the files at this point, just because then it is easier to debug, and because the space saved in the deployed package isn’t that much unless you have a very large project.

In addition, any *.js plain JavaScript files found in this directly will also be copied to app/scripts so you don’t have to make everything CoffeeScript. For example, any 3rd party libraries that I include, like Underscore, I can just put the pre-minified .js file in the directory.

3. Compile LESS

Uses grunt-contrib-less and is the same as running grunt less.

The build process looks for the file src/styles/app.less and builds it to app/styles/app.css. Here again, you can combine multiple LESS files into a single css file by using the @import statement in LESS. This lets us make separate files for separate structures, but deploy just a single file.

I like to separate my styles into a file for each view, plus files that are different for a particular OS.

Just like with the scripts directory, any plain *.css files found in the src/styles directory are copied to app/styles

4. Compile Jade

Uses grunt-contrib-jade and is the same as running grunt jade.

Since our CoffeeScript and LESS code can all be split into multiple files and combined into one for deployment, I wanted to do the same thing for the HTML. For this, I chose to use Jade. Jade is a fairly minimalist, whitespace sensitive language that compiles into HTML.

The build process looks for the file src/index.jade and compiles it to app/index.html.

Multiple jade files can be combined into index by using the include "path/to/jade/file" statement in index.jade. For the sample template, I put these additional files in src/views and created one for each Kendo UI Mobile View.

In addition, and additional *.html files found in the src directory will be copied to app so if you don’t want to use Jade, it can easily be removed.

5. Run Jasmine Tests

Uses grunt-contrib-jasmine and is the same as running grunt jasmine.

I really started this because I wanted to write some unit tests, and that seems to be really difficult to do in any other AppBuilder environment except the command line interface, and the VisualStudio plugin. The last step of the build process it to run the tests.

Since I was already using CoffeeScript for the app’s scripts, I used it for the tests as well. The build process looks for any src/tests/*.spec.coffee files, and compiles them all to src/tests/generated/app.spec.js and then runs this test file in Jasmine.

This is actually a bit tricky because of the way the sample Kendo UI Mobile app that AppBuilder creates is set up. The JavaScript initializes Kendo UI Mobile as soon as the JavaScript is loaded on the page, which in turn looks for the forst element with a data-role="view" attribute. Because our test runs against what is basically a blank HTML page, this element does not exist, and you get a JavaScript error in the test output. However, that error does not block the running of other tests. It is just a message that can be ignored. I would like to find a good way to restructure the app initialization code to be more testable, but I also didn’t want to drastically edit the default Kendo UI Mobile sample app.

Next Steps… Customize!

This template is just a guideline for how I would like to structure my AppBuilder CLI project. If you don’t like it, or want to use different technologies like TypeScript or SASS, you can certainly edit the Grunt build process to support that instead.

Take the template and make it your own, or let it serve as inspiration to make something tailored to your needs!

Why is this a “pretty cool” build process, and not a “super awesomely amazing” one?

Well, it still has a few shortcomings in my opinion. Most of these stem from the way AppBuilder wants its projects structured.

* Since you can’t exclude any files from being deployed in the AppBuilder project, I had to put all my source code in a separate parallel directory (/src). This also means that the “root directory” of the project can’t be an AppBuilder project. And that means that when you want to run appbuilder commands on the command line, you either need to move into the app directory, or specify --path app as a parameter to any appbuilder commands.

* The AppBuilder project file app/.abproject is a different format from every other AppBuilder interface (why???) so you can’t open this project in the AppBuidler web IDE if you ever needed to.

* The template has a lot of steps to clone and make useful. If you look at the README in the template project, I list out the steps. It was surprisingly a lot of them. Just cloning the repo is a multi-step process because Git seems to base the name of the project on the name of the remote. So if you clone appbuilder_grunt_tempalte to a new directory named my_app then drag-and-drop the folder to GitHub for Windows, it will show up as being named appbuilder_grunt_tempalte. This was a bit of an annoyance. It would be nice if GitHub had a way to “clone this to my account, with a different name.”

Tagged with: , , , ,
Posted in JavaScript, Programming
3 comments on “A Pretty Cool Build Process with AppBuilder CLI
  1. Hi Jeff,

    Thanks for your great post and for your ongoing feedback about AppBuilder. Much appreciated and please keep it coming 😉

    Now onto your final points:
    * File exclusion support (via .abignore file) has already be merged into our development branch (https://github.com/Icenium/icenium-cli/pull/250) and will be available in one of our next updates. If you want to be on the bleeding edge you can checkout the develop branch and give it a try.
    * We are in a process of unifying our project files across all AppBuilder clients. We have decided to embrace the CLI JSON based format so expect Graphite/Mist to stand understand it as well.


  2. Hi Jeff,

    I’ve created a basic grunt task to build appbuilder projects, might be useful for you with this process.




Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

CodingWithSpike is Jeff Valore. A professional software engineer, focused on JavaScript, Web Development, C# and the Microsoft stack. Jeff is currently a Software Engineer at Virtual Hold Technologies.

I am also a Pluralsight author. Check out my courses!

%d bloggers like this: