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.
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
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.
The core of the project is split into 3 directories. These are
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.
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.
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
tests folders, which makes it easier to search for things in files and not get hits in the generated content.
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
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
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
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
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
4. Compile Jade
Uses grunt-contrib-jade and is the same as running
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
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
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.
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
* 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.”