I wrote a web app for a silly card game that my friends & I play. Writing the Level Counter was a learning experience in a few things: writing an HTML5 app, managing multiple code bases for different platforms, & publishing the final results.
Here’s a link to the current Level Counter.
jQuery, Feature Bloat, & Angular
Initially, I wrote the app using jQuery, starting with a couple buttons for increasing/decreasing one’s level & bonuses & adding further features as I went. I added a menu, cached the current player’s statistics in local storage, let users restore the previous session from local storage, & added a modal combat dialog. These features are all usable if you rewind the project’s git repository; this commit from June of 2013 is close to that point. The readme shows I had plans to use some more modern JavaScript techniques to deal with how tangled & complex the code was becoming, such as using RequireJS or an evented pub-sub architecture.
But I noticed a couple things: the vast majority of the features I added were used rarely or not at all, while the code was messy & complicated. I had heard about AngularJS & wanted to try it out, so I started a new branch that would port the application over to Angular instead of jQuery. Angular is so excellent at doing certain tasks, like two-way data-binding, that I was able to rewrite the fundament of the application in about fourteen lines of code, where my initial jQuery version used somewhere near a hundred lines to achieve the same functionality. After that I paused to realize that all of these extra features, like local storage & the combat dialog, weren’t adding much value but rather were simply me diverting myself so I could play around & take on new challenges. So I decided to stop short & leave only the most essential features in place.
Developer Tooling
The Level Counter project was one of the first projects where I began to develop some tools for my development workflow. One example is the pair of version number handling scripts. Since I found myself maintaining two main branches—one for a Chrome application & the other for a generic web app—well as a couple manifests with version numbers, it was a chore to ensure that version numbers were consistent throughout the code.
So I wrote a shell script & what was probably my first Node script ever to help with the tedious version number maintenance. The shell script handles moving between git branches, employing some small but important practices like stashing changes in the working directory before doing its thing. The Node script takes advantage of the fact that all the various manifest files are JSON, which is easy to process in JavaScript (but not in Bash, thus why I didn’t use the shell here), to update numbers.
Version numbers aside, I also employed Grunt to help with many of the development & deployment tasks for the Level Counter. Grunt is at its most useful when preparing a development application for production; for a web app, this entails several steps, from copying the code to a new folder, to concatenating stylesheets & scripts, minifying CSS, JavaScript, & HTML, & employing cache-busting filename-based versioning. Whew, that’s a lot of work for a simple grunt build
command. Grunt is also handy for running a livereload development server which refreshes every time I edit one of the app’s files.
Writing an application with multiple platform targets, some sophisticated functionality, & various development tools was a learning experience. I picked up a few tricks along the way, e.g. how to make Angular work inside a Chrome app & with the closure-compiler, which may come in useful as I continue to code. I also used a .gitattributes file to manage the divergent index.html files across the Chrome and web app branches, which circumvents manually dealing with merge conflicts every time I take changes from one branch into the other.
I’m not done yet, either; I have a few open bugs involving how the buttons render on mobile phones to deal with.