Zero Bugs Reported2015-05-10T02:22:09+00:00http://abogartz.github.ioAlex Bogartzalex@jumpkick.proIn Which I Finally Get MVC (Sort Of)2015-05-09T00:00:00+00:00http://abogartz.github.io/2015/05/09/in-which-i-finally-get-mvc-sort-of
<p>There is no design pattern that’s gotten more attention than MVC, and virtually all of the biggest frameworks use it to some degree. Backbone.js, Angular, Laravel, CodeIgniter, all rely on the basic concept of models, views, and controllers. I’ve been using frameworks like these for years, but even using a framework and calling a script a “controller” or a “view” or a “model” is no guarantee that you’ll actually realize <em>where your code should go</em> and put your code where it makes sense. And in the end, MVC frameworks are all about creating a predictable convention so that stuff goes where you think it should go. Well, back up. Really it’s so stuff goes where the next developer who looks at your code thinks it should go.</p>
<p>So let me share my thoughts on why MVC isn’t a panacea and where I put things to try and make sense out of something as complex as software.</p>
<p>One of the first frameworks I used was Backbone.js. Backbone doesn’t really have a controller, but it has a view and a model. So in essence your view and your controller are sort of the same thing. But my mistake when writing with Backbone was thinking that a Backbone view should contain all of the code that related to the view. Well, all of the code that isn’t a model. But the problem there is that this violates the single responsibility principle.</p>
<blockquote>
<p>In object-oriented programming, the single responsibility principle states that every class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.</p>
</blockquote>
<p>Ok, so right away, I can see where I was going wrong. Having a Backbone view that does a little of everything violates the SRP. For instance, let’s say I’m trying to be diligent and I write a <code>MenuView</code> class, which will handle everything in the header of the site. But what is a “menu”? And what should the <code>MenuView</code> do? Is it really apparent from the name? Well, no. Typically, a site menu will have some navigation. Maybe it will also have a flyout somewhere. But sometimes it also will have a login button. But hang on a second, a login system isn’t a menu system. Those are two different things! In reality, we should have a <code>LoginView</code> that handles the login area. But what should this view do?</p>
<p>Well, we should be able to explain what it does in one sentence.</p>
<blockquote>
<p>The login view listens for a change in the login state. If the user is logged in, it displays a welcome message. If not, it displays a username and password field, plus a login button.</p>
</blockquote>
<p>That’s it. Now, that view file is really only doing one thing. SRP for the win, baby! But so now what? Where do I put the code to handle the button clicks?</p>
<p>This is where it gets tricky, because while in MVC convention we should put all user interaction in the controller and not the view, breaking everything up in separate file. But is that really always the right choice? Let’s go back to what I wrote above.</p>
<blockquote>
<p>And in the end, MVC frameworks are all about creating a predictable convention so that stuff goes where you think it should go.</p>
</blockquote>
<p>The real goal here is putting things in a place they make sense. Not only to you, but to anyone else looking at your code. And so if your application combines user interaction with display, that’s ok. But it should still break things up into a single responsibility. So the LoginView <em>could</em> add a second responsibility, so long as every view combines the same responsibilities in the same predictable way. In our new version, the <code>LoginView</code> class would now be described like this.</p>
<blockquote>
<p>The login view listens for a change in the login state. If the user is logged in, it displays a welcome message. If not, it displays a username and password field, plus a login button. When the login button is clicked, it submits the form to the model and responds to the result.</p>
</blockquote>
<p>This makes it so that we don’t need a controller to communicate with our view, nor does a controller need to subscribe to events from the model. It can control the view directly, which can make the code simpler to follow.</p>
<p>Now is this precisely the MVC pattern? No, not exactly, but I’d say that’s ok. In the end, MVC is only a way to get us to a place where our code makes sense to us after we write it. Part of that is keeping our code to a minimum. But it’s also about not cluttering up the project with more files than we really need. Isn’t that worth breaking a few rules here and there?</p>
<p>So how can I wrap this up? Here’s how I see the SRP in relation to an MVC setup.</p>
<h3 id="models">Models.</h3>
<p>These are where you store data that has to persist between views. This allows for a basic subscription to data changes. All the model does is store data and alert subscribers when it changes. But the key is to name the model for the domain it holds data for. And only one domain at a time. In my example, it only holds the login state. It says we’re logged in if there’s a <code>User</code> and if not, it returns null. That’s it. Simple.</p>
<h3 id="views">Views.</h3>
<p>These are only concerned with showing the state of their model. Ideally, these should have just one or two models to listen for. For instance, in my example, it should listen for logged in state, but maybe also a window resize. Maybe a scroll model is updated as well. Again, all it does is one thing. It reacts to stuff that affects the login section of the menu and that’s all.</p>
<h3 id="controllers">Controllers.</h3>
<p>This code can go in the view, or here in its own file. This code is concerned with users interacting with the application and how this affects the model. It tells the model that something should change and the model affects its subscribers. It doesn’t tell the login view to change. Why? Because what if there are two views that need to react to login status? Now we’ve violated the another important rule, which is the Open/Closed Principle. Which is basically that once you write a class, it shouldn’t change. We shouldn’t edit that controller every time we want to add a new subscriber to the model. And going back to the idea of putting code where it’s easy to understand later, if I’m a new developer and I’m looking for a listener in the login over in the sidebar, then having a class called <code>SidebarLoginView</code> seems pretty clear, doesn’t it?</p>
<p>And in the end, MVC is about being clear. In the end, it’s just a tool which urges us to write code that makes sense. That should be what we strive for above all else.</p>
Visual Studio Code Could Be Great For Typescript2015-05-02T00:00:00+00:00http://abogartz.github.io/2015/05/02/visual-studio-code-could-be-great-for-typescript
<p>Microsoft has just released a new code editor titled, unfortunately, <a href="https://code.visualstudio.com/">Visual Studio Code</a>. Why unfortunately? Imagine doing a Google search for “Visual Studio Code” and getting a 45 million results, of which only a handful are about the editor. I think a more unique name could have made it easier to learn about the editor, and get some momentum going with the community. That being said, the editor itself is pretty promising. I’ve seen a lot of people complaining that we don’t need another editor when we have Vim, or Sublime Text, Atom (with which I’m writing this post). That’s true, but for me, I’m still looking for an editor that can handle Typescript correctly, and my expectation is that Microsoft will make that its priority with this new editor.</p>
<iframe width="100%" height="400" src="https://www.youtube.com/embed/lEI9mxYpcS8" frameborder="0" allowfullscreen=""></iframe>
<h2 id="the-good">The Good</h2>
<p>So let me talk about what I love about VS Code.</p>
<ol>
<li>
<p>First of all, it’s built on a fork of the Atom editor. Atom has a brilliant Typescript <a href="https://atom.io/packages/atom-typescript">plugin</a>, but as of now that plugin lacks the ability to really drill down into Typescript classes. For instance, if I’m working in a class which references another class, mousing over any of the external functions doesn’t give me a way to simply cmd-click my way into the other file. But VS Code does this extremely well. I can mouse over the reference and hold the cmd key, and I see a preview of the class. It’s really nice.
<img src="/assets/images/vs-code-classes.png" alt="" /></p>
</li>
<li>
<p>VS Code also feels very responsive and the code hinting is pretty much immediate. I’ve been using Phpstorm for my production code and for some reason their Typescript support has taken a step backwards. They haven’t been keeping up with the language spec so often times perfectly valid Typescript will generate red squigglies.</p>
</li>
<li>
<p>It’s very hackable. For instance, you can update the keybindings however you like, and even assign multiple actions to a single key. So if you want to run a build task on every file save, you can edit the keybindings.json file and type:
<code>{ "key": "cmd+s", "command": "workbench.action.tasks.build" }</code> and voilà, your build tool runs on every save. Pretty neat!</p>
</li>
</ol>
<h2 id="the-bad">The Bad</h2>
<ol>
<li>
<p>Well, this is a little unfair because this is only a preview release, but the editor is still pretty raw. While they talk about the cmd+. lightbulb option in the video above, this doesn’t work in Tyepscript.</p>
</li>
<li>
<p>No debugger for client-side code in the browser. This is in their longterm plan, but lack of a proper debugger for website developement means that Phpstorm is still the tool to use for me.</p>
</li>
<li>
<p>No plugins. Part of what makes the Phpstorm, Atom, and Sublime community so vibrant is that they allow for third party plugins to fill the gaps that the core developers don’t have the resources to address. All of these editors have a rich plugin ecosystem and chances are that whatever you’re trying to accomplish has been at least attempted by someone else. Again, this is on the roadmap but this just further demonstrates that VS Code is still very green.</p>
</li>
</ol>
<p>All in all I have high hopes for VS Code. It looks and feels great, and once it really matures and offers the basic features available in other IDEs, I’ll be looking to switch. Until then, I recommend giving it a look and <a href="http://visualstudio.uservoice.com/forums/293070-visual-studio-code">vote up</a> features you think will be useful.</p>
Automate Your Deployment First2015-04-26T00:00:00+00:00http://abogartz.github.io/2015/04/26/automate-your-deployment-first
<p>I’m sure this isn’t news to anyone, but if you work for clients, then no matter what the project is you’ll be delivering a set of files to them. And usually you’ll do this over and over to fix bugs or make revisions. And while we take pains to make sure our code is DRY (which means “don’t repeat yourself”), we sometimes fail to notice all the other things we do repeatedly. After a while, these small tasks can add up to hours or even days of effort. Any time you do something more than once, it makes sense to step back and ask yourself if the process can be automated.</p>
<p>With this in mind, the first thing I like to do when starting a project is to set up a place to host the project online, and write a script that bundles the project files and posts them online. While there are a lot of ways to approach this, the most important thing to do is to make sure that your process is reliable and repeatable, so that what gets posted to the server is always the most recent and complete version of the application. For me, the solution is to use Git and a NodeJS library called <a href="https://github.com/pstadler/flightplan">Flightplan</a>. For this to work, you have to have a server which supports SSH and has Git installed. I won’t get into this here, but you need to set up SSH keys like you would for <a href="https://help.github.com/articles/generating-ssh-keys/">Github</a>. You will then have to copy your public key to your deployment server. As an example, here’s how you would do this with a <a href="http://kb.mediatemple.net/questions/1626/Using+SSH+keys+on+your+server">Media Temple</a> account.</p>
<p>Got that working? Great! If so, you should now be able to access your server by typing <code>ssh myuser@example.com</code>. If this is working, we’re ready to set up the deployment.</p>
<p>First we need to install Flightplan. In terminal, type</p>
<pre><code>npm install flightplan -g
</code></pre>
<p>Next, we’ll need to create a flightplan.js file. It doesn’t need a lot of code, but the way it works is that it sets up “transports” such as “local” and “remote”. We’re going to use both.First, let’s set up some configuration.</p>
<pre><code>var plan = require('flightplan');
config = {
host: 'example.com',
username: 'alex',
agent: process.env.SSH_AUTH_SOCK,
webroot: '/var/www/path/to/remote/site',
gitRepo: 'git@github.com:MyAccount/project.git'
}
plan.target('dev', config);
</code></pre>
<p>Now, the first thing I want to do is make sure that any time I deploy the application, I have the latest code. It’s too easy to make assumptions about this and have a coworker make a change to something and then accidentally overwrite the file. Luckily, Flightplan can automate this for us. We’ll have Flightplan pull the most recent commit, then commit your files and push those results to the repository.</p>
<pre><code>plan.local(function (local) {
local.exec('git pull origin master');
local.exec('git commit -am "deploy"');
local.exec('git push origin master');
});
</code></pre>
<p>Ok, so now we can see this part in action by simply typing in terminal</p>
<pre><code> fly dev
</code></pre>
<p>“Dev” is the name we gave our plan, and we can create multiple targets like this which will perform different tasks based on the destination. For instance, we could set up a target called “prod” which could restrict certain actions.</p>
<pre><code>plan.local(function (local) {
if (plan.runtime.target == "prod") return;
// let's just stop here before someone gets fired
...
});
</code></pre>
<p>Ok, but there’s still a flaw here. What happens when the work you’ve been doing has created a few new files (such as image files) and you’ve forgotten to add those to Git? Once you push your changes, you’ll end up with a bunch of broken images. So you’ll have to add the images and then repeat the process. And isn’t the whole <strong>point</strong> of this to never repeat ourselves?</p>
<p>Let’s add one more line to our list of commands.</p>
<pre><code>plan.local(function (local) {
local.exec('git pull origin master');
local.exec('git add .'); //Add in uncommitted files
local.exec('git commit -am "deploy"');
local.exec('git push origin master');
});
</code></pre>
<p>The only thing remaining is to tell the remote server that there are new files to pull. You can do this with post-commit hooks, but Flightplan makes this easy as well once you have SSH access.</p>
<pre><code>plan.remote(function (remote) {
remote.with("cd " + plan.runtime.hosts[0].webroot, function () {
remote.exec("git pull origin master");
})
});
</code></pre>
<p>Now, when we type <code>fly dev</code> we’ll see our local files committed and those changes updated on the server, all with a single command.</p>
<p>In the next lesson, we can expand on this and add some Gulp tasks to the process.</p>
Typescript, Gulp, and RequireJS Together in Harmony2015-04-24T00:00:00+00:00http://abogartz.github.io/programming/2015/04/24/typescript-gulp-and-requirejs-together-in-harmony
<p>I really like Typescript. I like the syntax and the way the code stays very readable. But unlike vanilla JavaScript, there’s a compile step involved, and in larger projects this compilation can start to really slow things down. I found this out while working on a WebGL project, and with the added strain on my laptop of running the app, my compilation times were between 5 and 10 seconds just to see a small change. I needed to explore some other options.</p>
<p>My first step was to try a different IDE. I use PhpStorm, which is just so cool and chock full of features, but it can be a little bloated, so I checked out of a few alternatives and found the Atom editor from GitHub. I’ll cut the story short and just say that this lead me to experiment with using AMD modules and RequireJS to reduce my compile times. Let me run you through the problems and the solutions I found. I’m curious if any of you have some better ideas.</p>
<h3 id="prerequisites">Prerequisites</h3>
<p>Please see my earlier post about using <a href="/programming/2015/04/24/managing-dependencies-with-bower-and-gulp/">Bower and Gulp</a> to manage dependencies.
First off, if you’re reading this you probably already have Typescript installed, but if not, you’ll need to install it plus a few other things.</p>
<ul>
<li><a href="https://nodejs.org/">NodeJS</a></li>
<li><a href="http://www.typescriptlang.org">Typescript</a></li>
<li><a href="http://bower.io/">Bower</a></li>
<li><a href="http://gulpjs.com/">Gulp</a></li>
<li><a href="https://github.com/DefinitelyTyped/tsd">Typescript Definition Manager</a></li>
</ul>
<h3 id="problem-1">Problem 1</h3>
<p>Compilation. The first thing I wanted to deal with is speeding up my compilation times. There are some wonderful tools which bundle assets very quickly, but they don’t play nice with Typescript at the moment.</p>
<p>At first I tried out Browserify, with the “tsify” plugin, but although this worked, I didn’t like that when I had any sort of compile-time error, Browserify wouldn’t alert me to this. I’d have to check the terminal window to see it. Worse yet, sometimes after a compile-time error it would just stop watching for changes. Then I’d have to restart the watcher and try again. Sometimes it would just fail and not give me any output at all, and I had to comment out blocks of code to narrow down the cause. This is supposed to save me time, right?</p>
<p>Next up I tried Webpack, which again had super fast compile times and seemed to work. But the deal breaker was the source mapping. Webpack outputs sourcemaps with a location of <code>/.webpack</code>, which PhpStorm can’t read. More on this a little later</p>
<p>In the end I went back to simple AMD, which is easy to output from Typescript using the flag.</p>
<pre><code>--module amd --sourcemap
</code></pre>
<p>For instance, to compile your main.ts file, you type</p>
<pre><code>tsc main.ts --module amd --sourcemap
</code></pre>
<p>This results in a main.js file, and a main.js.map file from the source file.</p>
<h3 id="problem-2">Problem 2</h3>
<p>Debugging. As I mentioned earlier, Webpack and PhpStorm don’t play nicely together. You can read more about that <a href="https://github.com/webpack/webpack/issues/238">here</a>. I really can’t see myself using Chrome tools to work with breakpoints, considering how powerful PhpStorm’s debugging tools are, so Webpack wasn’t going to work. And Browserify would create sourcemaps, but compile time errors wouldn’t alert me effectively. In the end, only AMD and RequireJS would give me reliable remote debugging and compile-time feedback. </p>
<h3 id="problem-3">Problem 3</h3>
<p>Shims. One of my main gripes about working with RequireJS is the need for shims. For instance, on their site, they post the following code for using jQuery with Require.</p>
<pre><code> //require.config
require.config({
baseUrl: 'js/lib',
paths: {
// the left side is the module ID,
// the right side is the path to
// the jQuery file, relative to baseUrl.
// Also, the path should NOT include
// the '.js' file extension. This example
// is using jQuery 1.9.0 located at
// js/lib/jquery-1.9.0.js, relative to
// the HTML page.
jquery: 'jquery-1.9.0'
}
});
</code></pre>
<p>To me, this is <em>horrible</em>. This can totally spiral out of control and looks, well, smelly. Luckily, in Typescript you don’t even need to shim anything. Instead, you create a simple file called JQuery.ts. But before doing this, we need to take advantage of the TSD tool.</p>
<pre><code>tsd install jquery
tsd rebundle
</code></pre>
<p>Now, we can create our jQuery Typescript file and all it contains is this</p>
<pre><code>/// <reference path="./typings/tsd.d.ts"/>
var jquery= jQuery;
export = jquery;
</code></pre>
<p>So let’s say you put this in /lib/JQuery.ts. In your main.ts file, to use JQuery, you only need to add the following code at the top of your module</p>
<pre><code>import JQuery = require("./lib/JQuery");
</code></pre>
<p>Now, Typescript will be happy, and you can use JQuery wherever you want.</p>
<h3 id="problem-4">Problem 4</h3>
<p>Loading the files. Remember in my earlier post about <a href="/programming/2015/04/24/managing-dependencies-with-bower-and-gulp/">dependencies</a>? You just need to add RequireJS to the list and compile the vendor JS file again.</p>
<pre><code> bower install requirejs
gulp compileVendorJS
tsd install require
tsd rebundle
</code></pre>
<p>Now we can load our main.ts file. Let’s suppose we put main.ts into a folder called <code>app</code>. So using the following script tag</p>
<pre><code><script src="lib/vendor.js" data-main="app/main"></script>
</code></pre>
<p>We can load our application (remember that RequireJS is now bundled into our <code>vendor.js</code> file)</p>
<h3 id="problem-5">Problem 5</h3>
<p>Bundling. Ok, so this is all working pretty well. We can debug. The compile times are fast. We can load our AMD modules using RequireJS and use external libraries like JQuery. But what about bundling? I don’t know about you, but the RequireJS optimizer gave me problems because it needed the same list of external libraries and dependencies as the main application, and I thought the whole idea here was to avoid that mess and make it easier? Again, Gulp can help us.</p>
<p>Let’s add a couple of new tasks here. </p>
<pre><code>gulp.task('bundleAMD', function () {
return gulp.src("html/js/**/*.js")
.pipe($.amdOptimize('app/main'))
.pipe($.concat('amd-bundle.js'))
.pipe($.insert.append('require(["app/main"]);'))
.pipe(gulp.dest('./dist'))
});
gulp.task('bundleCombine', function () {
return gulp.src(["lib/vendor.js", "dist/amd-bundle.js"])
.pipe($.concat('app.min.js', {
newLine:';'
}))
.pipe($.uglify())
.pipe(gulp.dest('./dist'))
});
</code></pre>
<p>The first task takes the code from main.js and bundles everything up. It appends a small snippet of code <code>require(["app/main"]);</code> to make the app self-initiating. The second task simply combines the vendor.js file with the new bundled js file and then minifies it. The result is a file called <code>app.min.js</code>. </p>
<p>Now we can change our script tag (or set the source conditionally with something like PHP) to </p>
<pre><code><script src="dist/app.min.js"></script>
</code></pre>
<p>The application will now run with a single minified JavaScript file.</p>
<p>I’ve created a <a href="https://github.com/abogartz/typescript-amd-gulp-example">repository</a> with all of the working code for this. Take a look and let me know what you think!</p>
Managing dependencies with Bower and Gulp2015-04-24T00:00:00+00:00http://abogartz.github.io/programming/2015/04/24/managing-dependencies-with-bower-and-gulp
<p>Here’s a quick method of dealing with external libraries. <a href="http://www.bower.io">Bower</a> makes it really easy to work with external libraries. For instance, loading jQuery into your project is as easy as typing <code>bower install jquery</code>.</p>
<p>So what does this do? It downloads the jQuery repository to a folder called <code>query</code> in <code>bower_components</code>. From there, you can add your script tag like this.</p>
<p><code><script src="bower_components/jquery/dist/jquery.js"></script></code></p>
<p>However, when you add an additional library such as Greensock’s Tweenmax, you end up stacking the dependencies.</p>
<pre><code><script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/greensock/minified/TweenMax.min.js"></script>
</code></pre>
<p>After you download a dozen third party libraries, this can get out of hand. To make this easier, I’ve created a Gulp task that takes all of the Bower libraries and compiles them into a single JavaScript file. From there you just need to include the one file, and then whenever you add any additional libraries you will run the Gulp task again.</p>
<p>To learn more about Gulp, see their homepage. You need to install NodeJS and <a href="http://gulpjs.com">Gulp</a> for this to work.</p>
<p>Here is my package.json file (this goes in the root of your project).</p>
<pre><code>{
"name": "GulpBower",
"version": "0.0.1",
"devDependencies": {
"gulp": "^3.8.11",
"gulp-concat": "^2.5.2",
"gulp-filelog": "^0.4.1",
"gulp-load-plugins": "^0.10.0",
"gulp-notify": "^2.2.0",
"main-bower-files": "^2.6.2"
}
}
</code></pre>
<p>After this, you need to create a file called gulpfile.js.</p>
<pre><code>var gulp = require('gulp');
var $ = require('gulp-load-plugins')({pattern: '*'});
gulp.task('compileVendorJS', function () {
return gulp.src($.mainBowerFiles({filter: "**/*.js"}))
.pipe($.filelog())
.pipe($.concat('vendor.js'))
.pipe(gulp.dest('./lib'))
.pipe($.notify({message: 'Vendor JS compiled!'}));
});
</code></pre>
<p>And then simply run <code>gulp compileVendorJS</code> from the terminal to combine the libraries. </p>